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 <sal/config.h>
22 #include <o3tl/any.hxx>
23 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
24 #include <rtl/ustrbuf.hxx>
25 #include <sal/types.h>
26 #include <sal/log.hxx>
27 #include <osl/diagnose.h>
28 #include <com/sun/star/lang/XServiceInfo.hpp>
29 #include <com/sun/star/container/XEnumerationAccess.hpp>
30 #include <com/sun/star/container/XEnumeration.hpp>
31 #include <com/sun/star/container/XIndexReplace.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/beans/XMultiPropertySet.hpp>
34 #include <com/sun/star/beans/XPropertyState.hpp>
35 #include <com/sun/star/graphic/XGraphic.hpp>
36 #include <com/sun/star/text/XTextDocument.hpp>
37 #include <com/sun/star/text/XTextSectionsSupplier.hpp>
38 #include <com/sun/star/text/XTextTablesSupplier.hpp>
39 #include <com/sun/star/text/XNumberingRulesSupplier.hpp>
40 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
41 #include <com/sun/star/text/XTextTable.hpp>
42 #include <com/sun/star/text/XText.hpp>
43 #include <com/sun/star/text/XTextContent.hpp>
44 #include <com/sun/star/text/XTextRange.hpp>
45 #include <com/sun/star/text/XTextField.hpp>
46 #include <com/sun/star/container/XNamed.hpp>
47 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
48 #include <com/sun/star/text/XTextFrame.hpp>
49 #include <com/sun/star/container/XNameAccess.hpp>
50 #include <com/sun/star/text/SizeType.hpp>
51 #include <com/sun/star/text/HoriOrientation.hpp>
52 #include <com/sun/star/text/VertOrientation.hpp>
53 #include <com/sun/star/text/TextContentAnchorType.hpp>
54 #include <com/sun/star/text/XTextFramesSupplier.hpp>
55 #include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
56 #include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
57 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
58 #include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
59 #include <com/sun/star/document/XEventsSupplier.hpp>
60 #include <com/sun/star/document/XRedlinesSupplier.hpp>
61 #include <com/sun/star/text/XFormField.hpp>
62 #include <com/sun/star/text/XTextSection.hpp>
63 #include <com/sun/star/drawing/XShape.hpp>
64 #include <com/sun/star/style/XAutoStylesSupplier.hpp>
65 #include <com/sun/star/style/XAutoStyleFamily.hpp>
66 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
67 #include <com/sun/star/drawing/XControlShape.hpp>
68 #include <com/sun/star/util/DateTime.hpp>
70 #include <sax/tools/converter.hxx>
72 #include <xmloff/xmlnamespace.hxx>
73 #include <xmloff/xmlaustp.hxx>
74 #include <xmloff/families.hxx>
75 #include "txtexppr.hxx"
76 #include <xmloff/xmluconv.hxx>
77 #include "XMLAnchorTypePropHdl.hxx"
78 #include <xexptran.hxx>
79 #include <xmloff/ProgressBarHelper.hxx>
80 #include <xmloff/namespacemap.hxx>
81 #include <xmloff/xmlexp.hxx>
82 #include <txtflde.hxx>
83 #include <xmloff/txtprmap.hxx>
84 #include <XMLImageMapExport.hxx>
85 #include "XMLTextNumRuleInfo.hxx"
86 #include <xmloff/XMLTextListAutoStylePool.hxx>
87 #include <xmloff/txtparae.hxx>
88 #include "XMLSectionExport.hxx"
89 #include "XMLIndexMarkExport.hxx"
90 #include <xmloff/XMLEventExport.hxx>
91 #include "XMLRedlineExport.hxx"
92 #include <MultiPropertySetHelper.hxx>
93 #include <xmloff/formlayerexport.hxx>
94 #include "XMLTextCharStyleNamesElementExport.hxx"
95 #include <xmloff/odffields.hxx>
96 #include <xmloff/maptype.hxx>
97 #include <basegfx/polygon/b2dpolypolygon.hxx>
98 #include <basegfx/polygon/b2dpolypolygontools.hxx>
99 #include <basegfx/polygon/b2dpolygontools.hxx>
100 #include <com/sun/star/embed/ElementModes.hpp>
101 #include <com/sun/star/embed/XTransactedObject.hpp>
102 #include <com/sun/star/document/XStorageBasedDocument.hpp>
103 #include <txtlists.hxx>
104 #include <com/sun/star/rdf/XMetadatable.hpp>
106 #include <unordered_map>
111 #include <officecfg/Office/Common.hxx>
113 using namespace ::std
;
114 using namespace ::com::sun::star
;
115 using namespace ::com::sun::star::uno
;
116 using namespace ::com::sun::star::lang
;
117 using namespace ::com::sun::star::beans
;
118 using namespace ::com::sun::star::container
;
119 using namespace ::com::sun::star::text
;
120 using namespace ::com::sun::star::style
;
121 using namespace ::com::sun::star::util
;
122 using namespace ::com::sun::star::drawing
;
123 using namespace ::com::sun::star::document
;
124 using namespace ::com::sun::star::graphic
;
125 using namespace ::xmloff
;
126 using namespace ::xmloff::token
;
128 // Implement Title/Description Elements UI (#i73249#)
129 constexpr OUStringLiteral
gsTitle(u
"Title");
130 constexpr OUStringLiteral
gsDescription(u
"Description");
131 constexpr OUStringLiteral
gsAnchorPageNo(u
"AnchorPageNo");
132 constexpr OUStringLiteral
gsAnchorType(u
"AnchorType");
133 constexpr OUStringLiteral
gsBookmark(u
"Bookmark");
134 constexpr OUStringLiteral
gsChainNextName(u
"ChainNextName");
135 constexpr OUStringLiteral
gsContourPolyPolygon(u
"ContourPolyPolygon");
136 constexpr OUStringLiteral
gsDocumentIndexMark(u
"DocumentIndexMark");
137 constexpr OUStringLiteral
gsFrame(u
"Frame");
138 constexpr OUStringLiteral
gsGraphicFilter(u
"GraphicFilter");
139 constexpr OUStringLiteral
gsGraphicRotation(u
"GraphicRotation");
140 constexpr OUStringLiteral
gsHeight(u
"Height");
141 constexpr OUStringLiteral
gsHoriOrient(u
"HoriOrient");
142 constexpr OUStringLiteral
gsHoriOrientPosition(u
"HoriOrientPosition");
143 constexpr OUStringLiteral
gsHyperLinkName(u
"HyperLinkName");
144 constexpr OUStringLiteral
gsHyperLinkTarget(u
"HyperLinkTarget");
145 constexpr OUStringLiteral
gsHyperLinkURL(u
"HyperLinkURL");
146 constexpr OUStringLiteral
gsIsAutomaticContour(u
"IsAutomaticContour");
147 constexpr OUStringLiteral
gsIsCollapsed(u
"IsCollapsed");
148 constexpr OUStringLiteral
gsIsPixelContour(u
"IsPixelContour");
149 constexpr OUStringLiteral
gsIsStart(u
"IsStart");
150 constexpr OUStringLiteral
gsIsSyncHeightToWidth(u
"IsSyncHeightToWidth");
151 constexpr OUStringLiteral
gsIsSyncWidthToHeight(u
"IsSyncWidthToHeight");
152 constexpr OUStringLiteral
gsNumberingRules(u
"NumberingRules");
153 constexpr OUStringLiteral
gsParaConditionalStyleName(u
"ParaConditionalStyleName");
154 constexpr OUStringLiteral
gsParagraphService(u
"com.sun.star.text.Paragraph");
155 constexpr OUStringLiteral
gsRedline(u
"Redline");
156 constexpr OUStringLiteral
gsReferenceMark(u
"ReferenceMark");
157 constexpr OUStringLiteral
gsRelativeHeight(u
"RelativeHeight");
158 constexpr OUStringLiteral
gsRelativeWidth(u
"RelativeWidth");
159 constexpr OUStringLiteral
gsRuby(u
"Ruby");
160 constexpr OUStringLiteral
gsRubyCharStyleName(u
"RubyCharStyleName");
161 constexpr OUStringLiteral
gsRubyText(u
"RubyText");
162 constexpr OUStringLiteral
gsServerMap(u
"ServerMap");
163 constexpr OUStringLiteral
gsShapeService(u
"com.sun.star.drawing.Shape");
164 constexpr OUStringLiteral
gsSizeType(u
"SizeType");
165 constexpr OUStringLiteral
gsSoftPageBreak( u
"SoftPageBreak" );
166 constexpr OUStringLiteral
gsTableService(u
"com.sun.star.text.TextTable");
167 constexpr OUStringLiteral
gsText(u
"Text");
168 constexpr OUStringLiteral
gsTextContentService(u
"com.sun.star.text.TextContent");
169 constexpr OUStringLiteral
gsTextEmbeddedService(u
"com.sun.star.text.TextEmbeddedObject");
170 constexpr OUStringLiteral
gsTextField(u
"TextField");
171 constexpr OUStringLiteral
gsTextFieldService(u
"com.sun.star.text.TextField");
172 constexpr OUStringLiteral
gsTextFrameService(u
"com.sun.star.text.TextFrame");
173 constexpr OUStringLiteral
gsTextGraphicService(u
"com.sun.star.text.TextGraphicObject");
174 constexpr OUStringLiteral
gsTextPortionType(u
"TextPortionType");
175 constexpr OUStringLiteral
gsUnvisitedCharStyleName(u
"UnvisitedCharStyleName");
176 constexpr OUStringLiteral
gsVertOrient(u
"VertOrient");
177 constexpr OUStringLiteral
gsVertOrientPosition(u
"VertOrientPosition");
178 constexpr OUStringLiteral
gsVisitedCharStyleName(u
"VisitedCharStyleName");
179 constexpr OUStringLiteral
gsWidth(u
"Width");
180 constexpr OUStringLiteral
gsWidthType( u
"WidthType" );
181 constexpr OUStringLiteral
gsTextFieldStart( u
"TextFieldStart" );
182 constexpr OUStringLiteral
gsTextFieldEnd( u
"TextFieldEnd" );
183 constexpr OUStringLiteral
gsTextFieldStartEnd( u
"TextFieldStartEnd" );
190 typedef list
<Reference
<XTextContent
>> contents_t
;
191 typedef back_insert_iterator
<contents_t
> inserter_t
;
192 typedef contents_t::const_iterator const_iterator_t
;
194 inserter_t
getInserter()
195 { return back_insert_iterator
<contents_t
>(m_vTextContents
); };
196 const_iterator_t
getBegin() const
197 { return m_vTextContents
.begin(); };
198 const_iterator_t
getEnd() const
199 { return m_vTextContents
.end(); };
202 contents_t m_vTextContents
;
207 size_t operator()(const Reference
<XTextFrame
>& rFrame
) const
208 { return sal::static_int_cast
<size_t>(reinterpret_cast<sal_uIntPtr
>(rFrame
.get())); }
211 bool lcl_TextContentsUnfiltered(const Reference
<XTextContent
>&)
214 bool lcl_ShapeFilter(const Reference
<XTextContent
>& xTxtContent
)
216 Reference
<XShape
> xShape(xTxtContent
, UNO_QUERY
);
219 Reference
<XServiceInfo
> xServiceInfo(xTxtContent
, UNO_QUERY
);
220 return !xServiceInfo
->supportsService("com.sun.star.text.TextFrame") &&
221 !xServiceInfo
->supportsService("com.sun.star.text.TextGraphicObject") &&
222 !xServiceInfo
->supportsService("com.sun.star.text.TextEmbeddedObject");
228 typedef bool (*filter_t
)(const Reference
<XTextContent
>&);
230 const Reference
<XEnumerationAccess
>& rEnumAccess
,
231 const filter_t
& rFilter
)
232 : m_xEnumAccess(rEnumAccess
)
238 const TextContentSet
& GetPageBoundContents() const
239 { return m_vPageBounds
; };
240 const TextContentSet
* GetFrameBoundContents(const Reference
<XTextFrame
>& rParentFrame
) const
242 framebound_map_t::const_iterator it
= m_vFrameBoundsOf
.find(rParentFrame
);
243 if(it
== m_vFrameBoundsOf
.end())
245 return &(it
->second
);
247 Reference
<XEnumeration
> createEnumeration() const
249 if(!m_xEnumAccess
.is())
250 return Reference
<XEnumeration
>();
251 return m_xEnumAccess
->createEnumeration();
255 typedef std::unordered_map
<
256 Reference
<XTextFrame
>,
258 FrameRefHash
> framebound_map_t
;
259 TextContentSet m_vPageBounds
;
260 framebound_map_t m_vFrameBoundsOf
;
261 const Reference
<XEnumerationAccess
> m_xEnumAccess
;
262 void Fill(const filter_t
& rFilter
);
265 class FieldParamExporter
268 FieldParamExporter(SvXMLExport
* const pExport
, Reference
<XNameContainer
> const & xFieldParams
)
270 , m_xFieldParams(xFieldParams
)
275 SvXMLExport
* const m_pExport
;
276 const Reference
<XNameContainer
> m_xFieldParams
;
278 void ExportParameter(const OUString
& sKey
, const OUString
& sValue
);
287 explicit BoundFrameSets(const Reference
<XInterface
>& rModel
);
288 const BoundFrames
* GetTexts() const
289 { return m_pTexts
.get(); };
290 const BoundFrames
* GetGraphics() const
291 { return m_pGraphics
.get(); };
292 const BoundFrames
* GetEmbeddeds() const
293 { return m_pEmbeddeds
.get(); };
294 const BoundFrames
* GetShapes() const
295 { return m_pShapes
.get(); };
297 unique_ptr
<BoundFrames
> m_pTexts
;
298 unique_ptr
<BoundFrames
> m_pGraphics
;
299 unique_ptr
<BoundFrames
> m_pEmbeddeds
;
300 unique_ptr
<BoundFrames
> m_pShapes
;
305 static bool txtparae_bContainsIllegalCharacters
= false;
308 // The following map shows which property values are required:
310 // property auto style pass export
312 // ParaStyleName if style exists always
313 // ParaConditionalStyleName if style exists always
314 // NumberingRules if style exists always
315 // TextSection always always
316 // ParaChapterNumberingLevel never always
317 // NumberingIsNumber never always
319 // The conclusion is that for auto styles the first three properties
320 // should be queried using a multi property set if, and only if, an
321 // auto style needs to be exported. TextSection should be queried by
322 // an individual call to getPropertyvalue, because this seems to be
323 // less expensive than querying the first three properties if they aren't
326 // For the export pass all properties can be queried using a multi property
329 static const char* aParagraphPropertyNamesAuto
[] =
332 "ParaConditionalStyleName",
339 enum eParagraphPropertyNamesEnumAuto
341 NUMBERING_RULES_AUTO
= 0,
342 PARA_CONDITIONAL_STYLE_NAME_AUTO
= 1,
343 PARA_STYLE_NAME_AUTO
= 2
348 static const char* aParagraphPropertyNames
[] =
351 "NumberingStyleName",
353 "ParaConditionalStyleName",
356 "OutlineContentVisible",
362 enum eParagraphPropertyNamesEnum
364 NUMBERING_IS_NUMBER
= 0,
365 PARA_NUMBERING_STYLENAME
= 1,
366 PARA_OUTLINE_LEVEL
=2,
367 PARA_CONDITIONAL_STYLE_NAME
= 3,
370 PARA_OUTLINE_CONTENT_VISIBLE
= 6
375 void BoundFrames::Fill(const filter_t
& rFilter
)
377 if(!m_xEnumAccess
.is())
379 const Reference
< XEnumeration
> xEnum
= m_xEnumAccess
->createEnumeration();
382 const OUString
our_sAnchorType("AnchorType");
383 const OUString
our_sAnchorFrame("AnchorFrame");
384 while(xEnum
->hasMoreElements())
386 Reference
<XPropertySet
> xPropSet(xEnum
->nextElement(), UNO_QUERY
);
387 Reference
<XTextContent
> xTextContent(xPropSet
, UNO_QUERY
);
388 if(!xPropSet
.is() || !xTextContent
.is())
390 TextContentAnchorType eAnchor
;
391 xPropSet
->getPropertyValue(our_sAnchorType
) >>= eAnchor
;
392 if(TextContentAnchorType_AT_PAGE
!= eAnchor
&& TextContentAnchorType_AT_FRAME
!= eAnchor
)
394 if(!rFilter(xTextContent
))
397 TextContentSet::inserter_t pInserter
= m_vPageBounds
.getInserter();
398 if(TextContentAnchorType_AT_FRAME
== eAnchor
)
400 Reference
<XTextFrame
> xAnchorTxtFrame(
401 xPropSet
->getPropertyValue(our_sAnchorFrame
),
403 pInserter
= m_vFrameBoundsOf
[xAnchorTxtFrame
].getInserter();
405 *pInserter
++ = xTextContent
;
409 BoundFrameSets::BoundFrameSets(const Reference
<XInterface
>& rModel
)
410 : m_pTexts(new BoundFrames())
411 , m_pGraphics(new BoundFrames())
412 , m_pEmbeddeds(new BoundFrames())
413 , m_pShapes(new BoundFrames())
415 const Reference
<XTextFramesSupplier
> xTFS(rModel
, UNO_QUERY
);
416 const Reference
<XTextGraphicObjectsSupplier
> xGOS(rModel
, UNO_QUERY
);
417 const Reference
<XTextEmbeddedObjectsSupplier
> xEOS(rModel
, UNO_QUERY
);
418 const Reference
<XDrawPageSupplier
> xDPS(rModel
, UNO_QUERY
);
420 m_pTexts
.reset(new BoundFrames(
421 Reference
<XEnumerationAccess
>(xTFS
->getTextFrames(), UNO_QUERY
),
422 &lcl_TextContentsUnfiltered
));
424 m_pGraphics
.reset(new BoundFrames(
425 Reference
<XEnumerationAccess
>(xGOS
->getGraphicObjects(), UNO_QUERY
),
426 &lcl_TextContentsUnfiltered
));
428 m_pEmbeddeds
.reset(new BoundFrames(
429 Reference
<XEnumerationAccess
>(xEOS
->getEmbeddedObjects(), UNO_QUERY
),
430 &lcl_TextContentsUnfiltered
));
432 m_pShapes
.reset(new BoundFrames(
433 Reference
<XEnumerationAccess
>(xDPS
->getDrawPage(), UNO_QUERY
),
437 void FieldParamExporter::Export()
439 const Type aStringType
= ::cppu::UnoType
<OUString
>::get();
440 const Type aBoolType
= cppu::UnoType
<sal_Bool
>::get();
441 const Type aSeqType
= cppu::UnoType
<Sequence
<OUString
>>::get();
442 const Type aIntType
= ::cppu::UnoType
<sal_Int32
>::get();
443 const Sequence
<OUString
> vParameters(m_xFieldParams
->getElementNames());
444 for(const auto & rParameter
: vParameters
)
446 const Any aValue
= m_xFieldParams
->getByName(rParameter
);
447 const Type
& aValueType
= aValue
.getValueType();
448 if(aValueType
== aStringType
)
452 ExportParameter(rParameter
,sValue
);
454 if ( rParameter
== ODF_OLE_PARAM
)
456 // Save the OLE object
457 Reference
< embed::XStorage
> xTargetStg
= m_pExport
->GetTargetStorage();
458 if (xTargetStg
.is()) {
459 Reference
< embed::XStorage
> xDstStg
= xTargetStg
->openStorageElement(
460 "OLELinks", embed::ElementModes::WRITE
);
462 if ( !xDstStg
->hasByName( sValue
) ) {
463 Reference
< XStorageBasedDocument
> xStgDoc (
464 m_pExport
->GetModel( ), UNO_QUERY
);
465 Reference
< embed::XStorage
> xDocStg
= xStgDoc
->getDocumentStorage();
466 Reference
< embed::XStorage
> xOleStg
= xDocStg
->openStorageElement(
467 "OLELinks", embed::ElementModes::READ
);
469 xOleStg
->copyElementTo( sValue
, xDstStg
, sValue
);
470 Reference
< embed::XTransactedObject
> xTransact( xDstStg
, UNO_QUERY
);
471 if ( xTransact
.is( ) )
472 xTransact
->commit( );
475 SAL_WARN("xmloff", "no target storage");
479 else if(aValueType
== aBoolType
)
483 ExportParameter(rParameter
, OUString::boolean(bValue
) );
485 else if(aValueType
== aSeqType
)
487 Sequence
<OUString
> vValue
;
489 for(const OUString
& i
: std::as_const(vValue
))
491 ExportParameter(rParameter
, i
);
494 else if(aValueType
== aIntType
)
496 sal_Int32 nValue
= 0;
498 ExportParameter(rParameter
, OUString::number(nValue
));
503 void FieldParamExporter::ExportParameter(const OUString
& sKey
, const OUString
& sValue
)
505 m_pExport
->AddAttribute(XML_NAMESPACE_FIELD
, XML_NAME
, sKey
);
506 m_pExport
->AddAttribute(XML_NAMESPACE_FIELD
, XML_VALUE
, sValue
);
507 m_pExport
->StartElement(XML_NAMESPACE_FIELD
, XML_PARAM
, false);
508 m_pExport
->EndElement(XML_NAMESPACE_FIELD
, XML_PARAM
, false);
511 void XMLTextParagraphExport::Add( XmlStyleFamily nFamily
,
512 const Reference
< XPropertySet
> & rPropSet
,
513 const XMLPropertyState
** ppAddStates
, bool bDontSeek
)
515 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper
;
518 case XmlStyleFamily::TEXT_PARAGRAPH
:
519 xPropMapper
= GetParaPropMapper();
521 case XmlStyleFamily::TEXT_TEXT
:
522 xPropMapper
= GetTextPropMapper();
524 case XmlStyleFamily::TEXT_FRAME
:
525 xPropMapper
= GetAutoFramePropMapper();
527 case XmlStyleFamily::TEXT_SECTION
:
528 xPropMapper
= GetSectionPropMapper();
530 case XmlStyleFamily::TEXT_RUBY
:
531 xPropMapper
= GetRubyPropMapper();
535 SAL_WARN_IF( !xPropMapper
.is(), "xmloff", "There is the property mapper?" );
537 vector
< XMLPropertyState
> aPropStates
=
538 xPropMapper
->Filter(GetExport(), rPropSet
);
542 while( *ppAddStates
)
544 aPropStates
.push_back( **ppAddStates
);
549 if( aPropStates
.empty() )
552 Reference
< XPropertySetInfo
> xPropSetInfo(rPropSet
->getPropertySetInfo());
553 OUString sParent
, sCondParent
;
554 sal_uInt16 nIgnoreProps
= 0;
557 case XmlStyleFamily::TEXT_PARAGRAPH
:
558 if( xPropSetInfo
->hasPropertyByName( gsParaStyleName
) )
560 rPropSet
->getPropertyValue( gsParaStyleName
) >>= sParent
;
562 if( xPropSetInfo
->hasPropertyByName( gsParaConditionalStyleName
) )
564 rPropSet
->getPropertyValue( gsParaConditionalStyleName
) >>= sCondParent
;
566 if( xPropSetInfo
->hasPropertyByName( gsNumberingRules
) )
568 Reference
< XIndexReplace
> xNumRule(rPropSet
->getPropertyValue( gsNumberingRules
), uno::UNO_QUERY
);
569 if( xNumRule
.is() && xNumRule
->getCount() )
571 Reference
< XNamed
> xNamed( xNumRule
, UNO_QUERY
);
574 sName
= xNamed
->getName();
575 bool bAdd
= sName
.isEmpty();
578 Reference
< XPropertySet
> xNumPropSet( xNumRule
,
580 if( xNumPropSet
.is() &&
581 xNumPropSet
->getPropertySetInfo()
582 ->hasPropertyByName( "IsAutomatic" ) )
584 bAdd
= *o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "IsAutomatic" ));
585 // Check on outline style (#i73361#)
587 xNumPropSet
->getPropertySetInfo()
588 ->hasPropertyByName( "NumberingIsOutline" ) )
590 bAdd
= !(*o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "NumberingIsOutline" )));
599 maListAutoPool
.Add( xNumRule
);
603 case XmlStyleFamily::TEXT_TEXT
:
605 // Get parent and remove hyperlinks (they aren't of interest)
606 rtl::Reference
< XMLPropertySetMapper
> xPM(xPropMapper
->getPropertySetMapper());
607 for( ::std::vector
< XMLPropertyState
>::iterator
i(aPropStates
.begin());
608 nIgnoreProps
< 2 && i
!= aPropStates
.end(); )
610 if( i
->mnIndex
== -1 )
616 switch( xPM
->GetEntryContextId(i
->mnIndex
) )
618 case CTF_CHAR_STYLE_NAME
:
619 case CTF_HYPERLINK_URL
:
622 i
= aPropStates
.erase( i
);
631 case XmlStyleFamily::TEXT_FRAME
:
632 if( xPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
634 rPropSet
->getPropertyValue( gsFrameStyleName
) >>= sParent
;
637 case XmlStyleFamily::TEXT_SECTION
:
638 case XmlStyleFamily::TEXT_RUBY
:
639 ; // section styles have no parents
643 if (aPropStates
.size() - nIgnoreProps
)
645 GetAutoStylePool().Add( nFamily
, sParent
, aPropStates
, bDontSeek
);
646 if( !sCondParent
.isEmpty() && sParent
!= sCondParent
)
647 GetAutoStylePool().Add( nFamily
, sCondParent
, aPropStates
);
651 static bool lcl_validPropState( const XMLPropertyState
& rState
)
653 return rState
.mnIndex
!= -1;
656 void XMLTextParagraphExport::Add( XmlStyleFamily nFamily
,
657 MultiPropertySetHelper
& rPropSetHelper
,
658 const Reference
< XPropertySet
> & rPropSet
)
660 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper
;
663 case XmlStyleFamily::TEXT_PARAGRAPH
:
664 xPropMapper
= GetParaPropMapper();
668 SAL_WARN_IF( !xPropMapper
.is(), "xmloff", "There is the property mapper?" );
670 vector
<XMLPropertyState
> aPropStates(xPropMapper
->Filter(GetExport(), rPropSet
));
672 if( rPropSetHelper
.hasProperty( NUMBERING_RULES_AUTO
) )
674 Reference
< XIndexReplace
> xNumRule(rPropSetHelper
.getValue( NUMBERING_RULES_AUTO
,
675 rPropSet
, true ), uno::UNO_QUERY
);
676 if( xNumRule
.is() && xNumRule
->getCount() )
678 Reference
< XNamed
> xNamed( xNumRule
, UNO_QUERY
);
681 sName
= xNamed
->getName();
682 bool bAdd
= sName
.isEmpty();
685 Reference
< XPropertySet
> xNumPropSet( xNumRule
,
687 if( xNumPropSet
.is() &&
688 xNumPropSet
->getPropertySetInfo()
689 ->hasPropertyByName( "IsAutomatic" ) )
691 bAdd
= *o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "IsAutomatic" ));
692 // Check on outline style (#i73361#)
694 xNumPropSet
->getPropertySetInfo()
695 ->hasPropertyByName( "NumberingIsOutline" ) )
697 bAdd
= !(*o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "NumberingIsOutline" )));
706 maListAutoPool
.Add( xNumRule
);
710 if( aPropStates
.empty() )
713 OUString sParent
, sCondParent
;
716 case XmlStyleFamily::TEXT_PARAGRAPH
:
717 if( rPropSetHelper
.hasProperty( PARA_STYLE_NAME_AUTO
) )
719 rPropSetHelper
.getValue( PARA_STYLE_NAME_AUTO
, rPropSet
,
722 if( rPropSetHelper
.hasProperty( PARA_CONDITIONAL_STYLE_NAME_AUTO
) )
724 rPropSetHelper
.getValue( PARA_CONDITIONAL_STYLE_NAME_AUTO
,
725 rPropSet
, true ) >>= sCondParent
;
732 if( std::any_of( aPropStates
.begin(), aPropStates
.end(), lcl_validPropState
) )
734 GetAutoStylePool().Add( nFamily
, sParent
, aPropStates
);
735 if( !sCondParent
.isEmpty() && sParent
!= sCondParent
)
736 GetAutoStylePool().Add( nFamily
, sCondParent
, aPropStates
);
740 OUString
XMLTextParagraphExport::Find(
741 XmlStyleFamily nFamily
,
742 const Reference
< XPropertySet
> & rPropSet
,
743 const OUString
& rParent
,
744 const XMLPropertyState
** ppAddStates
) const
746 OUString
sName( rParent
);
747 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper
;
750 case XmlStyleFamily::TEXT_PARAGRAPH
:
751 xPropMapper
= GetParaPropMapper();
753 case XmlStyleFamily::TEXT_FRAME
:
754 xPropMapper
= GetAutoFramePropMapper();
756 case XmlStyleFamily::TEXT_SECTION
:
757 xPropMapper
= GetSectionPropMapper();
759 case XmlStyleFamily::TEXT_RUBY
:
760 xPropMapper
= GetRubyPropMapper();
764 SAL_WARN_IF( !xPropMapper
.is(), "xmloff", "There is the property mapper?" );
765 if( !xPropMapper
.is() )
767 vector
<XMLPropertyState
> aPropStates(xPropMapper
->Filter(GetExport(), rPropSet
));
770 while( *ppAddStates
)
772 aPropStates
.push_back( **ppAddStates
);
776 if( std::any_of( aPropStates
.begin(), aPropStates
.end(), lcl_validPropState
) )
777 sName
= GetAutoStylePool().Find( nFamily
, sName
, aPropStates
);
782 OUString
XMLTextParagraphExport::FindTextStyleAndHyperlink(
783 const Reference
< XPropertySet
> & rPropSet
,
785 bool& rbHasCharStyle
,
786 bool& rbHasAutoStyle
,
787 const XMLPropertyState
** ppAddStates
) const
789 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper(GetTextPropMapper());
790 vector
<XMLPropertyState
> aPropStates(xPropMapper
->Filter(GetExport(), rPropSet
));
792 // Get parent and remove hyperlinks (they aren't of interest)
794 rbHyperlink
= rbHasCharStyle
= rbHasAutoStyle
= false;
795 sal_uInt16 nIgnoreProps
= 0;
796 rtl::Reference
< XMLPropertySetMapper
> xPM(xPropMapper
->getPropertySetMapper());
797 ::std::vector
< XMLPropertyState
>::iterator aFirstDel
= aPropStates
.end();
798 ::std::vector
< XMLPropertyState
>::iterator aSecondDel
= aPropStates
.end();
800 for( ::std::vector
< XMLPropertyState
>::iterator
801 i
= aPropStates
.begin();
802 nIgnoreProps
< 2 && i
!= aPropStates
.end();
805 if( i
->mnIndex
== -1 )
808 switch( xPM
->GetEntryContextId(i
->mnIndex
) )
810 case CTF_CHAR_STYLE_NAME
:
811 i
->maValue
>>= sName
;
813 rbHasCharStyle
= !sName
.isEmpty();
820 case CTF_HYPERLINK_URL
:
833 while( *ppAddStates
)
835 aPropStates
.push_back( **ppAddStates
);
839 if (aPropStates
.size() - nIgnoreProps
)
841 // erase the character style, otherwise the autostyle cannot be found!
842 // erase the hyperlink, otherwise the autostyle cannot be found!
845 // If two elements of a vector have to be deleted,
846 // we should delete the second one first.
848 aPropStates
.erase( aSecondDel
);
849 aPropStates
.erase( aFirstDel
);
851 sName
= GetAutoStylePool().Find(
852 XmlStyleFamily::TEXT_TEXT
,
853 OUString(), // AutoStyles should not have parents!
855 rbHasAutoStyle
= true;
861 // adjustments to support lists independent from list style
862 void XMLTextParagraphExport::exportListChange(
863 const XMLTextNumRuleInfo
& rPrevInfo
,
864 const XMLTextNumRuleInfo
& rNextInfo
)
867 if ( rPrevInfo
.GetLevel() > 0 )
869 sal_Int16 nListLevelsToBeClosed
= 0;
870 if ( !rNextInfo
.BelongsToSameList( rPrevInfo
) ||
871 rNextInfo
.GetLevel() <= 0 )
873 // close complete previous list
874 nListLevelsToBeClosed
= rPrevInfo
.GetLevel();
876 else if ( rPrevInfo
.GetLevel() > rNextInfo
.GetLevel() )
878 // close corresponding sub lists
879 SAL_WARN_IF( rNextInfo
.GetLevel() <= 0, "xmloff",
880 "<rPrevInfo.GetLevel() > 0> not hold. Serious defect." );
881 nListLevelsToBeClosed
= rPrevInfo
.GetLevel() - rNextInfo
.GetLevel();
884 if ( nListLevelsToBeClosed
> 0 &&
886 pListElements
->size() >= sal::static_int_cast
< sal_uInt32
>( 2 * nListLevelsToBeClosed
) )
889 for(size_t j
= 0; j
< 2; ++j
)
891 OUString
aElem(pListElements
->back());
892 pListElements
->pop_back();
893 GetExport().EndElement(aElem
, true);
896 // remove closed list from list stack
897 mpTextListsHelper
->PopListFromStack();
899 --nListLevelsToBeClosed
;
900 } while ( nListLevelsToBeClosed
> 0 );
904 const bool bExportODF
=
905 bool( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
);
906 const SvtSaveOptions::ODFSaneDefaultVersion eODFDefaultVersion
=
907 GetExport().getSaneDefaultVersion();
910 if ( rNextInfo
.GetLevel() > 0 )
912 bool bRootListToBeStarted
= false;
913 sal_Int16 nListLevelsToBeOpened
= 0;
914 if ( !rPrevInfo
.BelongsToSameList( rNextInfo
) ||
915 rPrevInfo
.GetLevel() <= 0 )
918 bRootListToBeStarted
= true;
919 nListLevelsToBeOpened
= rNextInfo
.GetLevel();
921 else if ( rNextInfo
.GetLevel() > rPrevInfo
.GetLevel() )
923 // open corresponding sub lists
924 SAL_WARN_IF( rPrevInfo
.GetLevel() <= 0, "xmloff",
925 "<rPrevInfo.GetLevel() > 0> not hold. Serious defect." );
926 nListLevelsToBeOpened
= rNextInfo
.GetLevel() - rPrevInfo
.GetLevel();
929 if ( nListLevelsToBeOpened
> 0 )
931 const OUString
& sListStyleName( rNextInfo
.GetNumRulesName() );
932 // Currently only the text documents support <ListId>.
933 // Thus, for other document types <sListId> is empty.
934 const OUString
& sListId( rNextInfo
.GetListId() );
935 bool bExportListStyle( true );
936 bool bRestartNumberingAtContinuedList( false );
937 sal_Int32
nRestartValueForContinuedList( -1 );
938 bool bContinueingPreviousSubList
= !bRootListToBeStarted
&&
939 rNextInfo
.IsContinueingPreviousSubTree();
941 GetExport().CheckAttrList();
943 if ( bRootListToBeStarted
)
945 if ( !mpTextListsHelper
->IsListProcessed( sListId
) )
948 eODFDefaultVersion
>= SvtSaveOptions::ODFSVER_012
&&
951 /* Property text:id at element <text:list> has to be
952 replaced by property xml:id (#i92221#)
954 GetExport().AddAttribute( XML_NAMESPACE_XML
,
958 mpTextListsHelper
->KeepListAsProcessed( sListId
,
964 const OUString
sNewListId(
965 mpTextListsHelper
->GenerateNewListId() );
967 eODFDefaultVersion
>= SvtSaveOptions::ODFSVER_012
&&
970 /* Property text:id at element <text:list> has to be
971 replaced by property xml:id (#i92221#)
973 GetExport().AddAttribute( XML_NAMESPACE_XML
,
978 const OUString sContinueListId
=
979 mpTextListsHelper
->GetLastContinuingListId( sListId
);
980 // store that list with list id <sNewListId> is last list,
981 // which has continued list with list id <sListId>
982 mpTextListsHelper
->StoreLastContinuingList( sListId
,
984 if ( sListStyleName
==
985 mpTextListsHelper
->GetListStyleOfLastProcessedList() &&
986 // Inconsistent behavior regarding lists (#i92811#)
988 mpTextListsHelper
->GetLastProcessedListId() &&
989 !rNextInfo
.IsRestart() )
991 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
992 XML_CONTINUE_NUMBERING
,
998 eODFDefaultVersion
>= SvtSaveOptions::ODFSVER_012
&&
1001 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1006 if ( rNextInfo
.IsRestart() &&
1007 ( nListLevelsToBeOpened
!= 1 ||
1008 !rNextInfo
.HasStartValue() ) )
1010 bRestartNumberingAtContinuedList
= true;
1011 nRestartValueForContinuedList
=
1012 rNextInfo
.GetListLevelStartValue();
1016 mpTextListsHelper
->KeepListAsProcessed( sNewListId
,
1021 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
1022 GetExport().EncodeStyleName( sListStyleName
) );
1023 bExportListStyle
= false;
1025 bRootListToBeStarted
= false;
1027 else if ( bExportListStyle
&&
1028 !mpTextListsHelper
->EqualsToTopListStyleOnStack( sListStyleName
) )
1030 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
1031 GetExport().EncodeStyleName( sListStyleName
) );
1032 bExportListStyle
= false;
1037 // rhbz#746174: also export list restart for non root list
1038 if (rNextInfo
.IsRestart() && !rNextInfo
.HasStartValue())
1040 bRestartNumberingAtContinuedList
= true;
1041 nRestartValueForContinuedList
=
1042 rNextInfo
.GetListLevelStartValue();
1046 if ( bContinueingPreviousSubList
)
1048 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1049 XML_CONTINUE_NUMBERING
, XML_TRUE
);
1050 bContinueingPreviousSubList
= false;
1053 enum XMLTokenEnum eLName
= XML_LIST
;
1055 OUString
aElem(GetExport().GetNamespaceMap().GetQNameByKey(
1057 GetXMLToken(eLName
) ) );
1058 GetExport().IgnorableWhitespace();
1059 GetExport().StartElement(aElem
, false);
1062 pListElements
.reset( new std::vector
<OUString
> );
1063 pListElements
->push_back(aElem
);
1065 mpTextListsHelper
->PushListOnStack( sListId
,
1068 // <text:list-header> or <text:list-item>
1069 GetExport().CheckAttrList();
1071 /* Export start value at correct list item (#i97309#) */
1072 if ( nListLevelsToBeOpened
== 1 )
1074 if ( rNextInfo
.HasStartValue() )
1076 OUStringBuffer aBuffer
;
1077 aBuffer
.append( static_cast<sal_Int32
>(rNextInfo
.GetStartValue()) );
1078 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_START_VALUE
,
1079 aBuffer
.makeStringAndClear() );
1081 else if (bRestartNumberingAtContinuedList
)
1083 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1085 OUString::number(nRestartValueForContinuedList
) );
1086 bRestartNumberingAtContinuedList
= false;
1090 eLName
= ( rNextInfo
.IsNumbered() || nListLevelsToBeOpened
> 1 )
1093 aElem
= GetExport().GetNamespaceMap().GetQNameByKey(
1095 GetXMLToken(eLName
) );
1096 GetExport().IgnorableWhitespace();
1097 GetExport().StartElement(aElem
, false);
1098 pListElements
->push_back(aElem
);
1100 // export of <text:number> element for last opened <text:list-item>, if requested
1101 if ( GetExport().exportTextNumberElement() &&
1102 eLName
== XML_LIST_ITEM
&& nListLevelsToBeOpened
== 1 && // last iteration --> last opened <text:list-item>
1103 !rNextInfo
.ListLabelString().isEmpty() )
1105 const OUString aTextNumberElem
=
1106 GetExport().GetNamespaceMap().GetQNameByKey(
1108 GetXMLToken(XML_NUMBER
) );
1109 GetExport().IgnorableWhitespace();
1110 GetExport().StartElement( aTextNumberElem
, false );
1111 GetExport().Characters( rNextInfo
.ListLabelString() );
1112 GetExport().EndElement( aTextNumberElem
, true );
1114 --nListLevelsToBeOpened
;
1115 } while ( nListLevelsToBeOpened
> 0 );
1119 bool bEndElement
= false;
1121 if ( rNextInfo
.GetLevel() > 0 &&
1122 rNextInfo
.IsNumbered() &&
1123 rPrevInfo
.BelongsToSameList( rNextInfo
) &&
1124 rPrevInfo
.GetLevel() >= rNextInfo
.GetLevel() )
1126 assert(pListElements
&& pListElements
->size() >= 2 && "list elements missing");
1127 bEndElement
= pListElements
&& pListElements
->size() >= 2;
1133 // close previous list-item
1134 GetExport().EndElement(pListElements
->back(), true );
1135 pListElements
->pop_back();
1137 // Only for sub lists (#i103745#)
1138 if ( rNextInfo
.IsRestart() && !rNextInfo
.HasStartValue() &&
1139 rNextInfo
.GetLevel() != 1 )
1141 // start new sub list respectively list on same list level
1142 GetExport().EndElement(pListElements
->back(), true );
1143 GetExport().IgnorableWhitespace();
1144 GetExport().StartElement(pListElements
->back(), false);
1147 // open new list-item
1148 GetExport().CheckAttrList();
1149 if( rNextInfo
.HasStartValue() )
1151 OUStringBuffer aBuffer
;
1152 aBuffer
.append( static_cast<sal_Int32
>(rNextInfo
.GetStartValue()) );
1153 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_START_VALUE
,
1154 aBuffer
.makeStringAndClear() );
1156 // Handle restart without start value on list level 1 (#i103745#)
1157 else if ( rNextInfo
.IsRestart() && /*!rNextInfo.HasStartValue() &&*/
1158 rNextInfo
.GetLevel() == 1 )
1160 OUStringBuffer aBuffer
;
1161 aBuffer
.append( static_cast<sal_Int32
>(rNextInfo
.GetListLevelStartValue()) );
1162 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_START_VALUE
,
1163 aBuffer
.makeStringAndClear() );
1165 if ( ( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
1166 GetExport().getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
1168 const OUString
& sListStyleName( rNextInfo
.GetNumRulesName() );
1169 if ( !mpTextListsHelper
->EqualsToTopListStyleOnStack( sListStyleName
) )
1171 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1173 GetExport().EncodeStyleName( sListStyleName
) );
1176 OUString
aElem( GetExport().GetNamespaceMap().GetQNameByKey(
1178 GetXMLToken(XML_LIST_ITEM
) ) );
1179 GetExport().IgnorableWhitespace();
1180 GetExport().StartElement(aElem
, false );
1181 pListElements
->push_back(aElem
);
1183 // export of <text:number> element for <text:list-item>, if requested
1184 if ( GetExport().exportTextNumberElement() &&
1185 !rNextInfo
.ListLabelString().isEmpty() )
1187 const OUString aTextNumberElem
=
1188 GetExport().GetNamespaceMap().GetQNameByKey(
1190 GetXMLToken(XML_NUMBER
) );
1191 GetExport().IgnorableWhitespace();
1192 GetExport().StartElement( aTextNumberElem
, false );
1193 GetExport().Characters( rNextInfo
.ListLabelString() );
1194 GetExport().EndElement( aTextNumberElem
, true );
1199 struct XMLTextParagraphExport::Impl
1201 typedef ::std::map
<Reference
<XFormField
>, sal_Int32
> FieldMarkMap_t
;
1202 FieldMarkMap_t m_FieldMarkMap
;
1205 sal_Int32
AddFieldMarkStart(Reference
<XFormField
> const& i_xFieldMark
)
1207 assert(m_FieldMarkMap
.find(i_xFieldMark
) == m_FieldMarkMap
.end());
1208 sal_Int32
const ret(m_FieldMarkMap
.size());
1209 m_FieldMarkMap
.insert(::std::make_pair(i_xFieldMark
, ret
));
1212 sal_Int32
GetFieldMarkIndex(Reference
<XFormField
> const& i_xFieldMark
)
1214 FieldMarkMap_t::const_iterator
const it(
1215 m_FieldMarkMap
.find(i_xFieldMark
));
1216 // rely on SwXFieldmark::CreateXFieldmark returning the same instance
1217 // because the Reference in m_FieldMarkMap will keep it alive
1218 assert(it
!= m_FieldMarkMap
.end());
1223 XMLTextParagraphExport::XMLTextParagraphExport(
1225 SvXMLAutoStylePoolP
& rASP
1227 XMLStyleExport( rExp
, &rASP
),
1229 rAutoStylePool( rASP
),
1230 pBoundFrameSets(new BoundFrameSets(GetExport().GetModel())),
1231 maListAutoPool( GetExport() ),
1235 mpTextListsHelper( nullptr ),
1236 maTextListsHelperStack(),
1238 aCharStyleNamesPropInfoCache( gsCharStyleNames
)
1240 rtl::Reference
< XMLPropertySetMapper
> xPropMapper(new XMLTextPropertySetMapper( TextPropMap::PARA
, true ));
1241 xParaPropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1244 OUString
sFamily( GetXMLToken(XML_PARAGRAPH
) );
1245 OUString
aPrefix(u
'P');
1246 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_PARAGRAPH
, sFamily
,
1247 xParaPropMapper
, aPrefix
);
1249 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::TEXT
, true );
1250 xTextPropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1252 sFamily
= GetXMLToken(XML_TEXT
);
1254 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_TEXT
, sFamily
,
1255 xTextPropMapper
, aPrefix
);
1257 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::AUTO_FRAME
, true );
1258 xAutoFramePropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1260 sFamily
= XML_STYLE_FAMILY_SD_GRAPHICS_NAME
;
1262 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_FRAME
, sFamily
,
1263 xAutoFramePropMapper
, aPrefix
);
1265 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::SECTION
, true );
1266 xSectionPropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1268 sFamily
= GetXMLToken( XML_SECTION
);
1270 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_SECTION
, sFamily
,
1271 xSectionPropMapper
, aPrefix
);
1273 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::RUBY
, true );
1274 xRubyPropMapper
= new SvXMLExportPropertyMapper( xPropMapper
);
1275 sFamily
= GetXMLToken( XML_RUBY
);
1277 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_RUBY
, sFamily
,
1278 xRubyPropMapper
, aPrefix
);
1280 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::FRAME
, true );
1281 xFramePropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1284 pSectionExport
.reset( new XMLSectionExport( rExp
, *this ) );
1285 pIndexMarkExport
.reset( new XMLIndexMarkExport( rExp
) );
1287 if( ! IsBlockMode() &&
1288 Reference
<XRedlinesSupplier
>( GetExport().GetModel(), UNO_QUERY
).is())
1289 pRedlineExport
.reset( new XMLRedlineExport( rExp
) );
1291 // The text field helper needs a pre-constructed XMLPropertyState
1292 // to export the combined characters field. We construct that
1293 // here, because we need the text property mapper to do it.
1295 // construct Any value, then find index
1296 sal_Int32 nIndex
= xTextPropMapper
->getPropertySetMapper()->FindEntryIndex(
1297 "", XML_NAMESPACE_STYLE
,
1298 GetXMLToken(XML_TEXT_COMBINE
));
1299 pFieldExport
.reset( new XMLTextFieldExport( rExp
, std::make_unique
<XMLPropertyState
>( nIndex
, uno::makeAny(true) ) ) );
1300 PushNewTextListsHelper();
1303 XMLTextParagraphExport::~XMLTextParagraphExport()
1305 pRedlineExport
.reset();
1306 pIndexMarkExport
.reset();
1307 pSectionExport
.reset();
1308 pFieldExport
.reset();
1309 pListElements
.reset();
1311 txtparae_bContainsIllegalCharacters
= false;
1313 PopTextListsHelper();
1314 SAL_WARN_IF( !maTextListsHelperStack
.empty(), "xmloff",
1315 "misusage of text lists helper stack - it is not empty. Serious defect" );
1318 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateShapeExtPropMapper(
1319 SvXMLExport
& rExport
)
1321 rtl::Reference
< XMLPropertySetMapper
> xPropMapper
=
1322 new XMLTextPropertySetMapper( TextPropMap::SHAPE
, true );
1323 return new XMLTextExportPropertySetMapper( xPropMapper
, rExport
);
1326 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateCharExtPropMapper(
1327 SvXMLExport
& rExport
)
1329 XMLPropertySetMapper
*pPropMapper
=
1330 new XMLTextPropertySetMapper( TextPropMap::TEXT
, true );
1331 return new XMLTextExportPropertySetMapper( pPropMapper
, rExport
);
1334 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateParaExtPropMapper(
1335 SvXMLExport
& rExport
)
1337 XMLPropertySetMapper
*pPropMapper
=
1338 new XMLTextPropertySetMapper( TextPropMap::SHAPE_PARA
, true );
1339 return new XMLTextExportPropertySetMapper( pPropMapper
, rExport
);
1342 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateParaDefaultExtPropMapper(
1343 SvXMLExport
& rExport
)
1345 XMLPropertySetMapper
*pPropMapper
=
1346 new XMLTextPropertySetMapper( TextPropMap::TEXT_ADDITIONAL_DEFAULTS
, true );
1347 return new XMLTextExportPropertySetMapper( pPropMapper
, rExport
);
1350 void XMLTextParagraphExport::exportPageFrames( bool bIsProgress
)
1352 const TextContentSet
& rTexts
= pBoundFrameSets
->GetTexts()->GetPageBoundContents();
1353 const TextContentSet
& rGraphics
= pBoundFrameSets
->GetGraphics()->GetPageBoundContents();
1354 const TextContentSet
& rEmbeddeds
= pBoundFrameSets
->GetEmbeddeds()->GetPageBoundContents();
1355 const TextContentSet
& rShapes
= pBoundFrameSets
->GetShapes()->GetPageBoundContents();
1356 for(TextContentSet::const_iterator_t it
= rTexts
.getBegin();
1357 it
!= rTexts
.getEnd();
1359 exportTextFrame(*it
, false/*bAutoStyles*/, bIsProgress
, true);
1360 for(TextContentSet::const_iterator_t it
= rGraphics
.getBegin();
1361 it
!= rGraphics
.getEnd();
1363 exportTextGraphic(*it
, false/*bAutoStyles*/);
1364 for(TextContentSet::const_iterator_t it
= rEmbeddeds
.getBegin();
1365 it
!= rEmbeddeds
.getEnd();
1367 exportTextEmbedded(*it
, false/*bAutoStyles*/);
1368 for(TextContentSet::const_iterator_t it
= rShapes
.getBegin();
1369 it
!= rShapes
.getEnd();
1371 exportShape(*it
, false/*bAutoStyles*/);
1374 void XMLTextParagraphExport::exportFrameFrames(
1377 const Reference
< XTextFrame
> *pParentTxtFrame
)
1379 const TextContentSet
* const pTexts
= pBoundFrameSets
->GetTexts()->GetFrameBoundContents(*pParentTxtFrame
);
1381 for(TextContentSet::const_iterator_t it
= pTexts
->getBegin();
1382 it
!= pTexts
->getEnd();
1384 exportTextFrame(*it
, bAutoStyles
, bIsProgress
, true);
1385 const TextContentSet
* const pGraphics
= pBoundFrameSets
->GetGraphics()->GetFrameBoundContents(*pParentTxtFrame
);
1387 for(TextContentSet::const_iterator_t it
= pGraphics
->getBegin();
1388 it
!= pGraphics
->getEnd();
1390 exportTextGraphic(*it
, bAutoStyles
);
1391 const TextContentSet
* const pEmbeddeds
= pBoundFrameSets
->GetEmbeddeds()->GetFrameBoundContents(*pParentTxtFrame
);
1393 for(TextContentSet::const_iterator_t it
= pEmbeddeds
->getBegin();
1394 it
!= pEmbeddeds
->getEnd();
1396 exportTextEmbedded(*it
, bAutoStyles
);
1397 const TextContentSet
* const pShapes
= pBoundFrameSets
->GetShapes()->GetFrameBoundContents(*pParentTxtFrame
);
1399 for(TextContentSet::const_iterator_t it
= pShapes
->getBegin();
1400 it
!= pShapes
->getEnd();
1402 exportShape(*it
, bAutoStyles
);
1405 // bookmarks, reference marks (and TOC marks) are the same except for the
1406 // element names. We use the same method for export and it an array with
1407 // the proper element names
1408 const enum XMLTokenEnum lcl_XmlReferenceElements
[] = {
1409 XML_REFERENCE_MARK
, XML_REFERENCE_MARK_START
, XML_REFERENCE_MARK_END
};
1410 const enum XMLTokenEnum lcl_XmlBookmarkElements
[] = {
1411 XML_BOOKMARK
, XML_BOOKMARK_START
, XML_BOOKMARK_END
};
1413 // This function replaces the text portion iteration during auto style
1415 void XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress
)
1417 GetExport().GetShapeExport(); // make sure the graphics styles family is added
1422 const bool bAutoStyles
= true;
1423 const bool bExportContent
= false;
1425 // Export AutoStyles:
1426 Reference
< XAutoStylesSupplier
> xAutoStylesSupp( GetExport().GetModel(), UNO_QUERY
);
1427 if ( xAutoStylesSupp
.is() )
1429 Reference
< XAutoStyles
> xAutoStyleFamilies
= xAutoStylesSupp
->getAutoStyles();
1430 const auto collectFamily
= [this, &xAutoStyleFamilies
](const OUString
& sName
,
1431 XmlStyleFamily nFamily
) {
1432 Any aAny
= xAutoStyleFamilies
->getByName( sName
);
1433 Reference
< XAutoStyleFamily
> xAutoStyles
= *o3tl::doAccess
<Reference
<XAutoStyleFamily
>>(aAny
);
1434 Reference
< XEnumeration
> xAutoStylesEnum( xAutoStyles
->createEnumeration() );
1436 while ( xAutoStylesEnum
->hasMoreElements() )
1438 aAny
= xAutoStylesEnum
->nextElement();
1439 Reference
< XAutoStyle
> xAutoStyle
= *o3tl::doAccess
<Reference
<XAutoStyle
>>(aAny
);
1440 Reference
< XPropertySet
> xPSet( xAutoStyle
, uno::UNO_QUERY
);
1441 Add( nFamily
, xPSet
, nullptr, true );
1444 collectFamily("CharacterStyles", XmlStyleFamily::TEXT_TEXT
);
1445 collectFamily("RubyStyles", XmlStyleFamily::TEXT_RUBY
);
1446 collectFamily("ParagraphStyles", XmlStyleFamily::TEXT_PARAGRAPH
);
1449 // Export Field AutoStyles:
1450 Reference
< XTextFieldsSupplier
> xTextFieldsSupp( GetExport().GetModel(), UNO_QUERY
);
1451 if ( xTextFieldsSupp
.is() )
1453 Reference
< XEnumerationAccess
> xTextFields
= xTextFieldsSupp
->getTextFields();
1454 Reference
< XEnumeration
> xTextFieldsEnum( xTextFields
->createEnumeration() );
1456 while ( xTextFieldsEnum
->hasMoreElements() )
1458 Any aAny
= xTextFieldsEnum
->nextElement();
1459 Reference
< XTextField
> xTextField
= *o3tl::doAccess
<Reference
<XTextField
>>(aAny
);
1460 exportTextField( xTextField
, bAutoStyles
, bIsProgress
,
1461 !xAutoStylesSupp
.is(), nullptr );
1464 Reference
< XPropertySet
> xSet( xTextField
, UNO_QUERY
);
1465 Reference
< XText
> xText
;
1466 Any a
= xSet
->getPropertyValue("TextRange");
1470 exportText( xText
, true, bIsProgress
, bExportContent
);
1471 GetExport().GetTextParagraphExport()
1472 ->collectTextAutoStyles( xText
);
1481 // Export text frames:
1482 Reference
<XEnumeration
> xTextFramesEnum
= pBoundFrameSets
->GetTexts()->createEnumeration();
1483 if(xTextFramesEnum
.is())
1484 while(xTextFramesEnum
->hasMoreElements())
1486 Reference
<XTextContent
> xTxtCntnt(xTextFramesEnum
->nextElement(), UNO_QUERY
);
1488 exportTextFrame(xTxtCntnt
, bAutoStyles
, bIsProgress
, bExportContent
);
1491 // Export graphic objects:
1492 Reference
<XEnumeration
> xGraphicsEnum
= pBoundFrameSets
->GetGraphics()->createEnumeration();
1493 if(xGraphicsEnum
.is())
1494 while(xGraphicsEnum
->hasMoreElements())
1496 Reference
<XTextContent
> xTxtCntnt(xGraphicsEnum
->nextElement(), UNO_QUERY
);
1498 exportTextGraphic(xTxtCntnt
, true);
1501 // Export embedded objects:
1502 Reference
<XEnumeration
> xEmbeddedsEnum
= pBoundFrameSets
->GetEmbeddeds()->createEnumeration();
1503 if(xEmbeddedsEnum
.is())
1504 while(xEmbeddedsEnum
->hasMoreElements())
1506 Reference
<XTextContent
> xTxtCntnt(xEmbeddedsEnum
->nextElement(), UNO_QUERY
);
1508 exportTextEmbedded(xTxtCntnt
, true);
1512 Reference
<XEnumeration
> xShapesEnum
= pBoundFrameSets
->GetShapes()->createEnumeration();
1513 if(xShapesEnum
.is())
1514 while(xShapesEnum
->hasMoreElements())
1516 Reference
<XTextContent
> xTxtCntnt(xShapesEnum
->nextElement(), UNO_QUERY
);
1519 Reference
<XServiceInfo
> xServiceInfo(xTxtCntnt
, UNO_QUERY
);
1520 if( xServiceInfo
->supportsService(gsShapeService
))
1521 exportShape(xTxtCntnt
, true);
1526 // AutoStyles for sections
1527 Reference
< XTextSectionsSupplier
> xSectionsSupp( GetExport().GetModel(), UNO_QUERY
);
1528 if ( xSectionsSupp
.is() )
1530 Reference
< XIndexAccess
> xSections( xSectionsSupp
->getTextSections(), UNO_QUERY
);
1531 if ( xSections
.is() )
1533 nCount
= xSections
->getCount();
1534 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
1536 Any aAny
= xSections
->getByIndex( i
);
1537 Reference
< XTextSection
> xSection
= *o3tl::doAccess
<Reference
<XTextSection
>>(aAny
);
1538 Reference
< XPropertySet
> xPSet( xSection
, uno::UNO_QUERY
);
1539 Add( XmlStyleFamily::TEXT_SECTION
, xPSet
);
1544 // AutoStyles for tables (Note: suppress autostyle collection for paragraphs in exportTable)
1545 Reference
< XTextTablesSupplier
> xTablesSupp( GetExport().GetModel(), UNO_QUERY
);
1546 if ( xTablesSupp
.is() )
1548 Reference
< XIndexAccess
> xTables( xTablesSupp
->getTextTables(), UNO_QUERY
);
1551 nCount
= xTables
->getCount();
1552 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
1554 Any aAny
= xTables
->getByIndex( i
);
1555 Reference
< XTextTable
> xTable
= *o3tl::doAccess
<Reference
<XTextTable
>>(aAny
);
1556 exportTable( xTable
, true, true );
1561 Reference
< XNumberingRulesSupplier
> xNumberingRulesSupp( GetExport().GetModel(), UNO_QUERY
);
1562 if ( xNumberingRulesSupp
.is() )
1564 Reference
< XIndexAccess
> xNumberingRules
= xNumberingRulesSupp
->getNumberingRules();
1565 nCount
= xNumberingRules
->getCount();
1566 // Custom outline assignment lost after re-importing sxw (#i73361#)
1567 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
1569 Reference
< XIndexReplace
> xNumRule( xNumberingRules
->getByIndex( i
), UNO_QUERY
);
1570 if( xNumRule
.is() && xNumRule
->getCount() )
1572 Reference
< XNamed
> xNamed( xNumRule
, UNO_QUERY
);
1575 sName
= xNamed
->getName();
1576 bool bAdd
= sName
.isEmpty();
1579 Reference
< XPropertySet
> xNumPropSet( xNumRule
,
1581 if( xNumPropSet
.is() &&
1582 xNumPropSet
->getPropertySetInfo()
1583 ->hasPropertyByName( "IsAutomatic" ) )
1585 bAdd
= *o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "IsAutomatic" ));
1586 // Check on outline style (#i73361#)
1588 xNumPropSet
->getPropertySetInfo()
1589 ->hasPropertyByName( "NumberingIsOutline" ) )
1591 bAdd
= !(*o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "NumberingIsOutline" )));
1600 maListAutoPool
.Add( xNumRule
);
1607 void XMLTextParagraphExport::exportText(
1608 const Reference
< XText
> & rText
,
1611 bool bExportParagraph
,
1612 TextPNS eExtensionNS
)
1615 GetExport().GetShapeExport(); // make sure the graphics styles family
1617 Reference
< XEnumerationAccess
> xEA( rText
, UNO_QUERY
);
1621 Reference
< XEnumeration
> xParaEnum(xEA
->createEnumeration());
1622 Reference
< XPropertySet
> xPropertySet( rText
, UNO_QUERY
);
1623 Reference
< XTextSection
> xBaseSection
;
1625 // #97718# footnotes don't supply paragraph enumerations in some cases
1626 // This is always a bug, but at least we don't want to crash.
1627 SAL_WARN_IF( !xParaEnum
.is(), "xmloff", "We need a paragraph enumeration" );
1628 if( ! xParaEnum
.is() )
1631 if (xPropertySet
.is())
1633 Reference
< XPropertySetInfo
> xInfo ( xPropertySet
->getPropertySetInfo() );
1637 if (xInfo
->hasPropertyByName( gsTextSection
))
1639 xPropertySet
->getPropertyValue(gsTextSection
) >>= xBaseSection
;
1644 // #96530# Export redlines at start & end of XText before & after
1645 // exporting the text content enumeration
1646 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1647 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, true );
1648 exportTextContentEnumeration( xParaEnum
, bAutoStyles
, xBaseSection
,
1649 bIsProgress
, bExportParagraph
, nullptr, eExtensionNS
);
1650 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1651 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, false );
1654 void XMLTextParagraphExport::exportText(
1655 const Reference
< XText
> & rText
,
1656 const Reference
< XTextSection
> & rBaseSection
,
1659 bool bExportParagraph
)
1662 GetExport().GetShapeExport(); // make sure the graphics styles family
1664 Reference
< XEnumerationAccess
> xEA( rText
, UNO_QUERY
);
1665 Reference
< XEnumeration
> xParaEnum(xEA
->createEnumeration());
1667 // #98165# don't continue without a paragraph enumeration
1668 if( ! xParaEnum
.is() )
1671 // #96530# Export redlines at start & end of XText before & after
1672 // exporting the text content enumeration
1673 Reference
<XPropertySet
> xPropertySet
;
1674 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1676 xPropertySet
.set(rText
, uno::UNO_QUERY
);
1677 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, true );
1679 exportTextContentEnumeration( xParaEnum
, bAutoStyles
, rBaseSection
,
1680 bIsProgress
, bExportParagraph
);
1681 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1682 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, false );
1685 void XMLTextParagraphExport::exportTextContentEnumeration(
1686 const Reference
< XEnumeration
> & rContEnum
,
1688 const Reference
< XTextSection
> & rBaseSection
,
1690 bool bExportParagraph
,
1691 const Reference
< XPropertySet
> *pRangePropSet
,
1692 TextPNS eExtensionNS
)
1694 SAL_WARN_IF( !rContEnum
.is(), "xmloff", "No enumeration to export!" );
1695 bool bHasMoreElements
= rContEnum
->hasMoreElements();
1696 if( !bHasMoreElements
)
1699 XMLTextNumRuleInfo aPrevNumInfo
;
1700 XMLTextNumRuleInfo aNextNumInfo
;
1702 bool bHasContent
= false;
1703 Reference
<XTextSection
> xCurrentTextSection(rBaseSection
);
1705 MultiPropertySetHelper
aPropSetHelper(
1706 bAutoStyles
? aParagraphPropertyNamesAuto
:
1707 aParagraphPropertyNames
);
1709 bool bHoldElement
= false;
1710 Reference
< XTextContent
> xTxtCntnt
;
1711 while( bHoldElement
|| bHasMoreElements
)
1715 bHoldElement
= false;
1719 xTxtCntnt
.set(rContEnum
->nextElement(), uno::UNO_QUERY
);
1721 aPropSetHelper
.resetValues();
1725 Reference
<XServiceInfo
> xServiceInfo( xTxtCntnt
, UNO_QUERY
);
1726 if( xServiceInfo
->supportsService( gsParagraphService
) )
1730 exportListAndSectionChange( xCurrentTextSection
, xTxtCntnt
,
1731 aPrevNumInfo
, aNextNumInfo
,
1736 /* Pass list auto style pool to <XMLTextNumRuleInfo> instance
1737 Pass info about request to export <text:number> element
1738 to <XMLTextNumRuleInfo> instance (#i69627#)
1740 aNextNumInfo
.Set( xTxtCntnt
,
1741 GetExport().writeOutlineStyleAsNormalListStyle(),
1742 GetListAutoStylePool(),
1743 GetExport().exportTextNumberElement() );
1745 exportListAndSectionChange( xCurrentTextSection
, aPropSetHelper
,
1746 TEXT_SECTION
, xTxtCntnt
,
1747 aPrevNumInfo
, aNextNumInfo
,
1751 // if we found a mute section: skip all section content
1752 if (pSectionExport
->IsMuteSection(xCurrentTextSection
))
1754 // Make sure headings are exported anyway.
1756 pSectionExport
->ExportMasterDocHeadingDummies();
1758 while (rContEnum
->hasMoreElements() &&
1759 XMLSectionExport::IsInSection( xCurrentTextSection
,
1762 xTxtCntnt
.set(rContEnum
->nextElement(), uno::UNO_QUERY
);
1763 aPropSetHelper
.resetValues();
1764 aNextNumInfo
.Reset();
1766 // the first non-mute element still needs to be processed
1768 ! XMLSectionExport::IsInSection( xCurrentTextSection
,
1772 exportParagraph( xTxtCntnt
, bAutoStyles
, bIsProgress
,
1773 bExportParagraph
, aPropSetHelper
, eExtensionNS
);
1776 else if( xServiceInfo
->supportsService( gsTableService
) )
1780 aNextNumInfo
.Reset();
1783 exportListAndSectionChange( xCurrentTextSection
, xTxtCntnt
,
1784 aPrevNumInfo
, aNextNumInfo
,
1787 if (! pSectionExport
->IsMuteSection(xCurrentTextSection
))
1789 // export start + end redlines (for wholly redlined tables)
1790 if ((! bAutoStyles
) && (nullptr != pRedlineExport
))
1791 pRedlineExport
->ExportStartOrEndRedline(xTxtCntnt
, true);
1793 exportTable( xTxtCntnt
, bAutoStyles
, bIsProgress
);
1795 if ((! bAutoStyles
) && (nullptr != pRedlineExport
))
1796 pRedlineExport
->ExportStartOrEndRedline(xTxtCntnt
, false);
1798 else if( !bAutoStyles
)
1800 // Make sure headings are exported anyway.
1801 pSectionExport
->ExportMasterDocHeadingDummies();
1806 else if( xServiceInfo
->supportsService( gsTextFrameService
) )
1808 exportTextFrame( xTxtCntnt
, bAutoStyles
, bIsProgress
, true, pRangePropSet
);
1810 else if( xServiceInfo
->supportsService( gsTextGraphicService
) )
1812 exportTextGraphic( xTxtCntnt
, bAutoStyles
, pRangePropSet
);
1814 else if( xServiceInfo
->supportsService( gsTextEmbeddedService
) )
1816 exportTextEmbedded( xTxtCntnt
, bAutoStyles
, pRangePropSet
);
1818 else if( xServiceInfo
->supportsService( gsShapeService
) )
1820 exportShape( xTxtCntnt
, bAutoStyles
, pRangePropSet
);
1824 SAL_WARN_IF( xTxtCntnt
.is(), "xmloff", "unknown text content" );
1829 aPrevNumInfo
= aNextNumInfo
;
1832 bHasMoreElements
= rContEnum
->hasMoreElements();
1835 if( bHasContent
&& !bAutoStyles
)
1837 aNextNumInfo
.Reset();
1839 // close open lists and sections; no new styles
1840 exportListAndSectionChange( xCurrentTextSection
, rBaseSection
,
1841 aPrevNumInfo
, aNextNumInfo
,
1846 void XMLTextParagraphExport::exportParagraph(
1847 const Reference
< XTextContent
> & rTextContent
,
1848 bool bAutoStyles
, bool bIsProgress
, bool bExportParagraph
,
1849 MultiPropertySetHelper
& rPropSetHelper
, TextPNS eExtensionNS
)
1851 sal_Int16 nOutlineLevel
= -1;
1855 ProgressBarHelper
*pProgress
= GetExport().GetProgressBarHelper();
1856 pProgress
->SetValue( pProgress
->GetValue()+1 );
1859 // get property set or multi property set and initialize helper
1860 Reference
<XMultiPropertySet
> xMultiPropSet( rTextContent
, UNO_QUERY
);
1861 Reference
<XPropertySet
> xPropSet( rTextContent
, UNO_QUERY
);
1863 // check for supported properties
1864 if( !rPropSetHelper
.checkedProperties() )
1865 rPropSetHelper
.hasProperties( xPropSet
->getPropertySetInfo() );
1867 // if( xMultiPropSet.is() )
1868 // rPropSetHelper.getValues( xMultiPropSet );
1870 // rPropSetHelper.getValues( xPropSet );
1872 if( bExportParagraph
)
1876 Add( XmlStyleFamily::TEXT_PARAGRAPH
, rPropSetHelper
, xPropSet
);
1880 // xml:id for RDF metadata
1881 GetExport().AddAttributeXmlId(rTextContent
);
1882 GetExport().AddAttributesRDFa(rTextContent
);
1885 if( rPropSetHelper
.hasProperty( PARA_STYLE_NAME
) )
1887 if( xMultiPropSet
.is() )
1888 rPropSetHelper
.getValue( PARA_STYLE_NAME
,
1889 xMultiPropSet
) >>= sStyle
;
1891 rPropSetHelper
.getValue( PARA_STYLE_NAME
,
1892 xPropSet
) >>= sStyle
;
1895 if( rTextContent
.is() )
1897 const OUString
& rIdentifier
= GetExport().getInterfaceToIdentifierMapper().getIdentifier( rTextContent
);
1898 if( !rIdentifier
.isEmpty() )
1900 // FIXME: this is just temporary until EditEngine
1901 // paragraphs implement XMetadatable.
1902 // then that must be used and not the mapper, because
1903 // when both can be used we get two xml:id!
1904 uno::Reference
<rdf::XMetadatable
> const xMeta(rTextContent
,
1906 OSL_ENSURE(!xMeta
.is(), "paragraph that implements "
1907 "XMetadatable used in interfaceToIdentifierMapper?");
1908 GetExport().AddAttributeIdLegacy(XML_NAMESPACE_TEXT
,
1913 OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_PARAGRAPH
, xPropSet
, sStyle
);
1914 if ( sAutoStyle
.isEmpty() )
1915 sAutoStyle
= sStyle
;
1916 if( !sAutoStyle
.isEmpty() )
1917 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
1918 GetExport().EncodeStyleName( sAutoStyle
) );
1920 if( rPropSetHelper
.hasProperty( PARA_CONDITIONAL_STYLE_NAME
) )
1922 OUString sCondStyle
;
1923 if( xMultiPropSet
.is() )
1924 rPropSetHelper
.getValue( PARA_CONDITIONAL_STYLE_NAME
,
1925 xMultiPropSet
) >>= sCondStyle
;
1927 rPropSetHelper
.getValue( PARA_CONDITIONAL_STYLE_NAME
,
1928 xPropSet
) >>= sCondStyle
;
1929 if( sCondStyle
!= sStyle
)
1931 sCondStyle
= Find( XmlStyleFamily::TEXT_PARAGRAPH
, xPropSet
,
1933 if( !sCondStyle
.isEmpty() )
1934 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1935 XML_COND_STYLE_NAME
,
1936 GetExport().EncodeStyleName( sCondStyle
) );
1940 if( rPropSetHelper
.hasProperty( PARA_OUTLINE_LEVEL
) )
1942 if( xMultiPropSet
.is() )
1943 rPropSetHelper
.getValue( PARA_OUTLINE_LEVEL
,
1944 xMultiPropSet
) >>= nOutlineLevel
;
1946 rPropSetHelper
.getValue( PARA_OUTLINE_LEVEL
,
1947 xPropSet
) >>= nOutlineLevel
;
1949 if( 0 < nOutlineLevel
)
1951 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1953 OUString::number( sal_Int32( nOutlineLevel
) ) );
1955 if ( rPropSetHelper
.hasProperty( PARA_OUTLINE_CONTENT_VISIBLE
) )
1957 uno::Sequence
<beans::PropertyValue
> propList
;
1958 bool bIsOutlineContentVisible
= true;
1959 if( xMultiPropSet
.is() )
1960 rPropSetHelper
.getValue(
1961 PARA_OUTLINE_CONTENT_VISIBLE
, xMultiPropSet
) >>= propList
;
1963 rPropSetHelper
.getValue(
1964 PARA_OUTLINE_CONTENT_VISIBLE
, xPropSet
) >>= propList
;
1965 for (const auto& rProp
: std::as_const(propList
))
1967 OUString propName
= rProp
.Name
;
1968 if (propName
== "OutlineContentVisibleAttr")
1970 rProp
.Value
>>= bIsOutlineContentVisible
;
1974 if (!bIsOutlineContentVisible
)
1976 GetExport().AddAttribute( XML_NAMESPACE_LO_EXT
,
1977 XML_OUTLINE_CONTENT_VISIBLE
,
1982 if( rPropSetHelper
.hasProperty( NUMBERING_IS_NUMBER
) )
1984 bool bIsNumber
= false;
1985 if( xMultiPropSet
.is() )
1986 rPropSetHelper
.getValue(
1987 NUMBERING_IS_NUMBER
, xMultiPropSet
) >>= bIsNumber
;
1989 rPropSetHelper
.getValue(
1990 NUMBERING_IS_NUMBER
, xPropSet
) >>= bIsNumber
;
1992 OUString sListStyleName
;
1993 if( xMultiPropSet
.is() )
1994 rPropSetHelper
.getValue(
1995 PARA_NUMBERING_STYLENAME
, xMultiPropSet
) >>= sListStyleName
;
1997 rPropSetHelper
.getValue(
1998 PARA_NUMBERING_STYLENAME
, xPropSet
) >>= sListStyleName
;
2000 bool bAssignedtoOutlineStyle
= false;
2002 Reference
< XChapterNumberingSupplier
> xCNSupplier( GetExport().GetModel(), UNO_QUERY
);
2004 if (xCNSupplier
.is())
2006 Reference
< XIndexReplace
> xNumRule ( xCNSupplier
->getChapterNumberingRules() );
2007 SAL_WARN_IF( !xNumRule
.is(), "xmloff", "no chapter numbering rules" );
2011 Reference
< XPropertySet
> xNumRulePropSet( xNumRule
, UNO_QUERY
);
2012 OUString sOutlineName
;
2013 xNumRulePropSet
->getPropertyValue(
2014 "Name" ) >>= sOutlineName
;
2015 bAssignedtoOutlineStyle
= ( sListStyleName
== sOutlineName
);
2020 if( ! bIsNumber
&& bAssignedtoOutlineStyle
)
2021 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
2027 bool bIsRestartNumbering
= false;
2029 Reference
< XPropertySetInfo
>
2030 xPropSetInfo(xMultiPropSet
.is() ?
2031 xMultiPropSet
->getPropertySetInfo():
2032 xPropSet
->getPropertySetInfo());
2035 hasPropertyByName("ParaIsNumberingRestart"))
2037 xPropSet
->getPropertyValue("ParaIsNumberingRestart")
2038 >>= bIsRestartNumbering
;
2041 if (bIsRestartNumbering
)
2043 GetExport().AddAttribute(XML_NAMESPACE_TEXT
,
2044 XML_RESTART_NUMBERING
,
2048 hasPropertyByName("NumberingStartValue"))
2050 sal_Int32 nStartValue
= 0;
2052 xPropSet
->getPropertyValue("NumberingStartValue")
2056 AddAttribute(XML_NAMESPACE_TEXT
,
2058 OUString::number(nStartValue
));
2067 Reference
< XEnumerationAccess
> xEA( rTextContent
, UNO_QUERY
);
2068 Reference
< XEnumeration
> xTextEnum
= xEA
->createEnumeration();
2069 const bool bHasPortions
= xTextEnum
.is();
2071 Reference
< XEnumeration
> xContentEnum
;
2072 Reference
< XContentEnumerationAccess
> xCEA( rTextContent
, UNO_QUERY
);
2074 xContentEnum
.set(xCEA
->createContentEnumeration( gsTextContentService
));
2075 const bool bHasContentEnum
= xContentEnum
.is() &&
2076 xContentEnum
->hasMoreElements();
2078 Reference
< XTextSection
> xSection
;
2079 if( bHasContentEnum
)
2081 // For the auto styles, the multi property set helper is only used
2082 // if hard attributes are existing. Therefore, it seems to be a better
2083 // strategy to have the TextSection property separate, because otherwise
2084 // we always retrieve the style names even if they are not required.
2087 if( xPropSet
->getPropertySetInfo()->hasPropertyByName( gsTextSection
) )
2089 xSection
.set(xPropSet
->getPropertyValue( gsTextSection
), uno::UNO_QUERY
);
2094 if( rPropSetHelper
.hasProperty( TEXT_SECTION
) )
2096 xSection
.set(rPropSetHelper
.getValue( TEXT_SECTION
), uno::UNO_QUERY
);
2101 bool bPrevCharIsSpace(true); // true because whitespace at start is ignored
2105 if( bHasContentEnum
)
2106 exportTextContentEnumeration(
2107 xContentEnum
, bAutoStyles
, xSection
,
2111 exportTextRangeEnumeration(xTextEnum
, bAutoStyles
, bIsProgress
, bPrevCharIsSpace
);
2116 enum XMLTokenEnum eElem
=
2117 0 < nOutlineLevel
? XML_H
: XML_P
;
2118 SvXMLElementExport
aElem( GetExport(), eExtensionNS
== TextPNS::EXTENSION
? XML_NAMESPACE_LO_EXT
: XML_NAMESPACE_TEXT
, eElem
,
2120 if( bHasContentEnum
)
2122 exportTextContentEnumeration(
2123 xContentEnum
, bAutoStyles
, xSection
,
2126 exportTextRangeEnumeration(xTextEnum
, bAutoStyles
, bIsProgress
, bPrevCharIsSpace
);
2130 void XMLTextParagraphExport::exportTextRangeEnumeration(
2131 const Reference
< XEnumeration
> & rTextEnum
,
2132 bool bAutoStyles
, bool bIsProgress
,
2133 bool & rPrevCharIsSpace
)
2135 static const char sFieldMarkName
[] = "__FieldMark_";
2137 /* This is used for exporting to strict OpenDocument 1.2, in which case traditional
2138 * bookmarks are used instead of fieldmarks. */
2139 FieldmarkType openFieldMark
= NONE
;
2141 while( rTextEnum
->hasMoreElements() )
2143 Reference
<XPropertySet
> xPropSet(rTextEnum
->nextElement(), UNO_QUERY
);
2144 Reference
< XTextRange
> xTxtRange(xPropSet
, uno::UNO_QUERY
);
2145 Reference
<XPropertySetInfo
> xPropInfo(xPropSet
->getPropertySetInfo());
2147 if (xPropInfo
->hasPropertyByName(gsTextPortionType
))
2150 xPropSet
->getPropertyValue(gsTextPortionType
) >>= sType
;
2152 if( sType
== gsText
)
2154 exportTextRange( xTxtRange
, bAutoStyles
,
2155 rPrevCharIsSpace
, openFieldMark
);
2157 else if( sType
== gsTextField
)
2159 exportTextField(xTxtRange
, bAutoStyles
, bIsProgress
, &rPrevCharIsSpace
);
2161 else if ( sType
== "Annotation" )
2163 exportTextField(xTxtRange
, bAutoStyles
, bIsProgress
, &rPrevCharIsSpace
);
2165 else if ( sType
== "AnnotationEnd" )
2169 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2170 const OUString
& rName
= xBookmark
->getName();
2171 if (!rName
.isEmpty())
2173 GetExport().AddAttribute(XML_NAMESPACE_OFFICE
, XML_NAME
, rName
);
2175 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_OFFICE
, XML_ANNOTATION_END
, false, false );
2178 else if( sType
== gsFrame
)
2180 Reference
< XEnumeration
> xContentEnum
;
2181 Reference
< XContentEnumerationAccess
> xCEA( xTxtRange
,
2184 xContentEnum
.set(xCEA
->createContentEnumeration(
2185 gsTextContentService
));
2186 // frames are never in sections
2187 Reference
<XTextSection
> xSection
;
2188 if( xContentEnum
.is() )
2189 exportTextContentEnumeration( xContentEnum
,
2191 xSection
, bIsProgress
, true,
2195 else if (sType
== gsFootnote
)
2197 exportTextFootnote(xPropSet
,
2198 xTxtRange
->getString(),
2199 bAutoStyles
, bIsProgress
);
2201 else if (sType
== gsBookmark
)
2203 exportTextMark(xPropSet
,
2205 lcl_XmlBookmarkElements
,
2208 else if (sType
== gsReferenceMark
)
2210 exportTextMark(xPropSet
,
2212 lcl_XmlReferenceElements
,
2215 else if (sType
== gsDocumentIndexMark
)
2217 pIndexMarkExport
->ExportIndexMark(xPropSet
, bAutoStyles
);
2219 else if (sType
== gsRedline
)
2221 if (nullptr != pRedlineExport
)
2222 pRedlineExport
->ExportChange(xPropSet
, bAutoStyles
);
2224 else if (sType
== gsRuby
)
2226 exportRuby(xPropSet
, bAutoStyles
);
2228 else if (sType
== "InContentMetadata")
2230 exportMeta(xPropSet
, bAutoStyles
, bIsProgress
, rPrevCharIsSpace
);
2232 else if (sType
== gsTextFieldStart
)
2234 Reference
< css::text::XFormField
> xFormField(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2236 /* As of now, textmarks are a proposed extension to the OpenDocument standard. */
2239 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2241 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2244 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
, xBookmark
->getName());
2247 if (xFormField
.is())
2249 GetExport().AddAttribute(XML_NAMESPACE_FIELD
, XML_TYPE
, xFormField
->getFieldType());
2252 GetExport().StartElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK_START
, false);
2253 if (xFormField
.is())
2255 FieldParamExporter(&GetExport(), xFormField
->getParameters()).Export();
2257 GetExport().EndElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK_START
, false);
2259 /* The OpenDocument standard does not include support for TextMarks for now, so use bookmarks instead. */
2262 if (xFormField
.is())
2265 Reference
< css::container::XNameAccess
> xParameters
= xFormField
->getParameters();
2266 if (xParameters
.is() && xParameters
->hasByName("Name"))
2268 const Any aValue
= xParameters
->getByName("Name");
2271 if (sName
.isEmpty())
2272 { // name attribute is mandatory, so have to pull a
2273 // rabbit out of the hat here
2274 sName
= sFieldMarkName
+ OUString::number(
2275 m_xImpl
->AddFieldMarkStart(xFormField
));
2277 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
,
2279 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2280 XML_NAMESPACE_TEXT
, XML_BOOKMARK_START
,
2282 const OUString sFieldType
= xFormField
->getFieldType();
2283 if (sFieldType
== ODF_FORMTEXT
)
2285 openFieldMark
= TEXT
;
2287 else if (sFieldType
== ODF_FORMCHECKBOX
)
2289 openFieldMark
= CHECK
;
2293 openFieldMark
= NONE
;
2299 else if (sType
== gsTextFieldEnd
)
2303 Reference
< css::text::XFormField
> xFormField(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2305 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2307 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2308 XML_NAMESPACE_FIELD
, XML_FIELDMARK_END
,
2313 if (xFormField
.is())
2316 Reference
< css::container::XNameAccess
> xParameters
= xFormField
->getParameters();
2317 if (xParameters
.is() && xParameters
->hasByName("Name"))
2319 const Any aValue
= xParameters
->getByName("Name");
2322 if (sName
.isEmpty())
2323 { // name attribute is mandatory, so have to pull a
2324 // rabbit out of the hat here
2325 sName
= sFieldMarkName
+ OUString::number(
2326 m_xImpl
->GetFieldMarkIndex(xFormField
));
2328 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
,
2330 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2331 XML_NAMESPACE_TEXT
, XML_BOOKMARK_END
,
2337 else if (sType
== gsTextFieldStartEnd
)
2341 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2343 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2346 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
, xBookmark
->getName());
2348 Reference
< css::text::XFormField
> xFormField(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2349 if (xFormField
.is())
2351 GetExport().AddAttribute(XML_NAMESPACE_FIELD
, XML_TYPE
, xFormField
->getFieldType());
2353 GetExport().StartElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK
, false);
2354 if (xFormField
.is())
2356 FieldParamExporter(&GetExport(), xFormField
->getParameters()).Export();
2358 GetExport().EndElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK
, false);
2362 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2365 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
, xBookmark
->getName());
2366 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2367 XML_NAMESPACE_TEXT
, XML_BOOKMARK
,
2373 else if (sType
== gsSoftPageBreak
)
2375 exportSoftPageBreak();
2378 OSL_FAIL("unknown text portion type");
2383 Reference
<XServiceInfo
> xServiceInfo( xTxtRange
, UNO_QUERY
);
2384 if( xServiceInfo
->supportsService( gsTextFieldService
) )
2386 exportTextField(xTxtRange
, bAutoStyles
, bIsProgress
, &rPrevCharIsSpace
);
2390 // no TextPortionType property -> non-Writer app -> text
2391 exportTextRange(xTxtRange
, bAutoStyles
, rPrevCharIsSpace
, openFieldMark
);
2396 // now that there are nested enumerations for meta(-field), this may be valid!
2397 // SAL_WARN_IF( bOpenRuby, "xmloff", "Red Alert: Ruby still open!" );
2400 void XMLTextParagraphExport::exportTable(
2401 const Reference
< XTextContent
> &,
2402 bool /*bAutoStyles*/, bool /*bIsProgress*/ )
2406 void XMLTextParagraphExport::exportTextField(
2407 const Reference
< XTextRange
> & rTextRange
,
2408 bool bAutoStyles
, bool bIsProgress
, bool *const pPrevCharIsSpace
)
2410 Reference
< XPropertySet
> xPropSet( rTextRange
, UNO_QUERY
);
2411 // non-Writer apps need not support Property TextField, so test first
2412 if (!xPropSet
->getPropertySetInfo()->hasPropertyByName( gsTextField
))
2415 Reference
< XTextField
> xTxtFld(xPropSet
->getPropertyValue( gsTextField
), uno::UNO_QUERY
);
2416 SAL_WARN_IF( !xTxtFld
.is(), "xmloff", "text field missing" );
2419 exportTextField(xTxtFld
, bAutoStyles
, bIsProgress
, true, pPrevCharIsSpace
);
2423 // write only characters
2424 GetExport().Characters(rTextRange
->getString());
2428 void XMLTextParagraphExport::exportTextField(
2429 const Reference
< XTextField
> & xTextField
,
2430 const bool bAutoStyles
, const bool bIsProgress
,
2431 const bool bRecursive
, bool *const pPrevCharIsSpace
)
2435 pFieldExport
->ExportFieldAutoStyle( xTextField
, bIsProgress
,
2440 assert(pPrevCharIsSpace
);
2441 pFieldExport
->ExportField(xTextField
, bIsProgress
, *pPrevCharIsSpace
);
2445 void XMLTextParagraphExport::exportSoftPageBreak()
2447 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
2448 XML_SOFT_PAGE_BREAK
, false,
2452 void XMLTextParagraphExport::exportTextMark(
2453 const Reference
<XPropertySet
> & rPropSet
,
2454 const OUString
& rProperty
,
2455 const ::xmloff::token::XMLTokenEnum pElements
[],
2458 // mib said: "Hau wech!"
2460 // (Originally, I'd export a span element in case the (book|reference)mark
2461 // was formatted. This actually makes a difference in case some pervert
2462 // sets a point reference mark in the document and, say, formats it bold.
2463 // This basically meaningless formatting will now been thrown away
2464 // (aka cleaned up), since mib said: ... dvo
2470 Reference
<XNamed
> xName(rPropSet
->getPropertyValue(rProperty
), UNO_QUERY
);
2471 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
,
2474 // start, end, or point-reference?
2476 if( *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsCollapsed
)) )
2482 nElement
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsStart
)) ? 1 : 2;
2485 // bookmark, bookmark-start: xml:id and RDFa for RDF metadata
2486 if( nElement
< 2 ) {
2487 GetExport().AddAttributeXmlId(xName
);
2488 const uno::Reference
<text::XTextContent
> xTextContent(
2489 xName
, uno::UNO_QUERY_THROW
);
2490 GetExport().AddAttributesRDFa(xTextContent
);
2493 // bookmark-start: add attributes hidden and condition
2496 Reference
<XPropertySet
> bkmkProps(rPropSet
->getPropertyValue(rProperty
), UNO_QUERY
);
2497 Reference
<XPropertySetInfo
> bkmkPropInfo
= bkmkProps
->getPropertySetInfo();
2498 OUString
sHidden("BookmarkHidden");
2499 if (bkmkPropInfo
->hasPropertyByName(sHidden
))
2501 bool bHidden
= false;
2502 bkmkProps
->getPropertyValue(sHidden
) >>= bHidden
;
2505 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, "hidden", "true");
2506 OUString
sCondition("BookmarkCondition");
2507 if (bkmkPropInfo
->hasPropertyByName(sCondition
))
2509 OUString sBookmarkCondition
;
2510 bkmkProps
->getPropertyValue(sCondition
) >>= sBookmarkCondition
;
2511 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, "condition", sBookmarkCondition
);
2518 assert(pElements
!= nullptr);
2519 assert(0 <= nElement
&& nElement
<= 2);
2520 SvXMLElementExport
aElem(GetExport(),
2521 XML_NAMESPACE_TEXT
, pElements
[nElement
],
2523 // else: no styles. (see above)
2526 static bool lcl_txtpara_isBoundAsChar(
2527 const Reference
< XPropertySet
> & rPropSet
,
2528 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
2530 bool bIsBoundAsChar
= false;
2531 OUString
sAnchorType( "AnchorType" );
2532 if( rPropSetInfo
->hasPropertyByName( sAnchorType
) )
2534 TextContentAnchorType eAnchor
;
2535 rPropSet
->getPropertyValue( sAnchorType
) >>= eAnchor
;
2536 bIsBoundAsChar
= TextContentAnchorType_AS_CHARACTER
== eAnchor
;
2539 return bIsBoundAsChar
;
2542 XMLShapeExportFlags
XMLTextParagraphExport::addTextFrameAttributes(
2543 const Reference
< XPropertySet
>& rPropSet
,
2545 basegfx::B2DPoint
* pCenter
,
2546 OUString
* pMinHeightValue
,
2547 OUString
* pMinWidthValue
)
2549 XMLShapeExportFlags nShapeFeatures
= SEF_DEFAULT
;
2551 // draw:name (#97662#: not for shapes, since those names will be
2552 // treated in the shape export)
2555 Reference
< XNamed
> xNamed( rPropSet
, UNO_QUERY
);
2558 OUString
sName( xNamed
->getName() );
2559 if( !sName
.isEmpty() )
2560 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
,
2561 xNamed
->getName() );
2565 OUStringBuffer sValue
;
2568 TextContentAnchorType eAnchor
= TextContentAnchorType_AT_PARAGRAPH
;
2569 rPropSet
->getPropertyValue( gsAnchorType
) >>= eAnchor
;
2571 XMLAnchorTypePropHdl aAnchorTypeHdl
;
2573 aAnchorTypeHdl
.exportXML( sTmp
, uno::makeAny(eAnchor
),
2574 GetExport().GetMM100UnitConverter() );
2575 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_ANCHOR_TYPE
, sTmp
);
2578 // text:anchor-page-number
2579 if( TextContentAnchorType_AT_PAGE
== eAnchor
)
2581 sal_Int16 nPage
= 0;
2582 rPropSet
->getPropertyValue( gsAnchorPageNo
) >>= nPage
;
2583 SAL_WARN_IF(nPage
<= 0, "xmloff",
2584 "ERROR: writing invalid anchor-page-number 0");
2585 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_ANCHOR_PAGE_NUMBER
,
2586 OUString::number( nPage
) );
2590 nShapeFeatures
|= XMLShapeExportFlags::NO_WS
;
2593 // OD 2004-06-01 #i27691# - correction: no export of svg:x, if object
2594 // is anchored as-character.
2596 eAnchor
!= TextContentAnchorType_AS_CHARACTER
)
2599 sal_Int16 nHoriOrient
= HoriOrientation::NONE
;
2600 rPropSet
->getPropertyValue( gsHoriOrient
) >>= nHoriOrient
;
2601 if( HoriOrientation::NONE
== nHoriOrient
)
2604 rPropSet
->getPropertyValue( gsHoriOrientPosition
) >>= nPos
;
2605 GetExport().GetMM100UnitConverter().convertMeasureToXML(
2607 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_X
,
2608 sValue
.makeStringAndClear() );
2609 if(nullptr != pCenter
)
2611 // add left edge to Center
2612 pCenter
->setX(pCenter
->getX() + nPos
);
2616 else if( TextContentAnchorType_AS_CHARACTER
== eAnchor
)
2617 nShapeFeatures
= (nShapeFeatures
& ~XMLShapeExportFlags::X
);
2619 if( !bShape
|| TextContentAnchorType_AS_CHARACTER
== eAnchor
)
2622 sal_Int16 nVertOrient
= VertOrientation::NONE
;
2623 rPropSet
->getPropertyValue( gsVertOrient
) >>= nVertOrient
;
2624 if( VertOrientation::NONE
== nVertOrient
)
2627 rPropSet
->getPropertyValue( gsVertOrientPosition
) >>= nPos
;
2628 GetExport().GetMM100UnitConverter().convertMeasureToXML(
2630 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_Y
,
2631 sValue
.makeStringAndClear() );
2632 if(nullptr != pCenter
)
2634 // add top edge to Center
2635 pCenter
->setY(pCenter
->getY() + nPos
);
2639 nShapeFeatures
= (nShapeFeatures
& ~XMLShapeExportFlags::Y
);
2642 Reference
< XPropertySetInfo
> xPropSetInfo(rPropSet
->getPropertySetInfo());
2645 sal_Int16 nWidthType
= SizeType::FIX
;
2646 if( xPropSetInfo
->hasPropertyByName( gsWidthType
) )
2648 rPropSet
->getPropertyValue( gsWidthType
) >>= nWidthType
;
2650 if( xPropSetInfo
->hasPropertyByName( gsWidth
) )
2652 sal_Int32 nWidth
= 0;
2653 // VAR size will be written as zero min-size
2654 if( SizeType::VARIABLE
!= nWidthType
)
2656 rPropSet
->getPropertyValue( gsWidth
) >>= nWidth
;
2658 GetExport().GetMM100UnitConverter().convertMeasureToXML(sValue
, nWidth
);
2659 if( SizeType::FIX
!= nWidthType
)
2661 assert(pMinWidthValue
);
2664 *pMinWidthValue
= sValue
.makeStringAndClear();
2669 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_WIDTH
,
2670 sValue
.makeStringAndClear() );
2671 if(nullptr != pCenter
)
2673 // add half width to Center
2674 pCenter
->setX(pCenter
->getX() + (0.5 * nWidth
));
2678 bool bSyncWidth
= false;
2679 if( xPropSetInfo
->hasPropertyByName( gsIsSyncWidthToHeight
) )
2681 bSyncWidth
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsIsSyncWidthToHeight
));
2683 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_WIDTH
,
2686 if( !bSyncWidth
&& xPropSetInfo
->hasPropertyByName( gsRelativeWidth
) )
2688 sal_Int16 nRelWidth
= 0;
2689 rPropSet
->getPropertyValue( gsRelativeWidth
) >>= nRelWidth
;
2690 SAL_WARN_IF( nRelWidth
< 0 || nRelWidth
> 254, "xmloff",
2691 "Got illegal relative width from API" );
2694 ::sax::Converter::convertPercent( sValue
, nRelWidth
);
2695 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_WIDTH
,
2696 sValue
.makeStringAndClear() );
2700 // svg:height, fo:min-height or style:rel-height
2701 sal_Int16 nSizeType
= SizeType::FIX
;
2702 if( xPropSetInfo
->hasPropertyByName( gsSizeType
) )
2704 rPropSet
->getPropertyValue( gsSizeType
) >>= nSizeType
;
2706 bool bSyncHeight
= false;
2707 if( xPropSetInfo
->hasPropertyByName( gsIsSyncHeightToWidth
) )
2709 bSyncHeight
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsIsSyncHeightToWidth
));
2711 sal_Int16 nRelHeight
= 0;
2712 if( !bSyncHeight
&& xPropSetInfo
->hasPropertyByName( gsRelativeHeight
) )
2714 rPropSet
->getPropertyValue( gsRelativeHeight
) >>= nRelHeight
;
2716 if( xPropSetInfo
->hasPropertyByName( gsHeight
) )
2718 sal_Int32 nHeight
= 0;
2719 if( SizeType::VARIABLE
!= nSizeType
)
2721 rPropSet
->getPropertyValue( gsHeight
) >>= nHeight
;
2723 GetExport().GetMM100UnitConverter().convertMeasureToXML( sValue
,
2725 if( SizeType::FIX
!= nSizeType
&& 0==nRelHeight
&& !bSyncHeight
&&
2728 *pMinHeightValue
= sValue
.makeStringAndClear();
2732 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_HEIGHT
,
2733 sValue
.makeStringAndClear() );
2734 if(nullptr != pCenter
)
2736 // add half height to Center
2737 pCenter
->setY(pCenter
->getY() + (0.5 * nHeight
));
2743 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_HEIGHT
,
2744 SizeType::MIN
== nSizeType
? XML_SCALE_MIN
: XML_SCALE
);
2747 else if( nRelHeight
> 0 )
2749 ::sax::Converter::convertPercent( sValue
, nRelHeight
);
2750 if( SizeType::MIN
== nSizeType
)
2752 assert(pMinHeightValue
);
2753 if (pMinHeightValue
)
2755 *pMinHeightValue
= sValue
.makeStringAndClear();
2759 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_HEIGHT
,
2760 sValue
.makeStringAndClear() );
2763 OUString
sZOrder( "ZOrder" );
2764 if( xPropSetInfo
->hasPropertyByName( sZOrder
) )
2766 sal_Int32 nZIndex
= 0;
2767 rPropSet
->getPropertyValue( sZOrder
) >>= nZIndex
;
2770 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_ZINDEX
,
2771 OUString::number( nZIndex
) );
2775 return nShapeFeatures
;
2778 void XMLTextParagraphExport::exportAnyTextFrame(
2779 const Reference
< XTextContent
> & rTxtCntnt
,
2783 bool bExportContent
,
2784 const Reference
< XPropertySet
> *pRangePropSet
)
2786 Reference
< XPropertySet
> xPropSet( rTxtCntnt
, UNO_QUERY
);
2790 if( FrameType::Embedded
== eType
)
2791 _collectTextEmbeddedAutoStyles( xPropSet
);
2792 // No text frame style for shapes (#i28745#)
2793 else if ( FrameType::Shape
!= eType
)
2794 Add( XmlStyleFamily::TEXT_FRAME
, xPropSet
);
2796 if( pRangePropSet
&& lcl_txtpara_isBoundAsChar( xPropSet
,
2797 xPropSet
->getPropertySetInfo() ) )
2798 Add( XmlStyleFamily::TEXT_TEXT
, *pRangePropSet
);
2802 case FrameType::Text
:
2804 // frame bound frames
2805 if ( bExportContent
)
2807 Reference
< XTextFrame
> xTxtFrame( rTxtCntnt
, UNO_QUERY
);
2808 Reference
< XText
> xTxt(xTxtFrame
->getText());
2809 exportFrameFrames( true, bIsProgress
, &xTxtFrame
);
2810 exportText( xTxt
, bAutoStyles
, bIsProgress
, true );
2814 case FrameType::Shape
:
2816 Reference
< XShape
> xShape( rTxtCntnt
, UNO_QUERY
);
2817 GetExport().GetShapeExport()->collectShapeAutoStyles( xShape
);
2826 Reference
< XPropertySetInfo
> xPropSetInfo(xPropSet
->getPropertySetInfo());
2827 Reference
< XPropertyState
> xPropState( xPropSet
, UNO_QUERY
);
2829 bool bAddCharStyles
= pRangePropSet
&&
2830 lcl_txtpara_isBoundAsChar( xPropSet
, xPropSetInfo
);
2832 bool bIsUICharStyle
;
2833 bool bHasAutoStyle
= false;
2837 if( bAddCharStyles
)
2840 sStyle
= FindTextStyleAndHyperlink( *pRangePropSet
, bDummy
, bIsUICharStyle
, bHasAutoStyle
);
2843 bIsUICharStyle
= false;
2845 bool bDoSomething
= bIsUICharStyle
2846 && aCharStyleNamesPropInfoCache
.hasProperty( *pRangePropSet
);
2847 XMLTextCharStyleNamesElementExport
aCharStylesExport(
2848 GetExport(), bDoSomething
, bHasAutoStyle
,
2849 bDoSomething
? *pRangePropSet
: Reference
<XPropertySet
>(),
2852 if( !sStyle
.isEmpty() )
2853 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
2854 GetExport().EncodeStyleName( sStyle
) );
2856 SvXMLElementExport
aElem( GetExport(), !sStyle
.isEmpty(),
2857 XML_NAMESPACE_TEXT
, XML_SPAN
, false, false );
2859 SvXMLElementExport
aElement( GetExport(),
2860 FrameType::Shape
!= eType
&&
2861 addHyperlinkAttributes( xPropSet
,
2862 xPropState
,xPropSetInfo
),
2863 XML_NAMESPACE_DRAW
, XML_A
, false, false );
2866 case FrameType::Text
:
2867 _exportTextFrame( xPropSet
, xPropSetInfo
, bIsProgress
);
2869 case FrameType::Graphic
:
2870 _exportTextGraphic( xPropSet
, xPropSetInfo
);
2872 case FrameType::Embedded
:
2873 _exportTextEmbedded( xPropSet
, xPropSetInfo
);
2875 case FrameType::Shape
:
2877 Reference
< XShape
> xShape( rTxtCntnt
, UNO_QUERY
);
2878 XMLShapeExportFlags nFeatures
=
2879 addTextFrameAttributes( xPropSet
, true );
2880 GetExport().GetShapeExport()
2881 ->exportShape( xShape
, nFeatures
);
2891 void XMLTextParagraphExport::_exportTextFrame(
2892 const Reference
< XPropertySet
> & rPropSet
,
2893 const Reference
< XPropertySetInfo
> & rPropSetInfo
,
2896 Reference
< XTextFrame
> xTxtFrame( rPropSet
, UNO_QUERY
);
2897 Reference
< XText
> xTxt(xTxtFrame
->getText());
2900 if( rPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
2902 rPropSet
->getPropertyValue( gsFrameStyleName
) >>= sStyle
;
2905 OUString aMinHeightValue
;
2906 OUString sMinWidthValue
;
2907 OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_FRAME
, rPropSet
, sStyle
);
2908 if ( sAutoStyle
.isEmpty() )
2909 sAutoStyle
= sStyle
;
2910 if( !sAutoStyle
.isEmpty() )
2911 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_STYLE_NAME
,
2912 GetExport().EncodeStyleName( sAutoStyle
) );
2913 addTextFrameAttributes(rPropSet
, false, nullptr, &aMinHeightValue
, &sMinWidthValue
);
2915 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
,
2916 XML_FRAME
, false, true );
2918 if( !aMinHeightValue
.isEmpty() )
2919 GetExport().AddAttribute( XML_NAMESPACE_FO
, XML_MIN_HEIGHT
,
2922 if (!sMinWidthValue
.isEmpty())
2924 GetExport().AddAttribute( XML_NAMESPACE_FO
, XML_MIN_WIDTH
,
2928 // draw:chain-next-name
2929 if( rPropSetInfo
->hasPropertyByName( gsChainNextName
) )
2932 if( (rPropSet
->getPropertyValue( gsChainNextName
) >>= sNext
) && !sNext
.isEmpty() )
2933 GetExport().AddAttribute( XML_NAMESPACE_DRAW
,
2934 XML_CHAIN_NEXT_NAME
,
2939 SvXMLElementExport
aElement( GetExport(), XML_NAMESPACE_DRAW
,
2940 XML_TEXT_BOX
, true, true );
2942 // frames bound to frame
2943 exportFrameFrames( false, bIsProgress
, &xTxtFrame
);
2945 exportText( xTxt
, false, bIsProgress
, true );
2949 Reference
<XEventsSupplier
> xEventsSupp( xTxtFrame
, UNO_QUERY
);
2950 GetExport().GetEventExport().Export(xEventsSupp
);
2953 GetExport().GetImageMapExport().Export( rPropSet
);
2955 // svg:title and svg:desc (#i73249#)
2956 exportTitleAndDescription( rPropSet
, rPropSetInfo
);
2959 void XMLTextParagraphExport::exportContour(
2960 const Reference
< XPropertySet
> & rPropSet
,
2961 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
2963 if( !rPropSetInfo
->hasPropertyByName( gsContourPolyPolygon
) )
2968 PointSequenceSequence aSourcePolyPolygon
;
2969 rPropSet
->getPropertyValue( gsContourPolyPolygon
) >>= aSourcePolyPolygon
;
2970 const basegfx::B2DPolyPolygon
aPolyPolygon(
2971 basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(
2972 aSourcePolyPolygon
));
2973 const sal_uInt32
nPolygonCount(aPolyPolygon
.count());
2980 const basegfx::B2DRange
aPolyPolygonRange(aPolyPolygon
.getB2DRange());
2983 if( rPropSetInfo
->hasPropertyByName( gsIsPixelContour
) )
2985 bPixel
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsIsPixelContour
));
2989 OUStringBuffer
aStringBuffer( 10 );
2993 ::sax::Converter::convertMeasurePx(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getWidth()));
2997 GetExport().GetMM100UnitConverter().convertMeasureToXML(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getWidth()));
3000 GetExport().AddAttribute(XML_NAMESPACE_SVG
, XML_WIDTH
, aStringBuffer
.makeStringAndClear());
3005 ::sax::Converter::convertMeasurePx(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getHeight()));
3009 GetExport().GetMM100UnitConverter().convertMeasureToXML(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getHeight()));
3012 GetExport().AddAttribute(XML_NAMESPACE_SVG
, XML_HEIGHT
, aStringBuffer
.makeStringAndClear());
3015 SdXMLImExViewBox
aViewBox(0.0, 0.0, aPolyPolygonRange
.getWidth(), aPolyPolygonRange
.getHeight());
3016 GetExport().AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
3017 enum XMLTokenEnum eElem
= XML_TOKEN_INVALID
;
3019 if(1 == nPolygonCount
)
3021 // simple polygon shape, can be written as svg:points sequence
3022 const OUString
aPointString(
3023 basegfx::utils::exportToSvgPoints(
3024 aPolyPolygon
.getB2DPolygon(0)));
3026 // write point array
3027 GetExport().AddAttribute(XML_NAMESPACE_DRAW
, XML_POINTS
, aPointString
);
3028 eElem
= XML_CONTOUR_POLYGON
;
3032 // polypolygon, needs to be written as a svg:path sequence
3033 const OUString
aPolygonString(
3034 basegfx::utils::exportToSvgD(
3036 true, // bUseRelativeCoordinates
3037 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
3038 true)); // bHandleRelativeNextPointCompatible
3040 // write point array
3041 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
3042 eElem
= XML_CONTOUR_PATH
;
3045 if( rPropSetInfo
->hasPropertyByName( gsIsAutomaticContour
) )
3047 bool bTmp
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(
3048 gsIsAutomaticContour
));
3049 GetExport().AddAttribute( XML_NAMESPACE_DRAW
,
3050 XML_RECREATE_ON_EDIT
, bTmp
? XML_TRUE
: XML_FALSE
);
3054 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
, eElem
,
3058 void XMLTextParagraphExport::_exportTextGraphic(
3059 const Reference
< XPropertySet
> & rPropSet
,
3060 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
3063 if( rPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
3065 rPropSet
->getPropertyValue( gsFrameStyleName
) >>= sStyle
;
3068 OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_FRAME
, rPropSet
, sStyle
);
3069 if ( sAutoStyle
.isEmpty() )
3070 sAutoStyle
= sStyle
;
3071 if( !sAutoStyle
.isEmpty() )
3072 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_STYLE_NAME
,
3073 GetExport().EncodeStyleName( sAutoStyle
) );
3075 // check if we need to use svg:transform
3076 sal_Int16
nRotation(0);
3077 rPropSet
->getPropertyValue( gsGraphicRotation
) >>= nRotation
;
3078 const bool bUseRotation(0 != nRotation
);
3079 basegfx::B2DPoint
aCenter(0.0, 0.0);
3081 // add TextFrame attributes like svg:x/y/width/height, also get back
3082 // object's center point if rotation is used and has to be exported
3083 addTextFrameAttributes(rPropSet
, false, bUseRotation
? &aCenter
: nullptr);
3088 // RotateFlyFrameFix: im/export full 'draw:transform' using existing tooling.
3089 // Currently only rotation is used, but combinations with 'draw:transform'
3090 // may be necessary in the future, so that svg:x/svg:y/svg:width/svg:height
3091 // may be extended/replaced with 'draw:transform' (see draw objects)
3092 SdXMLImExTransform2D aSdXMLImExTransform2D
;
3094 // Convert from 10th degree integer to deg.
3095 // CAUTION: internal rotation is classically mathematically 'wrong' defined by ignoring that
3096 // we have a right-handed coordinate system, so need to correct this by mirroring
3097 // the rotation to get the correct transformation. See also case XML_TOK_TEXT_FRAME_TRANSFORM
3098 // in XMLTextFrameContext_Impl::XMLTextFrameContext_Impl and #i78696#
3099 // CAUTION-II: due to tdf#115782 it is better for current ODF to indeed write it with the wrong
3100 // orientation as in all other cases - ARGH! We will need to correct this in future ODF ASAP!
3101 const double fRotate(static_cast< double >(nRotation
) * (F_PI
/1800.0));
3103 // transform to rotation center which is the object's center
3104 aSdXMLImExTransform2D
.AddTranslate(-aCenter
);
3106 // add rotation itself
3107 // tdf#115529 but correct value modulo 2PI to have it positive and in the range of [0.0 .. 2PI[
3108 aSdXMLImExTransform2D
.AddRotate(basegfx::normalizeToRange(fRotate
, F_2PI
));
3110 // back-transform after rotation
3111 aSdXMLImExTransform2D
.AddTranslate(aCenter
);
3113 // Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed,
3114 // but is not generally available (as it should be, a 'current' UnitConverter should
3115 // be available at GetExport() - and maybe was once). May have to be addressed as soon
3116 // as translate transformations are used here.
3117 GetExport().AddAttribute(
3120 aSdXMLImExTransform2D
.GetExportString(GetExport().GetMM100UnitConverter()));
3124 SvXMLElementExport
aElem(GetExport(), XML_NAMESPACE_DRAW
, XML_FRAME
, false, true);
3128 uno::Reference
<graphic::XGraphic
> xGraphic
;
3129 rPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3131 OUString sInternalURL
;
3132 OUString sOutMimeType
;
3136 sInternalURL
= GetExport().AddEmbeddedXGraphic(xGraphic
, sOutMimeType
);
3139 // If there still is no url, then graphic is empty
3140 if (!sInternalURL
.isEmpty())
3142 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sInternalURL
);
3143 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3144 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3145 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3149 OUString sGrfFilter
;
3150 rPropSet
->getPropertyValue( gsGraphicFilter
) >>= sGrfFilter
;
3151 if( !sGrfFilter
.isEmpty() )
3152 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_FILTER_NAME
,
3155 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
3157 if (sOutMimeType
.isEmpty())
3159 GetExport().GetGraphicMimeTypeFromStream(xGraphic
, sOutMimeType
);
3161 if (!sOutMimeType
.isEmpty())
3162 { // ODF 1.3 OFFICE-3943
3163 GetExport().AddAttribute(
3164 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
3165 ? XML_NAMESPACE_DRAW
3166 : XML_NAMESPACE_LO_EXT
,
3167 "mime-type", sOutMimeType
);
3172 // optional office:binary-data
3175 SvXMLElementExport
aElement(GetExport(), XML_NAMESPACE_DRAW
, XML_IMAGE
, false, true );
3176 GetExport().AddEmbeddedXGraphicAsBase64(xGraphic
);
3180 const bool bAddReplacementImages
= officecfg::Office::Common::Save::Graphic::AddReplacementImages::get();
3181 if (bAddReplacementImages
)
3183 // replacement graphic for backwards compatibility, but
3184 // only for SVG and metafiles currently
3185 uno::Reference
<graphic::XGraphic
> xReplacementGraphic
;
3186 rPropSet
->getPropertyValue("ReplacementGraphic") >>= xReplacementGraphic
;
3188 OUString sInternalURL
;
3189 OUString sOutMimeType
;
3191 //Resolves: fdo#62461 put preferred image first above, followed by
3193 if (xReplacementGraphic
.is())
3195 sInternalURL
= GetExport().AddEmbeddedXGraphic(xReplacementGraphic
, sOutMimeType
);
3198 // If there is no url, then graphic is empty
3199 if (!sInternalURL
.isEmpty())
3201 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sInternalURL
);
3202 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3203 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3204 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3207 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
3209 if (sOutMimeType
.isEmpty())
3211 GetExport().GetGraphicMimeTypeFromStream(xReplacementGraphic
, sOutMimeType
);
3213 if (!sOutMimeType
.isEmpty())
3214 { // ODF 1.3 OFFICE-3943
3215 GetExport().AddAttribute(
3216 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
3217 ? XML_NAMESPACE_DRAW
3218 : XML_NAMESPACE_LO_EXT
,
3219 "mime-type", sOutMimeType
);
3224 // optional office:binary-data
3225 if (xReplacementGraphic
.is())
3227 SvXMLElementExport
aElement(GetExport(), XML_NAMESPACE_DRAW
, XML_IMAGE
, true, true);
3228 GetExport().AddEmbeddedXGraphicAsBase64(xReplacementGraphic
);
3233 Reference
<XEventsSupplier
> xEventsSupp( rPropSet
, UNO_QUERY
);
3234 GetExport().GetEventExport().Export(xEventsSupp
);
3237 GetExport().GetImageMapExport().Export( rPropSet
);
3239 // svg:title and svg:desc (#i73249#)
3240 exportTitleAndDescription( rPropSet
, rPropSetInfo
);
3243 exportContour( rPropSet
, rPropSetInfo
);
3246 void XMLTextParagraphExport::_collectTextEmbeddedAutoStyles(const Reference
< XPropertySet
> & )
3248 SAL_WARN( "xmloff", "no API implementation available" );
3251 void XMLTextParagraphExport::_exportTextEmbedded(
3252 const Reference
< XPropertySet
> &,
3253 const Reference
< XPropertySetInfo
> & )
3255 SAL_WARN( "xmloff", "no API implementation available" );
3258 void XMLTextParagraphExport::exportEvents( const Reference
< XPropertySet
> & rPropSet
)
3261 Reference
<XEventsSupplier
> xEventsSupp( rPropSet
, UNO_QUERY
);
3262 GetExport().GetEventExport().Export(xEventsSupp
);
3265 if (rPropSet
->getPropertySetInfo()->hasPropertyByName("ImageMap"))
3266 GetExport().GetImageMapExport().Export( rPropSet
);
3269 // Implement Title/Description Elements UI (#i73249#)
3270 void XMLTextParagraphExport::exportTitleAndDescription(
3271 const Reference
< XPropertySet
> & rPropSet
,
3272 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
3275 if( rPropSetInfo
->hasPropertyByName( gsTitle
) )
3278 rPropSet
->getPropertyValue( gsTitle
) >>= sObjTitle
;
3279 if( !sObjTitle
.isEmpty() )
3281 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_SVG
,
3282 XML_TITLE
, true, false );
3283 GetExport().Characters( sObjTitle
);
3288 if( rPropSetInfo
->hasPropertyByName( gsDescription
) )
3291 rPropSet
->getPropertyValue( gsDescription
) >>= sObjDesc
;
3292 if( !sObjDesc
.isEmpty() )
3294 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_SVG
,
3295 XML_DESC
, true, false );
3296 GetExport().Characters( sObjDesc
);
3301 bool XMLTextParagraphExport::addHyperlinkAttributes(
3302 const Reference
< XPropertySet
> & rPropSet
,
3303 const Reference
< XPropertyState
> & rPropState
,
3304 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
3306 bool bExport
= false;
3307 OUString sHRef
, sName
, sTargetFrame
, sUStyleName
, sVStyleName
;
3308 bool bServerMap
= false;
3310 if( rPropSetInfo
->hasPropertyByName( gsHyperLinkURL
) &&
3311 ( !rPropState
.is() || PropertyState_DIRECT_VALUE
==
3312 rPropState
->getPropertyState( gsHyperLinkURL
) ) )
3314 rPropSet
->getPropertyValue( gsHyperLinkURL
) >>= sHRef
;
3316 if( !sHRef
.isEmpty() )
3320 if ( sHRef
.isEmpty() )
3322 // hyperlink without a URL does not make sense
3323 OSL_ENSURE( false, "hyperlink without a URL --> no export to ODF" );
3327 if ( rPropSetInfo
->hasPropertyByName( gsHyperLinkName
)
3328 && ( !rPropState
.is()
3329 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsHyperLinkName
) ) )
3331 rPropSet
->getPropertyValue( gsHyperLinkName
) >>= sName
;
3332 if( !sName
.isEmpty() )
3336 if ( rPropSetInfo
->hasPropertyByName( gsHyperLinkTarget
)
3337 && ( !rPropState
.is()
3338 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsHyperLinkTarget
) ) )
3340 rPropSet
->getPropertyValue( gsHyperLinkTarget
) >>= sTargetFrame
;
3341 if( !sTargetFrame
.isEmpty() )
3345 if ( rPropSetInfo
->hasPropertyByName( gsServerMap
)
3346 && ( !rPropState
.is()
3347 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsServerMap
) ) )
3349 bServerMap
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsServerMap
));
3354 if ( rPropSetInfo
->hasPropertyByName( gsUnvisitedCharStyleName
)
3355 && ( !rPropState
.is()
3356 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsUnvisitedCharStyleName
) ) )
3358 rPropSet
->getPropertyValue( gsUnvisitedCharStyleName
) >>= sUStyleName
;
3359 if( !sUStyleName
.isEmpty() )
3363 if ( rPropSetInfo
->hasPropertyByName( gsVisitedCharStyleName
)
3364 && ( !rPropState
.is()
3365 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsVisitedCharStyleName
) ) )
3367 rPropSet
->getPropertyValue( gsVisitedCharStyleName
) >>= sVStyleName
;
3368 if( !sVStyleName
.isEmpty() )
3374 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3375 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference( sHRef
) );
3377 if( !sName
.isEmpty() )
3378 GetExport().AddAttribute( XML_NAMESPACE_OFFICE
, XML_NAME
, sName
);
3380 if( !sTargetFrame
.isEmpty() )
3382 GetExport().AddAttribute( XML_NAMESPACE_OFFICE
,
3383 XML_TARGET_FRAME_NAME
, sTargetFrame
);
3384 enum XMLTokenEnum eTok
= sTargetFrame
== "_blank" ? XML_NEW
: XML_REPLACE
;
3385 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, eTok
);
3389 GetExport().AddAttribute( XML_NAMESPACE_OFFICE
,
3390 XML_SERVER_MAP
, XML_TRUE
);
3392 if( !sUStyleName
.isEmpty() )
3393 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
3394 XML_STYLE_NAME
, GetExport().EncodeStyleName( sUStyleName
) );
3396 if( !sVStyleName
.isEmpty() )
3397 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
3398 XML_VISITED_STYLE_NAME
, GetExport().EncodeStyleName( sVStyleName
) );
3404 void XMLTextParagraphExport::exportTextRangeSpan(
3405 const css::uno::Reference
< css::text::XTextRange
> & rTextRange
,
3406 Reference
< XPropertySet
> const & xPropSet
,
3407 Reference
< XPropertySetInfo
> & xPropSetInfo
,
3408 const bool bIsUICharStyle
,
3409 const bool bHasAutoStyle
,
3410 const OUString
& sStyle
,
3411 bool& rPrevCharIsSpace
,
3412 FieldmarkType
& openFieldMark
)
3414 XMLTextCharStyleNamesElementExport
aCharStylesExport(
3416 bIsUICharStyle
&& aCharStyleNamesPropInfoCache
.hasProperty( xPropSet
, xPropSetInfo
),
3421 if ( !sStyle
.isEmpty() )
3423 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
, GetExport().EncodeStyleName( sStyle
) );
3426 SvXMLElementExport
aElement( GetExport(), !sStyle
.isEmpty(), XML_NAMESPACE_TEXT
, XML_SPAN
, false, false );
3427 const OUString
aText( rTextRange
->getString() );
3428 SvXMLElementExport
aElem2( GetExport(), TEXT
== openFieldMark
,
3429 XML_NAMESPACE_TEXT
, XML_TEXT_INPUT
,
3431 exportCharacterData(aText
, rPrevCharIsSpace
);
3432 openFieldMark
= NONE
;
3436 void XMLTextParagraphExport::exportTextRange(
3437 const Reference
< XTextRange
> & rTextRange
,
3439 bool& rPrevCharIsSpace
,
3440 FieldmarkType
& openFieldMark
)
3442 Reference
< XPropertySet
> xPropSet( rTextRange
, UNO_QUERY
);
3445 Add( XmlStyleFamily::TEXT_TEXT
, xPropSet
);
3449 bool bHyperlink
= false;
3450 bool bIsUICharStyle
= false;
3451 bool bHasAutoStyle
= false;
3452 const OUString
sStyle(
3453 FindTextStyleAndHyperlink( xPropSet
, bHyperlink
, bIsUICharStyle
, bHasAutoStyle
) );
3455 Reference
< XPropertySetInfo
> xPropSetInfo
;
3456 bool bHyperlinkAttrsAdded
= false;
3459 Reference
< XPropertyState
> xPropState( xPropSet
, UNO_QUERY
);
3460 xPropSetInfo
.set( xPropSet
->getPropertySetInfo() );
3461 bHyperlinkAttrsAdded
= addHyperlinkAttributes( xPropSet
, xPropState
, xPropSetInfo
);
3464 if ( bHyperlink
&& bHyperlinkAttrsAdded
)
3466 SvXMLElementExport
aElem( GetExport(), true, XML_NAMESPACE_TEXT
, XML_A
, false, false );
3468 // export events (if supported)
3469 OUString
sHyperLinkEvents(
3471 if (xPropSetInfo
->hasPropertyByName(sHyperLinkEvents
))
3473 Reference
< XNameReplace
> xName( xPropSet
->getPropertyValue( sHyperLinkEvents
), uno::UNO_QUERY
);
3474 GetExport().GetEventExport().Export( xName
, false );
3477 exportTextRangeSpan( rTextRange
, xPropSet
, xPropSetInfo
, bIsUICharStyle
, bHasAutoStyle
, sStyle
, rPrevCharIsSpace
, openFieldMark
);
3481 exportTextRangeSpan( rTextRange
, xPropSet
, xPropSetInfo
, bIsUICharStyle
, bHasAutoStyle
, sStyle
, rPrevCharIsSpace
, openFieldMark
);
3486 void XMLTextParagraphExport::exportCharacterData(const OUString
& rText
,
3487 bool& rPrevCharIsSpace
)
3489 sal_Int32 nExpStartPos
= 0;
3490 sal_Int32 nEndPos
= rText
.getLength();
3491 sal_Int32 nSpaceChars
= 0;
3492 for( sal_Int32 nPos
= 0; nPos
< nEndPos
; nPos
++ )
3494 sal_Unicode cChar
= rText
[nPos
];
3495 bool bExpCharAsText
= true;
3496 bool bExpCharAsElement
= false;
3497 bool bCurrCharIsSpace
= false;
3502 // These characters are exported as text.
3503 bExpCharAsElement
= true;
3504 bExpCharAsText
= false;
3507 break; // legal character
3508 case 0x0020: // Blank
3509 if( rPrevCharIsSpace
)
3511 // If the previous character is a space character,
3512 // too, export a special space element.
3513 bExpCharAsText
= false;
3515 bCurrCharIsSpace
= true;
3518 if( cChar
< 0x0020 )
3521 OSL_ENSURE( txtparae_bContainsIllegalCharacters
||
3523 "illegal character in text content" );
3524 txtparae_bContainsIllegalCharacters
= true;
3526 bExpCharAsText
= false;
3531 // If the current character is not exported as text
3532 // the text that has not been exported by now has to be exported now.
3533 if( nPos
> nExpStartPos
&& !bExpCharAsText
)
3535 SAL_WARN_IF( 0 != nSpaceChars
, "xmloff", "pending spaces" );
3536 OUString
sExp( rText
.copy( nExpStartPos
, nPos
- nExpStartPos
) );
3537 GetExport().Characters( sExp
);
3538 nExpStartPos
= nPos
;
3541 // If there are spaces left that have not been exported and the
3542 // current character is not a space , the pending spaces have to be
3544 if( nSpaceChars
> 0 && !bCurrCharIsSpace
)
3546 SAL_WARN_IF( nExpStartPos
!= nPos
, "xmloff", " pending characters" );
3548 if( nSpaceChars
> 1 )
3550 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_C
,
3551 OUString::number(nSpaceChars
) );
3554 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
3555 XML_S
, false, false );
3560 // If the current character has to be exported as a special
3561 // element, the element will be exported now.
3562 if( bExpCharAsElement
)
3568 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
3575 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
3576 XML_LINE_BREAK
, false,
3583 // If the current character is a space, and the previous one
3584 // is a space, too, the number of pending spaces is incremented
3586 if( bCurrCharIsSpace
&& rPrevCharIsSpace
)
3588 rPrevCharIsSpace
= bCurrCharIsSpace
;
3590 // If the current character is not exported as text, the start
3591 // position for text is the position behind the current position.
3592 if( !bExpCharAsText
)
3594 SAL_WARN_IF( nExpStartPos
!= nPos
, "xmloff", "wrong export start pos" );
3595 nExpStartPos
= nPos
+1;
3599 if( nExpStartPos
< nEndPos
)
3601 SAL_WARN_IF( 0 != nSpaceChars
, "xmloff", " pending spaces " );
3602 OUString
sExp( rText
.copy( nExpStartPos
, nEndPos
- nExpStartPos
) );
3603 GetExport().Characters( sExp
);
3606 // If there are some spaces left, they have to be exported now.
3607 if( nSpaceChars
> 0 )
3609 if( nSpaceChars
> 1 )
3611 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_C
,
3612 OUString::number(nSpaceChars
) );
3615 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
, XML_S
,
3620 void XMLTextParagraphExport::exportTextDeclarations()
3622 pFieldExport
->ExportFieldDeclarations();
3624 // get XPropertySet from the document and ask for AutoMarkFileURL.
3625 // If it exists, export the auto-mark-file element.
3626 Reference
<XPropertySet
> xPropertySet( GetExport().GetModel(), UNO_QUERY
);
3627 if (!xPropertySet
.is())
3631 OUString
sIndexAutoMarkFileURL(
3632 "IndexAutoMarkFileURL");
3633 if (!xPropertySet
->getPropertySetInfo()->hasPropertyByName(
3634 sIndexAutoMarkFileURL
))
3637 xPropertySet
->getPropertyValue(sIndexAutoMarkFileURL
) >>= sUrl
;
3638 if (!sUrl
.isEmpty())
3640 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
,
3641 GetExport().GetRelativeReference(sUrl
) );
3642 SvXMLElementExport
aAutoMarkElement(
3643 GetExport(), XML_NAMESPACE_TEXT
,
3644 XML_ALPHABETICAL_INDEX_AUTO_MARK_FILE
,
3649 void XMLTextParagraphExport::exportTextDeclarations(
3650 const Reference
<XText
> & rText
)
3652 pFieldExport
->ExportFieldDeclarations(rText
);
3655 void XMLTextParagraphExport::exportUsedDeclarations()
3657 pFieldExport
->SetExportOnlyUsedFieldDeclarations( false/*bOnlyUsed*/ );
3660 void XMLTextParagraphExport::exportTrackedChanges(bool bAutoStyles
)
3662 if (nullptr != pRedlineExport
)
3663 pRedlineExport
->ExportChangesList( bAutoStyles
);
3666 void XMLTextParagraphExport::exportTrackedChanges(
3667 const Reference
<XText
> & rText
,
3670 if (nullptr != pRedlineExport
)
3671 pRedlineExport
->ExportChangesList(rText
, bAutoStyle
);
3674 void XMLTextParagraphExport::recordTrackedChangesForXText(
3675 const Reference
<XText
> & rText
)
3677 if (nullptr != pRedlineExport
)
3678 pRedlineExport
->SetCurrentXText(rText
);
3681 void XMLTextParagraphExport::recordTrackedChangesNoXText()
3683 if (nullptr != pRedlineExport
)
3684 pRedlineExport
->SetCurrentXText();
3687 void XMLTextParagraphExport::exportTableAutoStyles() {}
3689 void XMLTextParagraphExport::exportTextAutoStyles()
3691 // tdf#135942: do not collect styles during their export: this may modify iterated containers
3693 exportTableAutoStyles();
3695 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_PARAGRAPH
);
3697 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_TEXT
);
3699 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_FRAME
);
3701 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_SECTION
);
3703 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_RUBY
);
3705 maListAutoPool
.exportXML();
3708 void XMLTextParagraphExport::exportRuby(
3709 const Reference
<XPropertySet
> & rPropSet
,
3712 // early out: a collapsed ruby makes no sense
3713 if (*o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsCollapsed
)))
3717 bool bStart
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsStart
));
3723 Add( XmlStyleFamily::TEXT_RUBY
, rPropSet
);
3731 // we can only start a ruby if none is open
3732 assert(!bOpenRuby
&& "Can't open a ruby inside of ruby!");
3736 // save ruby text + ruby char style
3737 rPropSet
->getPropertyValue(gsRubyText
) >>= sOpenRubyText
;
3738 rPropSet
->getPropertyValue(gsRubyCharStyleName
) >>= sOpenRubyCharStyle
;
3741 GetExport().CheckAttrList();
3742 OUString
sStyleName(Find(XmlStyleFamily::TEXT_RUBY
, rPropSet
, ""));
3743 SAL_WARN_IF(sStyleName
.isEmpty(), "xmloff", "Can't find ruby style!");
3744 GetExport().AddAttribute(XML_NAMESPACE_TEXT
,
3745 XML_STYLE_NAME
, sStyleName
);
3747 // export <text:ruby> and <text:ruby-base> start elements
3748 GetExport().StartElement( XML_NAMESPACE_TEXT
, XML_RUBY
, false);
3749 GetExport().ClearAttrList();
3750 GetExport().StartElement( XML_NAMESPACE_TEXT
, XML_RUBY_BASE
,
3758 // check for an open ruby
3759 assert(bOpenRuby
&& "Can't close a ruby if none is open!");
3763 // close <text:ruby-base>
3764 GetExport().EndElement(XML_NAMESPACE_TEXT
, XML_RUBY_BASE
,
3767 // write the ruby text (with char style)
3769 if (!sOpenRubyCharStyle
.isEmpty())
3770 GetExport().AddAttribute(
3771 XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
3772 GetExport().EncodeStyleName( sOpenRubyCharStyle
) );
3774 SvXMLElementExport
aRubyElement(
3775 GetExport(), XML_NAMESPACE_TEXT
, XML_RUBY_TEXT
,
3778 GetExport().Characters(sOpenRubyText
);
3781 // and finally, close the ruby
3782 GetExport().EndElement(XML_NAMESPACE_TEXT
, XML_RUBY
, false);
3788 void XMLTextParagraphExport::exportMeta(
3789 const Reference
<XPropertySet
> & i_xPortion
,
3790 bool i_bAutoStyles
, bool i_isProgress
, bool & rPrevCharIsSpace
)
3792 bool doExport(!i_bAutoStyles
); // do not export element if autostyles
3793 // check version >= 1.2
3794 switch (GetExport().getSaneDefaultVersion()) {
3795 case SvtSaveOptions::ODFSVER_011
: // fall through
3796 case SvtSaveOptions::ODFSVER_010
: doExport
= false; break;
3800 const Reference
< XTextContent
> xTextContent(
3801 i_xPortion
->getPropertyValue("InContentMetadata"), UNO_QUERY_THROW
);
3802 const Reference
< XEnumerationAccess
> xEA( xTextContent
, UNO_QUERY_THROW
);
3803 const Reference
< XEnumeration
> xTextEnum( xEA
->createEnumeration() );
3807 const Reference
<rdf::XMetadatable
> xMeta(xTextContent
, UNO_QUERY_THROW
);
3809 // text:meta with neither xml:id nor RDFa is invalid
3810 xMeta
->ensureMetadataReference();
3812 // xml:id and RDFa for RDF metadata
3813 GetExport().AddAttributeXmlId(xMeta
);
3814 GetExport().AddAttributesRDFa(xTextContent
);
3817 SvXMLElementExport
aElem( GetExport(), doExport
,
3818 XML_NAMESPACE_TEXT
, XML_META
, false, false );
3820 // recurse to export content
3821 exportTextRangeEnumeration(xTextEnum
, i_bAutoStyles
, i_isProgress
, rPrevCharIsSpace
);
3824 void XMLTextParagraphExport::PreventExportOfControlsInMuteSections(
3825 const Reference
<XIndexAccess
> & rShapes
,
3826 const rtl::Reference
<xmloff::OFormLayerXMLExport
>& xFormExport
)
3828 // check parameters ad pre-conditions
3829 if( ( ! rShapes
.is() ) || ( ! xFormExport
.is() ) )
3831 // if we don't have shapes or a form export, there's nothing to do
3834 SAL_WARN_IF( pSectionExport
== nullptr, "xmloff", "We need the section export." );
3836 Reference
<XEnumeration
> xShapesEnum
= pBoundFrameSets
->GetShapes()->createEnumeration();
3837 if(!xShapesEnum
.is())
3839 while( xShapesEnum
->hasMoreElements() )
3841 // now we need to check
3842 // 1) if this is a control shape, and
3843 // 2) if it's in a mute section
3844 // if both answers are 'yes', notify the form layer export
3846 // we join accessing the shape and testing for control
3847 Reference
<XControlShape
> xControlShape(xShapesEnum
->nextElement(), UNO_QUERY
);
3848 if( xControlShape
.is() )
3850 // Reference<XPropertySet> xPropSet( xControlShape, UNO_QUERY );
3851 // Reference<XTextContent> xTextContent;
3852 // xPropSet->getPropertyValue("TextRange") >>= xTextContent;
3854 Reference
<XTextContent
> xTextContent( xControlShape
, UNO_QUERY
);
3855 if( xTextContent
.is() )
3857 if( pSectionExport
->IsMuteSection( xTextContent
, false ) )
3859 // Ah, we've found a shape that
3860 // 1) is a control shape
3861 // 2) is anchored in a mute section
3862 // so: don't export it!
3863 xFormExport
->excludeFromExport(
3864 xControlShape
->getControl() );
3866 // else: not in mute section -> should be exported -> nothing
3869 // else: no anchor -> ignore
3871 // else: no control shape -> nothing to do
3875 void XMLTextParagraphExport::PushNewTextListsHelper()
3877 maTextListsHelperStack
.emplace_back( new XMLTextListsHelper() );
3878 mpTextListsHelper
= maTextListsHelperStack
.back().get();
3881 void XMLTextParagraphExport::PopTextListsHelper()
3883 mpTextListsHelper
= nullptr;
3884 maTextListsHelperStack
.pop_back();
3885 if ( !maTextListsHelperStack
.empty() )
3887 mpTextListsHelper
= maTextListsHelperStack
.back().get();
3891 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */