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>
112 #include <o3tl/safeint.hxx>
113 #include <comphelper/sequenceashashmap.hxx>
115 using namespace ::std
;
116 using namespace ::com::sun::star
;
117 using namespace ::com::sun::star::uno
;
118 using namespace ::com::sun::star::lang
;
119 using namespace ::com::sun::star::beans
;
120 using namespace ::com::sun::star::container
;
121 using namespace ::com::sun::star::text
;
122 using namespace ::com::sun::star::style
;
123 using namespace ::com::sun::star::util
;
124 using namespace ::com::sun::star::drawing
;
125 using namespace ::com::sun::star::document
;
126 using namespace ::com::sun::star::graphic
;
127 using namespace ::xmloff
;
128 using namespace ::xmloff::token
;
130 // Implement Title/Description Elements UI (#i73249#)
131 constexpr OUStringLiteral
gsTitle(u
"Title");
132 constexpr OUStringLiteral
gsDescription(u
"Description");
133 constexpr OUStringLiteral
gsAnchorPageNo(u
"AnchorPageNo");
134 constexpr OUStringLiteral
gsAnchorType(u
"AnchorType");
135 constexpr OUStringLiteral
gsBookmark(u
"Bookmark");
136 constexpr OUStringLiteral
gsChainNextName(u
"ChainNextName");
137 constexpr OUStringLiteral
gsContourPolyPolygon(u
"ContourPolyPolygon");
138 constexpr OUStringLiteral
gsDocumentIndexMark(u
"DocumentIndexMark");
139 constexpr OUStringLiteral
gsFrame(u
"Frame");
140 constexpr OUStringLiteral
gsGraphicFilter(u
"GraphicFilter");
141 constexpr OUStringLiteral
gsGraphicRotation(u
"GraphicRotation");
142 constexpr OUStringLiteral
gsHeight(u
"Height");
143 constexpr OUStringLiteral
gsHoriOrient(u
"HoriOrient");
144 constexpr OUStringLiteral
gsHoriOrientPosition(u
"HoriOrientPosition");
145 constexpr OUStringLiteral
gsHyperLinkName(u
"HyperLinkName");
146 constexpr OUStringLiteral
gsHyperLinkTarget(u
"HyperLinkTarget");
147 constexpr OUStringLiteral
gsHyperLinkURL(u
"HyperLinkURL");
148 constexpr OUStringLiteral
gsIsAutomaticContour(u
"IsAutomaticContour");
149 constexpr OUStringLiteral
gsIsCollapsed(u
"IsCollapsed");
150 constexpr OUStringLiteral
gsIsPixelContour(u
"IsPixelContour");
151 constexpr OUStringLiteral
gsIsStart(u
"IsStart");
152 constexpr OUStringLiteral
gsIsSyncHeightToWidth(u
"IsSyncHeightToWidth");
153 constexpr OUStringLiteral
gsIsSyncWidthToHeight(u
"IsSyncWidthToHeight");
154 constexpr OUStringLiteral
gsNumberingRules(u
"NumberingRules");
155 constexpr OUStringLiteral
gsParaConditionalStyleName(u
"ParaConditionalStyleName");
156 constexpr OUStringLiteral
gsParagraphService(u
"com.sun.star.text.Paragraph");
157 constexpr OUStringLiteral
gsRedline(u
"Redline");
158 constexpr OUStringLiteral
gsReferenceMark(u
"ReferenceMark");
159 constexpr OUStringLiteral
gsRelativeHeight(u
"RelativeHeight");
160 constexpr OUStringLiteral
gsRelativeWidth(u
"RelativeWidth");
161 constexpr OUStringLiteral
gsRuby(u
"Ruby");
162 constexpr OUStringLiteral
gsRubyCharStyleName(u
"RubyCharStyleName");
163 constexpr OUStringLiteral
gsRubyText(u
"RubyText");
164 constexpr OUStringLiteral
gsServerMap(u
"ServerMap");
165 constexpr OUStringLiteral
gsShapeService(u
"com.sun.star.drawing.Shape");
166 constexpr OUStringLiteral
gsSizeType(u
"SizeType");
167 constexpr OUStringLiteral
gsSoftPageBreak( u
"SoftPageBreak" );
168 constexpr OUStringLiteral
gsTableService(u
"com.sun.star.text.TextTable");
169 constexpr OUStringLiteral
gsText(u
"Text");
170 constexpr OUStringLiteral
gsTextContentService(u
"com.sun.star.text.TextContent");
171 constexpr OUStringLiteral
gsTextEmbeddedService(u
"com.sun.star.text.TextEmbeddedObject");
172 constexpr OUStringLiteral
gsTextField(u
"TextField");
173 constexpr OUStringLiteral
gsTextFieldService(u
"com.sun.star.text.TextField");
174 constexpr OUStringLiteral
gsTextFrameService(u
"com.sun.star.text.TextFrame");
175 constexpr OUStringLiteral
gsTextGraphicService(u
"com.sun.star.text.TextGraphicObject");
176 constexpr OUStringLiteral
gsTextPortionType(u
"TextPortionType");
177 constexpr OUStringLiteral
gsUnvisitedCharStyleName(u
"UnvisitedCharStyleName");
178 constexpr OUStringLiteral
gsVertOrient(u
"VertOrient");
179 constexpr OUStringLiteral
gsVertOrientPosition(u
"VertOrientPosition");
180 constexpr OUStringLiteral
gsVisitedCharStyleName(u
"VisitedCharStyleName");
181 constexpr OUStringLiteral
gsWidth(u
"Width");
182 constexpr OUStringLiteral
gsWidthType( u
"WidthType" );
183 constexpr OUStringLiteral
gsTextFieldStart( u
"TextFieldStart" );
184 constexpr OUStringLiteral
gsTextFieldEnd( u
"TextFieldEnd" );
185 constexpr OUStringLiteral
gsTextFieldStartEnd( u
"TextFieldStartEnd" );
192 typedef list
<Reference
<XTextContent
>> contents_t
;
193 typedef back_insert_iterator
<contents_t
> inserter_t
;
194 typedef contents_t::const_iterator const_iterator_t
;
196 inserter_t
getInserter()
197 { return back_insert_iterator
<contents_t
>(m_vTextContents
); };
198 const_iterator_t
getBegin() const
199 { return m_vTextContents
.begin(); };
200 const_iterator_t
getEnd() const
201 { return m_vTextContents
.end(); };
204 contents_t m_vTextContents
;
209 size_t operator()(const Reference
<XTextFrame
>& rFrame
) const
210 { return sal::static_int_cast
<size_t>(reinterpret_cast<sal_uIntPtr
>(rFrame
.get())); }
213 bool lcl_TextContentsUnfiltered(const Reference
<XTextContent
>&)
216 bool lcl_ShapeFilter(const Reference
<XTextContent
>& xTxtContent
)
218 Reference
<XShape
> xShape(xTxtContent
, UNO_QUERY
);
221 Reference
<XServiceInfo
> xServiceInfo(xTxtContent
, UNO_QUERY
);
222 return !xServiceInfo
->supportsService("com.sun.star.text.TextFrame") &&
223 !xServiceInfo
->supportsService("com.sun.star.text.TextGraphicObject") &&
224 !xServiceInfo
->supportsService("com.sun.star.text.TextEmbeddedObject");
230 typedef bool (*filter_t
)(const Reference
<XTextContent
>&);
232 const Reference
<XEnumerationAccess
>& rEnumAccess
,
233 const filter_t
& rFilter
)
234 : m_xEnumAccess(rEnumAccess
)
240 const TextContentSet
& GetPageBoundContents() const
241 { return m_vPageBounds
; };
242 const TextContentSet
* GetFrameBoundContents(const Reference
<XTextFrame
>& rParentFrame
) const
244 framebound_map_t::const_iterator it
= m_vFrameBoundsOf
.find(rParentFrame
);
245 if(it
== m_vFrameBoundsOf
.end())
247 return &(it
->second
);
249 Reference
<XEnumeration
> createEnumeration() const
251 if(!m_xEnumAccess
.is())
252 return Reference
<XEnumeration
>();
253 return m_xEnumAccess
->createEnumeration();
257 typedef std::unordered_map
<
258 Reference
<XTextFrame
>,
260 FrameRefHash
> framebound_map_t
;
261 TextContentSet m_vPageBounds
;
262 framebound_map_t m_vFrameBoundsOf
;
263 const Reference
<XEnumerationAccess
> m_xEnumAccess
;
264 void Fill(const filter_t
& rFilter
);
267 class FieldParamExporter
270 FieldParamExporter(SvXMLExport
* const pExport
, Reference
<XNameContainer
> const & xFieldParams
)
272 , m_xFieldParams(xFieldParams
)
277 SvXMLExport
* const m_pExport
;
278 const Reference
<XNameContainer
> m_xFieldParams
;
280 void ExportParameter(const OUString
& sKey
, const OUString
& sValue
);
289 explicit BoundFrameSets(const Reference
<XInterface
>& rModel
);
290 const BoundFrames
* GetTexts() const
291 { return m_pTexts
.get(); };
292 const BoundFrames
* GetGraphics() const
293 { return m_pGraphics
.get(); };
294 const BoundFrames
* GetEmbeddeds() const
295 { return m_pEmbeddeds
.get(); };
296 const BoundFrames
* GetShapes() const
297 { return m_pShapes
.get(); };
299 unique_ptr
<BoundFrames
> m_pTexts
;
300 unique_ptr
<BoundFrames
> m_pGraphics
;
301 unique_ptr
<BoundFrames
> m_pEmbeddeds
;
302 unique_ptr
<BoundFrames
> m_pShapes
;
307 static bool txtparae_bContainsIllegalCharacters
= false;
310 // The following map shows which property values are required:
312 // property auto style pass export
314 // ParaStyleName if style exists always
315 // ParaConditionalStyleName if style exists always
316 // NumberingRules if style exists always
317 // TextSection always always
318 // ParaChapterNumberingLevel never always
319 // NumberingIsNumber never always
321 // The conclusion is that for auto styles the first three properties
322 // should be queried using a multi property set if, and only if, an
323 // auto style needs to be exported. TextSection should be queried by
324 // an individual call to getPropertyvalue, because this seems to be
325 // less expensive than querying the first three properties if they aren't
328 // For the export pass all properties can be queried using a multi property
331 static const char* aParagraphPropertyNamesAuto
[] =
334 "ParaConditionalStyleName",
341 enum eParagraphPropertyNamesEnumAuto
343 NUMBERING_RULES_AUTO
= 0,
344 PARA_CONDITIONAL_STYLE_NAME_AUTO
= 1,
345 PARA_STYLE_NAME_AUTO
= 2
350 static const char* aParagraphPropertyNames
[] =
353 "NumberingStyleName",
355 "ParaConditionalStyleName",
358 "OutlineContentVisible",
364 enum eParagraphPropertyNamesEnum
366 NUMBERING_IS_NUMBER
= 0,
367 PARA_NUMBERING_STYLENAME
= 1,
368 PARA_OUTLINE_LEVEL
=2,
369 PARA_CONDITIONAL_STYLE_NAME
= 3,
372 PARA_OUTLINE_CONTENT_VISIBLE
= 6
377 void BoundFrames::Fill(const filter_t
& rFilter
)
379 if(!m_xEnumAccess
.is())
381 const Reference
< XEnumeration
> xEnum
= m_xEnumAccess
->createEnumeration();
384 static const OUStringLiteral
our_sAnchorType(u
"AnchorType");
385 static const OUStringLiteral
our_sAnchorFrame(u
"AnchorFrame");
386 while(xEnum
->hasMoreElements())
388 Reference
<XPropertySet
> xPropSet(xEnum
->nextElement(), UNO_QUERY
);
389 Reference
<XTextContent
> xTextContent(xPropSet
, UNO_QUERY
);
390 if(!xPropSet
.is() || !xTextContent
.is())
392 TextContentAnchorType eAnchor
;
393 xPropSet
->getPropertyValue(our_sAnchorType
) >>= eAnchor
;
394 if(TextContentAnchorType_AT_PAGE
!= eAnchor
&& TextContentAnchorType_AT_FRAME
!= eAnchor
)
396 if(!rFilter(xTextContent
))
399 TextContentSet::inserter_t pInserter
= m_vPageBounds
.getInserter();
400 if(TextContentAnchorType_AT_FRAME
== eAnchor
)
402 Reference
<XTextFrame
> xAnchorTxtFrame(
403 xPropSet
->getPropertyValue(our_sAnchorFrame
),
405 pInserter
= m_vFrameBoundsOf
[xAnchorTxtFrame
].getInserter();
407 *pInserter
++ = xTextContent
;
411 BoundFrameSets::BoundFrameSets(const Reference
<XInterface
>& rModel
)
412 : m_pTexts(new BoundFrames())
413 , m_pGraphics(new BoundFrames())
414 , m_pEmbeddeds(new BoundFrames())
415 , m_pShapes(new BoundFrames())
417 const Reference
<XTextFramesSupplier
> xTFS(rModel
, UNO_QUERY
);
418 const Reference
<XTextGraphicObjectsSupplier
> xGOS(rModel
, UNO_QUERY
);
419 const Reference
<XTextEmbeddedObjectsSupplier
> xEOS(rModel
, UNO_QUERY
);
420 const Reference
<XDrawPageSupplier
> xDPS(rModel
, UNO_QUERY
);
422 m_pTexts
.reset(new BoundFrames(
423 Reference
<XEnumerationAccess
>(xTFS
->getTextFrames(), UNO_QUERY
),
424 &lcl_TextContentsUnfiltered
));
426 m_pGraphics
.reset(new BoundFrames(
427 Reference
<XEnumerationAccess
>(xGOS
->getGraphicObjects(), UNO_QUERY
),
428 &lcl_TextContentsUnfiltered
));
430 m_pEmbeddeds
.reset(new BoundFrames(
431 Reference
<XEnumerationAccess
>(xEOS
->getEmbeddedObjects(), UNO_QUERY
),
432 &lcl_TextContentsUnfiltered
));
434 m_pShapes
.reset(new BoundFrames(
435 Reference
<XEnumerationAccess
>(xDPS
->getDrawPage(), UNO_QUERY
),
439 void FieldParamExporter::Export()
441 const Type aStringType
= ::cppu::UnoType
<OUString
>::get();
442 const Type aBoolType
= cppu::UnoType
<sal_Bool
>::get();
443 const Type aSeqType
= cppu::UnoType
<Sequence
<OUString
>>::get();
444 const Type aIntType
= ::cppu::UnoType
<sal_Int32
>::get();
445 const Sequence
<OUString
> vParameters(m_xFieldParams
->getElementNames());
446 for(const auto & rParameter
: vParameters
)
448 const Any aValue
= m_xFieldParams
->getByName(rParameter
);
449 const Type
& aValueType
= aValue
.getValueType();
450 if(aValueType
== aStringType
)
454 ExportParameter(rParameter
,sValue
);
456 if ( rParameter
== ODF_OLE_PARAM
)
458 // Save the OLE object
459 Reference
< embed::XStorage
> xTargetStg
= m_pExport
->GetTargetStorage();
460 if (xTargetStg
.is()) {
461 Reference
< embed::XStorage
> xDstStg
= xTargetStg
->openStorageElement(
462 "OLELinks", embed::ElementModes::WRITE
);
464 if ( !xDstStg
->hasByName( sValue
) ) {
465 Reference
< XStorageBasedDocument
> xStgDoc (
466 m_pExport
->GetModel( ), UNO_QUERY
);
467 Reference
< embed::XStorage
> xDocStg
= xStgDoc
->getDocumentStorage();
468 Reference
< embed::XStorage
> xOleStg
= xDocStg
->openStorageElement(
469 "OLELinks", embed::ElementModes::READ
);
471 xOleStg
->copyElementTo( sValue
, xDstStg
, sValue
);
472 Reference
< embed::XTransactedObject
> xTransact( xDstStg
, UNO_QUERY
);
473 if ( xTransact
.is( ) )
474 xTransact
->commit( );
477 SAL_WARN("xmloff", "no target storage");
481 else if(aValueType
== aBoolType
)
485 ExportParameter(rParameter
, OUString::boolean(bValue
) );
487 else if(aValueType
== aSeqType
)
489 Sequence
<OUString
> vValue
;
491 for(const OUString
& i
: std::as_const(vValue
))
493 ExportParameter(rParameter
, i
);
496 else if(aValueType
== aIntType
)
498 sal_Int32 nValue
= 0;
500 ExportParameter(rParameter
, OUString::number(nValue
));
505 void FieldParamExporter::ExportParameter(const OUString
& sKey
, const OUString
& sValue
)
507 m_pExport
->AddAttribute(XML_NAMESPACE_FIELD
, XML_NAME
, sKey
);
508 m_pExport
->AddAttribute(XML_NAMESPACE_FIELD
, XML_VALUE
, sValue
);
509 m_pExport
->StartElement(XML_NAMESPACE_FIELD
, XML_PARAM
, false);
510 m_pExport
->EndElement(XML_NAMESPACE_FIELD
, XML_PARAM
, false);
513 void XMLTextParagraphExport::Add( XmlStyleFamily nFamily
,
514 const Reference
< XPropertySet
> & rPropSet
,
515 const o3tl::span
<const XMLPropertyState
> aAddStates
,
518 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper
;
521 case XmlStyleFamily::TEXT_PARAGRAPH
:
522 xPropMapper
= GetParaPropMapper();
524 case XmlStyleFamily::TEXT_TEXT
:
525 xPropMapper
= GetTextPropMapper();
527 case XmlStyleFamily::TEXT_FRAME
:
528 xPropMapper
= GetAutoFramePropMapper();
530 case XmlStyleFamily::TEXT_SECTION
:
531 xPropMapper
= GetSectionPropMapper();
533 case XmlStyleFamily::TEXT_RUBY
:
534 xPropMapper
= GetRubyPropMapper();
538 SAL_WARN_IF( !xPropMapper
.is(), "xmloff", "There is the property mapper?" );
540 vector
< XMLPropertyState
> aPropStates
=
541 xPropMapper
->Filter(GetExport(), rPropSet
);
543 aPropStates
.insert( aPropStates
.end(), aAddStates
.begin(), aAddStates
.end() );
545 if( aPropStates
.empty() )
548 Reference
< XPropertySetInfo
> xPropSetInfo(rPropSet
->getPropertySetInfo());
549 OUString sParent
, sCondParent
;
550 sal_uInt16 nIgnoreProps
= 0;
553 case XmlStyleFamily::TEXT_PARAGRAPH
:
554 if( xPropSetInfo
->hasPropertyByName( gsParaStyleName
) )
556 rPropSet
->getPropertyValue( gsParaStyleName
) >>= sParent
;
558 if( xPropSetInfo
->hasPropertyByName( gsParaConditionalStyleName
) )
560 rPropSet
->getPropertyValue( gsParaConditionalStyleName
) >>= sCondParent
;
562 if( xPropSetInfo
->hasPropertyByName( gsNumberingRules
) )
564 Reference
< XIndexReplace
> xNumRule(rPropSet
->getPropertyValue( gsNumberingRules
), uno::UNO_QUERY
);
565 if( xNumRule
.is() && xNumRule
->getCount() )
567 Reference
< XNamed
> xNamed( xNumRule
, UNO_QUERY
);
570 sName
= xNamed
->getName();
571 bool bAdd
= sName
.isEmpty();
574 Reference
< XPropertySet
> xNumPropSet( xNumRule
,
576 if( xNumPropSet
.is() &&
577 xNumPropSet
->getPropertySetInfo()
578 ->hasPropertyByName( "IsAutomatic" ) )
580 bAdd
= *o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "IsAutomatic" ));
581 // Check on outline style (#i73361#)
583 xNumPropSet
->getPropertySetInfo()
584 ->hasPropertyByName( "NumberingIsOutline" ) )
586 bAdd
= !(*o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "NumberingIsOutline" )));
595 maListAutoPool
.Add( xNumRule
);
599 case XmlStyleFamily::TEXT_TEXT
:
601 // Get parent and remove hyperlinks (they aren't of interest)
602 rtl::Reference
< XMLPropertySetMapper
> xPM(xPropMapper
->getPropertySetMapper());
603 for( ::std::vector
< XMLPropertyState
>::iterator
i(aPropStates
.begin());
604 nIgnoreProps
< 2 && i
!= aPropStates
.end(); )
606 if( i
->mnIndex
== -1 )
612 switch( xPM
->GetEntryContextId(i
->mnIndex
) )
614 case CTF_CHAR_STYLE_NAME
:
615 case CTF_HYPERLINK_URL
:
618 i
= aPropStates
.erase( i
);
627 case XmlStyleFamily::TEXT_FRAME
:
628 if( xPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
630 rPropSet
->getPropertyValue( gsFrameStyleName
) >>= sParent
;
633 case XmlStyleFamily::TEXT_SECTION
:
634 case XmlStyleFamily::TEXT_RUBY
:
635 ; // section styles have no parents
639 if (aPropStates
.size() - nIgnoreProps
)
641 GetAutoStylePool().Add( nFamily
, sParent
, std::vector(aPropStates
), bDontSeek
);
642 if( !sCondParent
.isEmpty() && sParent
!= sCondParent
)
643 GetAutoStylePool().Add( nFamily
, sCondParent
, std::move(aPropStates
) );
647 static bool lcl_validPropState( const XMLPropertyState
& rState
)
649 return rState
.mnIndex
!= -1;
652 void XMLTextParagraphExport::Add( XmlStyleFamily nFamily
,
653 MultiPropertySetHelper
& rPropSetHelper
,
654 const Reference
< XPropertySet
> & rPropSet
)
656 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper
;
659 case XmlStyleFamily::TEXT_PARAGRAPH
:
660 xPropMapper
= GetParaPropMapper();
664 SAL_WARN_IF( !xPropMapper
.is(), "xmloff", "There is the property mapper?" );
666 vector
<XMLPropertyState
> aPropStates(xPropMapper
->Filter(GetExport(), rPropSet
));
668 if( rPropSetHelper
.hasProperty( NUMBERING_RULES_AUTO
) )
670 Reference
< XIndexReplace
> xNumRule(rPropSetHelper
.getValue( NUMBERING_RULES_AUTO
,
671 rPropSet
, true ), uno::UNO_QUERY
);
672 if( xNumRule
.is() && xNumRule
->getCount() )
674 Reference
< XNamed
> xNamed( xNumRule
, UNO_QUERY
);
677 sName
= xNamed
->getName();
678 bool bAdd
= sName
.isEmpty();
681 Reference
< XPropertySet
> xNumPropSet( xNumRule
,
683 if( xNumPropSet
.is() &&
684 xNumPropSet
->getPropertySetInfo()
685 ->hasPropertyByName( "IsAutomatic" ) )
687 bAdd
= *o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "IsAutomatic" ));
688 // Check on outline style (#i73361#)
690 xNumPropSet
->getPropertySetInfo()
691 ->hasPropertyByName( "NumberingIsOutline" ) )
693 bAdd
= !(*o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "NumberingIsOutline" )));
702 maListAutoPool
.Add( xNumRule
);
706 if( aPropStates
.empty() )
709 OUString sParent
, sCondParent
;
712 case XmlStyleFamily::TEXT_PARAGRAPH
:
713 if( rPropSetHelper
.hasProperty( PARA_STYLE_NAME_AUTO
) )
715 rPropSetHelper
.getValue( PARA_STYLE_NAME_AUTO
, rPropSet
,
718 if( rPropSetHelper
.hasProperty( PARA_CONDITIONAL_STYLE_NAME_AUTO
) )
720 rPropSetHelper
.getValue( PARA_CONDITIONAL_STYLE_NAME_AUTO
,
721 rPropSet
, true ) >>= sCondParent
;
728 if( std::any_of( aPropStates
.begin(), aPropStates
.end(), lcl_validPropState
) )
730 GetAutoStylePool().Add( nFamily
, sParent
, std::vector(aPropStates
) );
731 if( !sCondParent
.isEmpty() && sParent
!= sCondParent
)
732 GetAutoStylePool().Add( nFamily
, sCondParent
, std::move(aPropStates
) );
736 OUString
XMLTextParagraphExport::Find(
737 XmlStyleFamily nFamily
,
738 const Reference
< XPropertySet
> & rPropSet
,
739 const OUString
& rParent
,
740 const o3tl::span
<const XMLPropertyState
> aAddStates
) const
742 OUString
sName( rParent
);
743 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper
;
746 case XmlStyleFamily::TEXT_PARAGRAPH
:
747 xPropMapper
= GetParaPropMapper();
749 case XmlStyleFamily::TEXT_FRAME
:
750 xPropMapper
= GetAutoFramePropMapper();
752 case XmlStyleFamily::TEXT_SECTION
:
753 xPropMapper
= GetSectionPropMapper();
755 case XmlStyleFamily::TEXT_RUBY
:
756 xPropMapper
= GetRubyPropMapper();
760 SAL_WARN_IF( !xPropMapper
.is(), "xmloff", "There is the property mapper?" );
761 if( !xPropMapper
.is() )
763 vector
<XMLPropertyState
> aPropStates(xPropMapper
->Filter(GetExport(), rPropSet
));
764 aPropStates
.insert( aPropStates
.end(), aAddStates
.begin(), aAddStates
.end() );
765 if( std::any_of( aPropStates
.begin(), aPropStates
.end(), lcl_validPropState
) )
766 sName
= GetAutoStylePool().Find( nFamily
, sName
, aPropStates
);
771 OUString
XMLTextParagraphExport::FindTextStyleAndHyperlink(
772 const Reference
< XPropertySet
> & rPropSet
,
774 bool& rbHasCharStyle
,
775 bool& rbHasAutoStyle
,
776 const XMLPropertyState
** ppAddStates
) const
778 rtl::Reference
< SvXMLExportPropertyMapper
> xPropMapper(GetTextPropMapper());
779 vector
<XMLPropertyState
> aPropStates(xPropMapper
->Filter(GetExport(), rPropSet
));
781 // Get parent and remove hyperlinks (they aren't of interest)
783 rbHyperlink
= rbHasCharStyle
= rbHasAutoStyle
= false;
784 sal_uInt16 nIgnoreProps
= 0;
785 rtl::Reference
< XMLPropertySetMapper
> xPM(xPropMapper
->getPropertySetMapper());
786 ::std::vector
< XMLPropertyState
>::iterator aFirstDel
= aPropStates
.end();
787 ::std::vector
< XMLPropertyState
>::iterator aSecondDel
= aPropStates
.end();
789 for( ::std::vector
< XMLPropertyState
>::iterator
790 i
= aPropStates
.begin();
791 nIgnoreProps
< 2 && i
!= aPropStates
.end();
794 if( i
->mnIndex
== -1 )
797 switch( xPM
->GetEntryContextId(i
->mnIndex
) )
799 case CTF_CHAR_STYLE_NAME
:
800 i
->maValue
>>= sName
;
802 rbHasCharStyle
= !sName
.isEmpty();
809 case CTF_HYPERLINK_URL
:
822 while( *ppAddStates
)
824 aPropStates
.push_back( **ppAddStates
);
828 if (aPropStates
.size() - nIgnoreProps
)
830 // erase the character style, otherwise the autostyle cannot be found!
831 // erase the hyperlink, otherwise the autostyle cannot be found!
834 // If two elements of a vector have to be deleted,
835 // we should delete the second one first.
837 aPropStates
.erase( aSecondDel
);
838 aPropStates
.erase( aFirstDel
);
840 sName
= GetAutoStylePool().Find(
841 XmlStyleFamily::TEXT_TEXT
,
842 OUString(), // AutoStyles should not have parents!
844 rbHasAutoStyle
= true;
850 // adjustments to support lists independent from list style
851 void XMLTextParagraphExport::exportListChange(
852 const XMLTextNumRuleInfo
& rPrevInfo
,
853 const XMLTextNumRuleInfo
& rNextInfo
)
856 if ( rPrevInfo
.GetLevel() > 0 )
858 sal_Int16 nListLevelsToBeClosed
= 0;
859 if ( !rNextInfo
.BelongsToSameList( rPrevInfo
) ||
860 rNextInfo
.GetLevel() <= 0 )
862 // close complete previous list
863 nListLevelsToBeClosed
= rPrevInfo
.GetLevel();
865 else if ( rPrevInfo
.GetLevel() > rNextInfo
.GetLevel() )
867 // close corresponding sub lists
868 SAL_WARN_IF( rNextInfo
.GetLevel() <= 0, "xmloff",
869 "<rPrevInfo.GetLevel() > 0> not hold. Serious defect." );
870 nListLevelsToBeClosed
= rPrevInfo
.GetLevel() - rNextInfo
.GetLevel();
873 if ( nListLevelsToBeClosed
> 0 &&
874 maListElements
.size() >= sal::static_int_cast
< sal_uInt32
>( 2 * nListLevelsToBeClosed
) )
877 for(size_t j
= 0; j
< 2; ++j
)
879 OUString
aElem(maListElements
.back());
880 maListElements
.pop_back();
881 GetExport().EndElement(aElem
, true);
884 // remove closed list from list stack
885 mpTextListsHelper
->PopListFromStack();
887 --nListLevelsToBeClosed
;
888 } while ( nListLevelsToBeClosed
> 0 );
892 const bool bExportODF
=
893 bool( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
);
894 const SvtSaveOptions::ODFSaneDefaultVersion eODFDefaultVersion
=
895 GetExport().getSaneDefaultVersion();
898 if ( rNextInfo
.GetLevel() > 0 )
900 bool bRootListToBeStarted
= false;
901 sal_Int16 nListLevelsToBeOpened
= 0;
902 if ( !rPrevInfo
.BelongsToSameList( rNextInfo
) ||
903 rPrevInfo
.GetLevel() <= 0 )
906 bRootListToBeStarted
= true;
907 nListLevelsToBeOpened
= rNextInfo
.GetLevel();
909 else if ( rNextInfo
.GetLevel() > rPrevInfo
.GetLevel() )
911 // open corresponding sub lists
912 SAL_WARN_IF( rPrevInfo
.GetLevel() <= 0, "xmloff",
913 "<rPrevInfo.GetLevel() > 0> not hold. Serious defect." );
914 nListLevelsToBeOpened
= rNextInfo
.GetLevel() - rPrevInfo
.GetLevel();
917 if ( nListLevelsToBeOpened
> 0 )
919 const OUString
& sListStyleName( rNextInfo
.GetNumRulesName() );
920 // Currently only the text documents support <ListId>.
921 // Thus, for other document types <sListId> is empty.
922 const OUString
& sListId( rNextInfo
.GetListId() );
923 bool bExportListStyle( true );
924 bool bRestartNumberingAtContinuedList( false );
925 sal_Int32
nRestartValueForContinuedList( -1 );
926 bool bContinueingPreviousSubList
= !bRootListToBeStarted
&&
927 rNextInfo
.IsContinueingPreviousSubTree();
929 GetExport().CheckAttrList();
931 if ( bRootListToBeStarted
)
933 if ( !mpTextListsHelper
->IsListProcessed( sListId
) )
936 eODFDefaultVersion
>= SvtSaveOptions::ODFSVER_012
&&
939 /* Property text:id at element <text:list> has to be
940 replaced by property xml:id (#i92221#)
942 GetExport().AddAttribute( XML_NAMESPACE_XML
,
946 mpTextListsHelper
->KeepListAsProcessed( sListId
,
952 const OUString
sNewListId(
953 mpTextListsHelper
->GenerateNewListId() );
955 eODFDefaultVersion
>= SvtSaveOptions::ODFSVER_012
&&
958 /* Property text:id at element <text:list> has to be
959 replaced by property xml:id (#i92221#)
961 GetExport().AddAttribute( XML_NAMESPACE_XML
,
966 const OUString sContinueListId
=
967 mpTextListsHelper
->GetLastContinuingListId( sListId
);
968 // store that list with list id <sNewListId> is last list,
969 // which has continued list with list id <sListId>
970 mpTextListsHelper
->StoreLastContinuingList( sListId
,
972 if ( sListStyleName
==
973 mpTextListsHelper
->GetListStyleOfLastProcessedList() &&
974 // Inconsistent behavior regarding lists (#i92811#)
976 mpTextListsHelper
->GetLastProcessedListId() &&
977 !rNextInfo
.IsRestart() )
979 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
980 XML_CONTINUE_NUMBERING
,
986 eODFDefaultVersion
>= SvtSaveOptions::ODFSVER_012
&&
989 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
994 if ( rNextInfo
.IsRestart() &&
995 ( nListLevelsToBeOpened
!= 1 ||
996 !rNextInfo
.HasStartValue() ) )
998 bRestartNumberingAtContinuedList
= true;
999 nRestartValueForContinuedList
=
1000 rNextInfo
.GetListLevelStartValue();
1004 mpTextListsHelper
->KeepListAsProcessed( sNewListId
,
1009 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
1010 GetExport().EncodeStyleName( sListStyleName
) );
1011 bExportListStyle
= false;
1013 bRootListToBeStarted
= false;
1015 else if ( bExportListStyle
&&
1016 !mpTextListsHelper
->EqualsToTopListStyleOnStack( sListStyleName
) )
1018 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
1019 GetExport().EncodeStyleName( sListStyleName
) );
1020 bExportListStyle
= false;
1025 // rhbz#746174: also export list restart for non root list
1026 if (rNextInfo
.IsRestart() && !rNextInfo
.HasStartValue())
1028 bRestartNumberingAtContinuedList
= true;
1029 nRestartValueForContinuedList
=
1030 rNextInfo
.GetListLevelStartValue();
1034 if ( bContinueingPreviousSubList
)
1036 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1037 XML_CONTINUE_NUMBERING
, XML_TRUE
);
1038 bContinueingPreviousSubList
= false;
1041 enum XMLTokenEnum eLName
= XML_LIST
;
1043 OUString
aElem(GetExport().GetNamespaceMap().GetQNameByKey(
1045 GetXMLToken(eLName
) ) );
1046 GetExport().IgnorableWhitespace();
1047 GetExport().StartElement(aElem
, false);
1049 maListElements
.push_back(aElem
);
1051 mpTextListsHelper
->PushListOnStack( sListId
,
1054 // <text:list-header> or <text:list-item>
1055 GetExport().CheckAttrList();
1057 /* Export start value at correct list item (#i97309#) */
1058 if ( nListLevelsToBeOpened
== 1 )
1060 if ( rNextInfo
.HasStartValue() )
1062 OUStringBuffer aBuffer
;
1063 aBuffer
.append( static_cast<sal_Int32
>(rNextInfo
.GetStartValue()) );
1064 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_START_VALUE
,
1065 aBuffer
.makeStringAndClear() );
1067 else if (bRestartNumberingAtContinuedList
)
1069 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1071 OUString::number(nRestartValueForContinuedList
) );
1072 bRestartNumberingAtContinuedList
= false;
1076 eLName
= ( rNextInfo
.IsNumbered() || nListLevelsToBeOpened
> 1 )
1079 aElem
= GetExport().GetNamespaceMap().GetQNameByKey(
1081 GetXMLToken(eLName
) );
1082 GetExport().IgnorableWhitespace();
1083 GetExport().StartElement(aElem
, false);
1084 maListElements
.push_back(aElem
);
1086 // export of <text:number> element for last opened <text:list-item>, if requested
1087 if ( GetExport().exportTextNumberElement() &&
1088 eLName
== XML_LIST_ITEM
&& nListLevelsToBeOpened
== 1 && // last iteration --> last opened <text:list-item>
1089 !rNextInfo
.ListLabelString().isEmpty() )
1091 const OUString aTextNumberElem
=
1092 GetExport().GetNamespaceMap().GetQNameByKey(
1094 GetXMLToken(XML_NUMBER
) );
1095 GetExport().IgnorableWhitespace();
1096 GetExport().StartElement( aTextNumberElem
, false );
1097 GetExport().Characters( rNextInfo
.ListLabelString() );
1098 GetExport().EndElement( aTextNumberElem
, true );
1100 --nListLevelsToBeOpened
;
1101 } while ( nListLevelsToBeOpened
> 0 );
1105 bool bEndElement
= false;
1107 if ( rNextInfo
.GetLevel() > 0 &&
1108 rNextInfo
.IsNumbered() &&
1109 rPrevInfo
.BelongsToSameList( rNextInfo
) &&
1110 rPrevInfo
.GetLevel() >= rNextInfo
.GetLevel() )
1112 assert(maListElements
.size() >= 2 && "list elements missing");
1113 bEndElement
= maListElements
.size() >= 2;
1119 // close previous list-item
1120 GetExport().EndElement(maListElements
.back(), true );
1121 maListElements
.pop_back();
1123 // Only for sub lists (#i103745#)
1124 if ( rNextInfo
.IsRestart() && !rNextInfo
.HasStartValue() &&
1125 rNextInfo
.GetLevel() != 1 )
1127 // start new sub list respectively list on same list level
1128 GetExport().EndElement(maListElements
.back(), true );
1129 GetExport().IgnorableWhitespace();
1130 GetExport().StartElement(maListElements
.back(), false);
1133 // open new list-item
1134 GetExport().CheckAttrList();
1135 if( rNextInfo
.HasStartValue() )
1137 OUStringBuffer aBuffer
;
1138 aBuffer
.append( static_cast<sal_Int32
>(rNextInfo
.GetStartValue()) );
1139 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_START_VALUE
,
1140 aBuffer
.makeStringAndClear() );
1142 // Handle restart without start value on list level 1 (#i103745#)
1143 else if ( rNextInfo
.IsRestart() && /*!rNextInfo.HasStartValue() &&*/
1144 rNextInfo
.GetLevel() == 1 )
1146 OUStringBuffer aBuffer
;
1147 aBuffer
.append( static_cast<sal_Int32
>(rNextInfo
.GetListLevelStartValue()) );
1148 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_START_VALUE
,
1149 aBuffer
.makeStringAndClear() );
1151 if ( ( GetExport().getExportFlags() & SvXMLExportFlags::OASIS
) &&
1152 GetExport().getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
1154 const OUString
& sListStyleName( rNextInfo
.GetNumRulesName() );
1155 if ( !mpTextListsHelper
->EqualsToTopListStyleOnStack( sListStyleName
) )
1157 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1159 GetExport().EncodeStyleName( sListStyleName
) );
1162 OUString
aElem( GetExport().GetNamespaceMap().GetQNameByKey(
1164 GetXMLToken(XML_LIST_ITEM
) ) );
1165 GetExport().IgnorableWhitespace();
1166 GetExport().StartElement(aElem
, false );
1167 maListElements
.push_back(aElem
);
1169 // export of <text:number> element for <text:list-item>, if requested
1170 if ( GetExport().exportTextNumberElement() &&
1171 !rNextInfo
.ListLabelString().isEmpty() )
1173 const OUString aTextNumberElem
=
1174 GetExport().GetNamespaceMap().GetQNameByKey(
1176 GetXMLToken(XML_NUMBER
) );
1177 GetExport().IgnorableWhitespace();
1178 GetExport().StartElement( aTextNumberElem
, false );
1179 GetExport().Characters( rNextInfo
.ListLabelString() );
1180 GetExport().EndElement( aTextNumberElem
, true );
1185 struct XMLTextParagraphExport::Impl
1187 typedef ::std::map
<Reference
<XFormField
>, sal_Int32
> FieldMarkMap_t
;
1188 FieldMarkMap_t m_FieldMarkMap
;
1191 sal_Int32
AddFieldMarkStart(Reference
<XFormField
> const& i_xFieldMark
)
1193 assert(m_FieldMarkMap
.find(i_xFieldMark
) == m_FieldMarkMap
.end());
1194 sal_Int32
const ret(m_FieldMarkMap
.size());
1195 m_FieldMarkMap
.insert(::std::make_pair(i_xFieldMark
, ret
));
1198 sal_Int32
GetFieldMarkIndex(Reference
<XFormField
> const& i_xFieldMark
)
1200 FieldMarkMap_t::const_iterator
const it(
1201 m_FieldMarkMap
.find(i_xFieldMark
));
1202 // rely on SwXFieldmark::CreateXFieldmark returning the same instance
1203 // because the Reference in m_FieldMarkMap will keep it alive
1204 assert(it
!= m_FieldMarkMap
.end());
1209 XMLTextParagraphExport::XMLTextParagraphExport(
1211 SvXMLAutoStylePoolP
& rASP
1213 XMLStyleExport( rExp
, &rASP
),
1215 rAutoStylePool( rASP
),
1216 pBoundFrameSets(new BoundFrameSets(GetExport().GetModel())),
1217 maListAutoPool( GetExport() ),
1221 mpTextListsHelper( nullptr ),
1223 aCharStyleNamesPropInfoCache( gsCharStyleNames
)
1225 rtl::Reference
< XMLPropertySetMapper
> xPropMapper(new XMLTextPropertySetMapper( TextPropMap::PARA
, true ));
1226 xParaPropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1229 OUString
sFamily( GetXMLToken(XML_PARAGRAPH
) );
1230 OUString
aPrefix(u
'P');
1231 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_PARAGRAPH
, sFamily
,
1232 xParaPropMapper
, aPrefix
);
1234 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::TEXT
, true );
1235 xTextPropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1237 sFamily
= GetXMLToken(XML_TEXT
);
1239 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_TEXT
, sFamily
,
1240 xTextPropMapper
, aPrefix
);
1242 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::AUTO_FRAME
, true );
1243 xAutoFramePropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1245 sFamily
= XML_STYLE_FAMILY_SD_GRAPHICS_NAME
;
1247 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_FRAME
, sFamily
,
1248 xAutoFramePropMapper
, aPrefix
);
1250 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::SECTION
, true );
1251 xSectionPropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1253 sFamily
= GetXMLToken( XML_SECTION
);
1255 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_SECTION
, sFamily
,
1256 xSectionPropMapper
, aPrefix
);
1258 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::RUBY
, true );
1259 xRubyPropMapper
= new SvXMLExportPropertyMapper( xPropMapper
);
1260 sFamily
= GetXMLToken( XML_RUBY
);
1262 rAutoStylePool
.AddFamily( XmlStyleFamily::TEXT_RUBY
, sFamily
,
1263 xRubyPropMapper
, aPrefix
);
1265 xPropMapper
= new XMLTextPropertySetMapper( TextPropMap::FRAME
, true );
1266 xFramePropMapper
= new XMLTextExportPropertySetMapper( xPropMapper
,
1269 pSectionExport
.reset( new XMLSectionExport( rExp
, *this ) );
1270 pIndexMarkExport
.reset( new XMLIndexMarkExport( rExp
) );
1272 if( ! IsBlockMode() &&
1273 Reference
<XRedlinesSupplier
>( GetExport().GetModel(), UNO_QUERY
).is())
1274 pRedlineExport
.reset( new XMLRedlineExport( rExp
) );
1276 // The text field helper needs a pre-constructed XMLPropertyState
1277 // to export the combined characters field. We construct that
1278 // here, because we need the text property mapper to do it.
1280 // construct Any value, then find index
1281 sal_Int32 nIndex
= xTextPropMapper
->getPropertySetMapper()->FindEntryIndex(
1282 "", XML_NAMESPACE_STYLE
,
1283 GetXMLToken(XML_TEXT_COMBINE
));
1284 pFieldExport
.reset( new XMLTextFieldExport( rExp
, std::make_unique
<XMLPropertyState
>( nIndex
, uno::makeAny(true) ) ) );
1285 PushNewTextListsHelper();
1288 XMLTextParagraphExport::~XMLTextParagraphExport()
1290 pRedlineExport
.reset();
1291 pIndexMarkExport
.reset();
1292 pSectionExport
.reset();
1293 pFieldExport
.reset();
1295 txtparae_bContainsIllegalCharacters
= false;
1297 PopTextListsHelper();
1298 SAL_WARN_IF( !maTextListsHelperStack
.empty(), "xmloff",
1299 "misusage of text lists helper stack - it is not empty. Serious defect" );
1302 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateShapeExtPropMapper(
1303 SvXMLExport
& rExport
)
1305 rtl::Reference
< XMLPropertySetMapper
> xPropMapper
=
1306 new XMLTextPropertySetMapper( TextPropMap::SHAPE
, true );
1307 return new XMLTextExportPropertySetMapper( xPropMapper
, rExport
);
1310 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateCharExtPropMapper(
1311 SvXMLExport
& rExport
)
1313 XMLPropertySetMapper
*pPropMapper
=
1314 new XMLTextPropertySetMapper( TextPropMap::TEXT
, true );
1315 return new XMLTextExportPropertySetMapper( pPropMapper
, rExport
);
1318 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateParaExtPropMapper(
1319 SvXMLExport
& rExport
)
1321 XMLPropertySetMapper
*pPropMapper
=
1322 new XMLTextPropertySetMapper( TextPropMap::SHAPE_PARA
, true );
1323 return new XMLTextExportPropertySetMapper( pPropMapper
, rExport
);
1326 SvXMLExportPropertyMapper
*XMLTextParagraphExport::CreateParaDefaultExtPropMapper(
1327 SvXMLExport
& rExport
)
1329 XMLPropertySetMapper
*pPropMapper
=
1330 new XMLTextPropertySetMapper( TextPropMap::TEXT_ADDITIONAL_DEFAULTS
, true );
1331 return new XMLTextExportPropertySetMapper( pPropMapper
, rExport
);
1334 void XMLTextParagraphExport::exportPageFrames( bool bIsProgress
)
1336 const TextContentSet
& rTexts
= pBoundFrameSets
->GetTexts()->GetPageBoundContents();
1337 const TextContentSet
& rGraphics
= pBoundFrameSets
->GetGraphics()->GetPageBoundContents();
1338 const TextContentSet
& rEmbeddeds
= pBoundFrameSets
->GetEmbeddeds()->GetPageBoundContents();
1339 const TextContentSet
& rShapes
= pBoundFrameSets
->GetShapes()->GetPageBoundContents();
1340 for(TextContentSet::const_iterator_t it
= rTexts
.getBegin();
1341 it
!= rTexts
.getEnd();
1343 exportTextFrame(*it
, false/*bAutoStyles*/, bIsProgress
, true);
1344 for(TextContentSet::const_iterator_t it
= rGraphics
.getBegin();
1345 it
!= rGraphics
.getEnd();
1347 exportTextGraphic(*it
, false/*bAutoStyles*/);
1348 for(TextContentSet::const_iterator_t it
= rEmbeddeds
.getBegin();
1349 it
!= rEmbeddeds
.getEnd();
1351 exportTextEmbedded(*it
, false/*bAutoStyles*/);
1352 for(TextContentSet::const_iterator_t it
= rShapes
.getBegin();
1353 it
!= rShapes
.getEnd();
1355 exportShape(*it
, false/*bAutoStyles*/);
1358 void XMLTextParagraphExport::exportFrameFrames(
1361 const Reference
< XTextFrame
> *pParentTxtFrame
)
1363 const TextContentSet
* const pTexts
= pBoundFrameSets
->GetTexts()->GetFrameBoundContents(*pParentTxtFrame
);
1365 for(TextContentSet::const_iterator_t it
= pTexts
->getBegin();
1366 it
!= pTexts
->getEnd();
1368 exportTextFrame(*it
, bAutoStyles
, bIsProgress
, true);
1369 const TextContentSet
* const pGraphics
= pBoundFrameSets
->GetGraphics()->GetFrameBoundContents(*pParentTxtFrame
);
1371 for(TextContentSet::const_iterator_t it
= pGraphics
->getBegin();
1372 it
!= pGraphics
->getEnd();
1374 exportTextGraphic(*it
, bAutoStyles
);
1375 const TextContentSet
* const pEmbeddeds
= pBoundFrameSets
->GetEmbeddeds()->GetFrameBoundContents(*pParentTxtFrame
);
1377 for(TextContentSet::const_iterator_t it
= pEmbeddeds
->getBegin();
1378 it
!= pEmbeddeds
->getEnd();
1380 exportTextEmbedded(*it
, bAutoStyles
);
1381 const TextContentSet
* const pShapes
= pBoundFrameSets
->GetShapes()->GetFrameBoundContents(*pParentTxtFrame
);
1383 for(TextContentSet::const_iterator_t it
= pShapes
->getBegin();
1384 it
!= pShapes
->getEnd();
1386 exportShape(*it
, bAutoStyles
);
1389 // bookmarks, reference marks (and TOC marks) are the same except for the
1390 // element names. We use the same method for export and it an array with
1391 // the proper element names
1392 const enum XMLTokenEnum lcl_XmlReferenceElements
[] = {
1393 XML_REFERENCE_MARK
, XML_REFERENCE_MARK_START
, XML_REFERENCE_MARK_END
};
1394 const enum XMLTokenEnum lcl_XmlBookmarkElements
[] = {
1395 XML_BOOKMARK
, XML_BOOKMARK_START
, XML_BOOKMARK_END
};
1397 // This function replaces the text portion iteration during auto style
1399 void XMLTextParagraphExport::collectTextAutoStylesOptimized( bool bIsProgress
)
1401 GetExport().GetShapeExport(); // make sure the graphics styles family is added
1406 const bool bAutoStyles
= true;
1407 const bool bExportContent
= false;
1409 // Export AutoStyles:
1410 Reference
< XAutoStylesSupplier
> xAutoStylesSupp( GetExport().GetModel(), UNO_QUERY
);
1411 if ( xAutoStylesSupp
.is() )
1413 Reference
< XAutoStyles
> xAutoStyleFamilies
= xAutoStylesSupp
->getAutoStyles();
1414 const auto collectFamily
= [this, &xAutoStyleFamilies
](const OUString
& sName
,
1415 XmlStyleFamily nFamily
) {
1416 Any aAny
= xAutoStyleFamilies
->getByName( sName
);
1417 Reference
< XAutoStyleFamily
> xAutoStyles
= *o3tl::doAccess
<Reference
<XAutoStyleFamily
>>(aAny
);
1418 Reference
< XEnumeration
> xAutoStylesEnum( xAutoStyles
->createEnumeration() );
1420 while ( xAutoStylesEnum
->hasMoreElements() )
1422 aAny
= xAutoStylesEnum
->nextElement();
1423 Reference
< XAutoStyle
> xAutoStyle
= *o3tl::doAccess
<Reference
<XAutoStyle
>>(aAny
);
1424 Reference
< XPropertySet
> xPSet( xAutoStyle
, uno::UNO_QUERY
);
1425 Add( nFamily
, xPSet
, {}, true );
1428 collectFamily("CharacterStyles", XmlStyleFamily::TEXT_TEXT
);
1429 collectFamily("RubyStyles", XmlStyleFamily::TEXT_RUBY
);
1430 collectFamily("ParagraphStyles", XmlStyleFamily::TEXT_PARAGRAPH
);
1433 // Export Field AutoStyles:
1434 Reference
< XTextFieldsSupplier
> xTextFieldsSupp( GetExport().GetModel(), UNO_QUERY
);
1435 if ( xTextFieldsSupp
.is() )
1437 Reference
< XEnumerationAccess
> xTextFields
= xTextFieldsSupp
->getTextFields();
1438 Reference
< XEnumeration
> xTextFieldsEnum( xTextFields
->createEnumeration() );
1440 while ( xTextFieldsEnum
->hasMoreElements() )
1442 Any aAny
= xTextFieldsEnum
->nextElement();
1443 Reference
< XTextField
> xTextField
= *o3tl::doAccess
<Reference
<XTextField
>>(aAny
);
1444 exportTextField( xTextField
, bAutoStyles
, bIsProgress
,
1445 !xAutoStylesSupp
.is(), nullptr );
1448 Reference
< XPropertySet
> xSet( xTextField
, UNO_QUERY
);
1449 Reference
< XText
> xText
;
1450 Any a
= xSet
->getPropertyValue("TextRange");
1454 exportText( xText
, true, bIsProgress
, bExportContent
);
1455 GetExport().GetTextParagraphExport()
1456 ->collectTextAutoStyles( xText
);
1465 // Export text frames:
1466 Reference
<XEnumeration
> xTextFramesEnum
= pBoundFrameSets
->GetTexts()->createEnumeration();
1467 if(xTextFramesEnum
.is())
1468 while(xTextFramesEnum
->hasMoreElements())
1470 Reference
<XTextContent
> xTxtCntnt(xTextFramesEnum
->nextElement(), UNO_QUERY
);
1472 exportTextFrame(xTxtCntnt
, bAutoStyles
, bIsProgress
, bExportContent
);
1475 // Export graphic objects:
1476 Reference
<XEnumeration
> xGraphicsEnum
= pBoundFrameSets
->GetGraphics()->createEnumeration();
1477 if(xGraphicsEnum
.is())
1478 while(xGraphicsEnum
->hasMoreElements())
1480 Reference
<XTextContent
> xTxtCntnt(xGraphicsEnum
->nextElement(), UNO_QUERY
);
1482 exportTextGraphic(xTxtCntnt
, true);
1485 // Export embedded objects:
1486 Reference
<XEnumeration
> xEmbeddedsEnum
= pBoundFrameSets
->GetEmbeddeds()->createEnumeration();
1487 if(xEmbeddedsEnum
.is())
1488 while(xEmbeddedsEnum
->hasMoreElements())
1490 Reference
<XTextContent
> xTxtCntnt(xEmbeddedsEnum
->nextElement(), UNO_QUERY
);
1492 exportTextEmbedded(xTxtCntnt
, true);
1496 Reference
<XEnumeration
> xShapesEnum
= pBoundFrameSets
->GetShapes()->createEnumeration();
1497 if(xShapesEnum
.is())
1498 while(xShapesEnum
->hasMoreElements())
1500 Reference
<XTextContent
> xTxtCntnt(xShapesEnum
->nextElement(), UNO_QUERY
);
1503 Reference
<XServiceInfo
> xServiceInfo(xTxtCntnt
, UNO_QUERY
);
1504 if( xServiceInfo
->supportsService(gsShapeService
))
1505 exportShape(xTxtCntnt
, true);
1510 // AutoStyles for sections
1511 Reference
< XTextSectionsSupplier
> xSectionsSupp( GetExport().GetModel(), UNO_QUERY
);
1512 if ( xSectionsSupp
.is() )
1514 Reference
< XIndexAccess
> xSections( xSectionsSupp
->getTextSections(), UNO_QUERY
);
1515 if ( xSections
.is() )
1517 nCount
= xSections
->getCount();
1518 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
1520 Any aAny
= xSections
->getByIndex( i
);
1521 Reference
< XTextSection
> xSection
= *o3tl::doAccess
<Reference
<XTextSection
>>(aAny
);
1522 Reference
< XPropertySet
> xPSet( xSection
, uno::UNO_QUERY
);
1523 Add( XmlStyleFamily::TEXT_SECTION
, xPSet
);
1528 // AutoStyles for tables (Note: suppress autostyle collection for paragraphs in exportTable)
1529 Reference
< XTextTablesSupplier
> xTablesSupp( GetExport().GetModel(), UNO_QUERY
);
1530 if ( xTablesSupp
.is() )
1532 Reference
< XIndexAccess
> xTables( xTablesSupp
->getTextTables(), UNO_QUERY
);
1535 nCount
= xTables
->getCount();
1536 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
1538 Any aAny
= xTables
->getByIndex( i
);
1539 Reference
< XTextTable
> xTable
= *o3tl::doAccess
<Reference
<XTextTable
>>(aAny
);
1540 exportTable( xTable
, true, true );
1545 Reference
< XNumberingRulesSupplier
> xNumberingRulesSupp( GetExport().GetModel(), UNO_QUERY
);
1546 if ( xNumberingRulesSupp
.is() )
1548 Reference
< XIndexAccess
> xNumberingRules
= xNumberingRulesSupp
->getNumberingRules();
1549 nCount
= xNumberingRules
->getCount();
1550 // Custom outline assignment lost after re-importing sxw (#i73361#)
1551 for( sal_Int32 i
= 0; i
< nCount
; ++i
)
1553 Reference
< XIndexReplace
> xNumRule( xNumberingRules
->getByIndex( i
), UNO_QUERY
);
1554 if( xNumRule
.is() && xNumRule
->getCount() )
1556 Reference
< XNamed
> xNamed( xNumRule
, UNO_QUERY
);
1559 sName
= xNamed
->getName();
1560 bool bAdd
= sName
.isEmpty();
1563 Reference
< XPropertySet
> xNumPropSet( xNumRule
,
1565 if( xNumPropSet
.is() &&
1566 xNumPropSet
->getPropertySetInfo()
1567 ->hasPropertyByName( "IsAutomatic" ) )
1569 bAdd
= *o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "IsAutomatic" ));
1570 // Check on outline style (#i73361#)
1572 xNumPropSet
->getPropertySetInfo()
1573 ->hasPropertyByName( "NumberingIsOutline" ) )
1575 bAdd
= !(*o3tl::doAccess
<bool>(xNumPropSet
->getPropertyValue( "NumberingIsOutline" )));
1584 maListAutoPool
.Add( xNumRule
);
1591 void XMLTextParagraphExport::exportText(
1592 const Reference
< XText
> & rText
,
1595 bool bExportParagraph
,
1596 TextPNS eExtensionNS
)
1599 GetExport().GetShapeExport(); // make sure the graphics styles family
1601 Reference
< XEnumerationAccess
> xEA( rText
, UNO_QUERY
);
1605 Reference
< XEnumeration
> xParaEnum(xEA
->createEnumeration());
1606 Reference
< XPropertySet
> xPropertySet( rText
, UNO_QUERY
);
1607 Reference
< XTextSection
> xBaseSection
;
1609 // #97718# footnotes don't supply paragraph enumerations in some cases
1610 // This is always a bug, but at least we don't want to crash.
1611 SAL_WARN_IF( !xParaEnum
.is(), "xmloff", "We need a paragraph enumeration" );
1612 if( ! xParaEnum
.is() )
1615 if (xPropertySet
.is())
1617 Reference
< XPropertySetInfo
> xInfo ( xPropertySet
->getPropertySetInfo() );
1621 if (xInfo
->hasPropertyByName( gsTextSection
))
1623 xPropertySet
->getPropertyValue(gsTextSection
) >>= xBaseSection
;
1628 // #96530# Export redlines at start & end of XText before & after
1629 // exporting the text content enumeration
1630 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1631 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, true );
1632 exportTextContentEnumeration( xParaEnum
, bAutoStyles
, xBaseSection
,
1633 bIsProgress
, bExportParagraph
, nullptr, eExtensionNS
);
1634 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1635 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, false );
1638 void XMLTextParagraphExport::exportText(
1639 const Reference
< XText
> & rText
,
1640 const Reference
< XTextSection
> & rBaseSection
,
1643 bool bExportParagraph
)
1646 GetExport().GetShapeExport(); // make sure the graphics styles family
1648 Reference
< XEnumerationAccess
> xEA( rText
, UNO_QUERY
);
1649 Reference
< XEnumeration
> xParaEnum(xEA
->createEnumeration());
1651 // #98165# don't continue without a paragraph enumeration
1652 if( ! xParaEnum
.is() )
1655 // #96530# Export redlines at start & end of XText before & after
1656 // exporting the text content enumeration
1657 Reference
<XPropertySet
> xPropertySet
;
1658 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1660 xPropertySet
.set(rText
, uno::UNO_QUERY
);
1661 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, true );
1663 exportTextContentEnumeration( xParaEnum
, bAutoStyles
, rBaseSection
,
1664 bIsProgress
, bExportParagraph
);
1665 if( !bAutoStyles
&& (pRedlineExport
!= nullptr) )
1666 pRedlineExport
->ExportStartOrEndRedline( xPropertySet
, false );
1669 void XMLTextParagraphExport::exportTextContentEnumeration(
1670 const Reference
< XEnumeration
> & rContEnum
,
1672 const Reference
< XTextSection
> & rBaseSection
,
1674 bool bExportParagraph
,
1675 const Reference
< XPropertySet
> *pRangePropSet
,
1676 TextPNS eExtensionNS
)
1678 SAL_WARN_IF( !rContEnum
.is(), "xmloff", "No enumeration to export!" );
1679 bool bHasMoreElements
= rContEnum
->hasMoreElements();
1680 if( !bHasMoreElements
)
1683 XMLTextNumRuleInfo aPrevNumInfo
;
1684 XMLTextNumRuleInfo aNextNumInfo
;
1686 bool bHasContent
= false;
1687 Reference
<XTextSection
> xCurrentTextSection(rBaseSection
);
1689 MultiPropertySetHelper
aPropSetHelper(
1690 bAutoStyles
? aParagraphPropertyNamesAuto
:
1691 aParagraphPropertyNames
);
1693 bool bHoldElement
= false;
1694 Reference
< XTextContent
> xTxtCntnt
;
1695 while( bHoldElement
|| bHasMoreElements
)
1699 bHoldElement
= false;
1703 xTxtCntnt
.set(rContEnum
->nextElement(), uno::UNO_QUERY
);
1705 aPropSetHelper
.resetValues();
1709 Reference
<XServiceInfo
> xServiceInfo( xTxtCntnt
, UNO_QUERY
);
1710 if( xServiceInfo
->supportsService( gsParagraphService
) )
1714 exportListAndSectionChange( xCurrentTextSection
, xTxtCntnt
,
1715 aPrevNumInfo
, aNextNumInfo
,
1720 /* Pass list auto style pool to <XMLTextNumRuleInfo> instance
1721 Pass info about request to export <text:number> element
1722 to <XMLTextNumRuleInfo> instance (#i69627#)
1724 aNextNumInfo
.Set( xTxtCntnt
,
1725 GetExport().writeOutlineStyleAsNormalListStyle(),
1726 GetListAutoStylePool(),
1727 GetExport().exportTextNumberElement() );
1729 exportListAndSectionChange( xCurrentTextSection
, aPropSetHelper
,
1730 TEXT_SECTION
, xTxtCntnt
,
1731 aPrevNumInfo
, aNextNumInfo
,
1735 // if we found a mute section: skip all section content
1736 if (pSectionExport
->IsMuteSection(xCurrentTextSection
))
1738 // Make sure headings are exported anyway.
1740 pSectionExport
->ExportMasterDocHeadingDummies();
1742 while (rContEnum
->hasMoreElements() &&
1743 XMLSectionExport::IsInSection( xCurrentTextSection
,
1746 xTxtCntnt
.set(rContEnum
->nextElement(), uno::UNO_QUERY
);
1747 aPropSetHelper
.resetValues();
1748 aNextNumInfo
.Reset();
1750 // the first non-mute element still needs to be processed
1752 ! XMLSectionExport::IsInSection( xCurrentTextSection
,
1756 exportParagraph( xTxtCntnt
, bAutoStyles
, bIsProgress
,
1757 bExportParagraph
, aPropSetHelper
, eExtensionNS
);
1760 else if( xServiceInfo
->supportsService( gsTableService
) )
1764 aNextNumInfo
.Reset();
1767 exportListAndSectionChange( xCurrentTextSection
, xTxtCntnt
,
1768 aPrevNumInfo
, aNextNumInfo
,
1771 if (! pSectionExport
->IsMuteSection(xCurrentTextSection
))
1773 // export start + end redlines (for wholly redlined tables)
1774 if ((! bAutoStyles
) && (nullptr != pRedlineExport
))
1775 pRedlineExport
->ExportStartOrEndRedline(xTxtCntnt
, true);
1777 exportTable( xTxtCntnt
, bAutoStyles
, bIsProgress
);
1779 if ((! bAutoStyles
) && (nullptr != pRedlineExport
))
1780 pRedlineExport
->ExportStartOrEndRedline(xTxtCntnt
, false);
1782 else if( !bAutoStyles
)
1784 // Make sure headings are exported anyway.
1785 pSectionExport
->ExportMasterDocHeadingDummies();
1790 else if( xServiceInfo
->supportsService( gsTextFrameService
) )
1792 exportTextFrame( xTxtCntnt
, bAutoStyles
, bIsProgress
, true, pRangePropSet
);
1794 else if( xServiceInfo
->supportsService( gsTextGraphicService
) )
1796 exportTextGraphic( xTxtCntnt
, bAutoStyles
, pRangePropSet
);
1798 else if( xServiceInfo
->supportsService( gsTextEmbeddedService
) )
1800 exportTextEmbedded( xTxtCntnt
, bAutoStyles
, pRangePropSet
);
1802 else if( xServiceInfo
->supportsService( gsShapeService
) )
1804 exportShape( xTxtCntnt
, bAutoStyles
, pRangePropSet
);
1808 SAL_WARN_IF( xTxtCntnt
.is(), "xmloff", "unknown text content" );
1813 aPrevNumInfo
= aNextNumInfo
;
1816 bHasMoreElements
= rContEnum
->hasMoreElements();
1819 if( bHasContent
&& !bAutoStyles
)
1821 aNextNumInfo
.Reset();
1823 // close open lists and sections; no new styles
1824 exportListAndSectionChange( xCurrentTextSection
, rBaseSection
,
1825 aPrevNumInfo
, aNextNumInfo
,
1830 void XMLTextParagraphExport::exportParagraph(
1831 const Reference
< XTextContent
> & rTextContent
,
1832 bool bAutoStyles
, bool bIsProgress
, bool bExportParagraph
,
1833 MultiPropertySetHelper
& rPropSetHelper
, TextPNS eExtensionNS
)
1835 sal_Int16 nOutlineLevel
= -1;
1839 ProgressBarHelper
*pProgress
= GetExport().GetProgressBarHelper();
1840 pProgress
->SetValue( pProgress
->GetValue()+1 );
1843 // get property set or multi property set and initialize helper
1844 Reference
<XMultiPropertySet
> xMultiPropSet( rTextContent
, UNO_QUERY
);
1845 Reference
<XPropertySet
> xPropSet( rTextContent
, UNO_QUERY
);
1847 // check for supported properties
1848 if( !rPropSetHelper
.checkedProperties() )
1849 rPropSetHelper
.hasProperties( xPropSet
->getPropertySetInfo() );
1851 // if( xMultiPropSet.is() )
1852 // rPropSetHelper.getValues( xMultiPropSet );
1854 // rPropSetHelper.getValues( xPropSet );
1856 if( bExportParagraph
)
1860 Add( XmlStyleFamily::TEXT_PARAGRAPH
, rPropSetHelper
, xPropSet
);
1864 // xml:id for RDF metadata
1865 GetExport().AddAttributeXmlId(rTextContent
);
1866 GetExport().AddAttributesRDFa(rTextContent
);
1869 if( rPropSetHelper
.hasProperty( PARA_STYLE_NAME
) )
1871 if( xMultiPropSet
.is() )
1872 rPropSetHelper
.getValue( PARA_STYLE_NAME
,
1873 xMultiPropSet
) >>= sStyle
;
1875 rPropSetHelper
.getValue( PARA_STYLE_NAME
,
1876 xPropSet
) >>= sStyle
;
1879 if( rTextContent
.is() )
1881 const OUString
& rIdentifier
= GetExport().getInterfaceToIdentifierMapper().getIdentifier( rTextContent
);
1882 if( !rIdentifier
.isEmpty() )
1884 // FIXME: this is just temporary until EditEngine
1885 // paragraphs implement XMetadatable.
1886 // then that must be used and not the mapper, because
1887 // when both can be used we get two xml:id!
1888 uno::Reference
<rdf::XMetadatable
> const xMeta(rTextContent
,
1890 OSL_ENSURE(!xMeta
.is(), "paragraph that implements "
1891 "XMetadatable used in interfaceToIdentifierMapper?");
1892 GetExport().AddAttributeIdLegacy(XML_NAMESPACE_TEXT
,
1897 OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_PARAGRAPH
, xPropSet
, sStyle
);
1898 if ( sAutoStyle
.isEmpty() )
1899 sAutoStyle
= sStyle
;
1900 if( !sAutoStyle
.isEmpty() )
1901 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
1902 GetExport().EncodeStyleName( sAutoStyle
) );
1904 if( rPropSetHelper
.hasProperty( PARA_CONDITIONAL_STYLE_NAME
) )
1906 OUString sCondStyle
;
1907 if( xMultiPropSet
.is() )
1908 rPropSetHelper
.getValue( PARA_CONDITIONAL_STYLE_NAME
,
1909 xMultiPropSet
) >>= sCondStyle
;
1911 rPropSetHelper
.getValue( PARA_CONDITIONAL_STYLE_NAME
,
1912 xPropSet
) >>= sCondStyle
;
1913 if( sCondStyle
!= sStyle
)
1915 sCondStyle
= Find( XmlStyleFamily::TEXT_PARAGRAPH
, xPropSet
,
1917 if( !sCondStyle
.isEmpty() )
1918 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1919 XML_COND_STYLE_NAME
,
1920 GetExport().EncodeStyleName( sCondStyle
) );
1924 if( rPropSetHelper
.hasProperty( PARA_OUTLINE_LEVEL
) )
1926 if( xMultiPropSet
.is() )
1927 rPropSetHelper
.getValue( PARA_OUTLINE_LEVEL
,
1928 xMultiPropSet
) >>= nOutlineLevel
;
1930 rPropSetHelper
.getValue( PARA_OUTLINE_LEVEL
,
1931 xPropSet
) >>= nOutlineLevel
;
1933 if( 0 < nOutlineLevel
)
1935 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
1937 OUString::number( sal_Int32( nOutlineLevel
) ) );
1939 if ( rPropSetHelper
.hasProperty( PARA_OUTLINE_CONTENT_VISIBLE
) )
1941 uno::Sequence
<beans::PropertyValue
> propList
;
1942 bool bIsOutlineContentVisible
= true;
1943 if( xMultiPropSet
.is() )
1944 rPropSetHelper
.getValue(
1945 PARA_OUTLINE_CONTENT_VISIBLE
, xMultiPropSet
) >>= propList
;
1947 rPropSetHelper
.getValue(
1948 PARA_OUTLINE_CONTENT_VISIBLE
, xPropSet
) >>= propList
;
1949 for (const auto& rProp
: std::as_const(propList
))
1951 OUString propName
= rProp
.Name
;
1952 if (propName
== "OutlineContentVisibleAttr")
1954 rProp
.Value
>>= bIsOutlineContentVisible
;
1958 if (!bIsOutlineContentVisible
)
1960 GetExport().AddAttribute( XML_NAMESPACE_LO_EXT
,
1961 XML_OUTLINE_CONTENT_VISIBLE
,
1966 if( rPropSetHelper
.hasProperty( NUMBERING_IS_NUMBER
) )
1968 bool bIsNumber
= false;
1969 if( xMultiPropSet
.is() )
1970 rPropSetHelper
.getValue(
1971 NUMBERING_IS_NUMBER
, xMultiPropSet
) >>= bIsNumber
;
1973 rPropSetHelper
.getValue(
1974 NUMBERING_IS_NUMBER
, xPropSet
) >>= bIsNumber
;
1976 OUString sListStyleName
;
1977 if( xMultiPropSet
.is() )
1978 rPropSetHelper
.getValue(
1979 PARA_NUMBERING_STYLENAME
, xMultiPropSet
) >>= sListStyleName
;
1981 rPropSetHelper
.getValue(
1982 PARA_NUMBERING_STYLENAME
, xPropSet
) >>= sListStyleName
;
1984 bool bAssignedtoOutlineStyle
= false;
1986 Reference
< XChapterNumberingSupplier
> xCNSupplier( GetExport().GetModel(), UNO_QUERY
);
1988 if (xCNSupplier
.is())
1990 Reference
< XIndexReplace
> xNumRule ( xCNSupplier
->getChapterNumberingRules() );
1991 SAL_WARN_IF( !xNumRule
.is(), "xmloff", "no chapter numbering rules" );
1995 Reference
< XPropertySet
> xNumRulePropSet( xNumRule
, UNO_QUERY
);
1996 OUString sOutlineName
;
1997 xNumRulePropSet
->getPropertyValue(
1998 "Name" ) >>= sOutlineName
;
1999 bAssignedtoOutlineStyle
= ( sListStyleName
== sOutlineName
);
2004 if( ! bIsNumber
&& bAssignedtoOutlineStyle
)
2005 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
2011 bool bIsRestartNumbering
= false;
2013 Reference
< XPropertySetInfo
>
2014 xPropSetInfo(xMultiPropSet
.is() ?
2015 xMultiPropSet
->getPropertySetInfo():
2016 xPropSet
->getPropertySetInfo());
2019 hasPropertyByName("ParaIsNumberingRestart"))
2021 xPropSet
->getPropertyValue("ParaIsNumberingRestart")
2022 >>= bIsRestartNumbering
;
2025 if (bIsRestartNumbering
)
2027 GetExport().AddAttribute(XML_NAMESPACE_TEXT
,
2028 XML_RESTART_NUMBERING
,
2032 hasPropertyByName("NumberingStartValue"))
2034 sal_Int32 nStartValue
= 0;
2036 xPropSet
->getPropertyValue("NumberingStartValue")
2040 AddAttribute(XML_NAMESPACE_TEXT
,
2042 OUString::number(nStartValue
));
2051 Reference
< XEnumerationAccess
> xEA( rTextContent
, UNO_QUERY
);
2052 Reference
< XEnumeration
> xTextEnum
= xEA
->createEnumeration();
2053 const bool bHasPortions
= xTextEnum
.is();
2055 Reference
< XEnumeration
> xContentEnum
;
2056 Reference
< XContentEnumerationAccess
> xCEA( rTextContent
, UNO_QUERY
);
2058 xContentEnum
.set(xCEA
->createContentEnumeration( gsTextContentService
));
2059 const bool bHasContentEnum
= xContentEnum
.is() &&
2060 xContentEnum
->hasMoreElements();
2062 Reference
< XTextSection
> xSection
;
2063 if( bHasContentEnum
)
2065 // For the auto styles, the multi property set helper is only used
2066 // if hard attributes are existing. Therefore, it seems to be a better
2067 // strategy to have the TextSection property separate, because otherwise
2068 // we always retrieve the style names even if they are not required.
2071 if( xPropSet
->getPropertySetInfo()->hasPropertyByName( gsTextSection
) )
2073 xSection
.set(xPropSet
->getPropertyValue( gsTextSection
), uno::UNO_QUERY
);
2078 if( rPropSetHelper
.hasProperty( TEXT_SECTION
) )
2080 xSection
.set(rPropSetHelper
.getValue( TEXT_SECTION
), uno::UNO_QUERY
);
2085 bool bPrevCharIsSpace(true); // true because whitespace at start is ignored
2089 if( bHasContentEnum
)
2090 exportTextContentEnumeration(
2091 xContentEnum
, bAutoStyles
, xSection
,
2095 exportTextRangeEnumeration(xTextEnum
, bAutoStyles
, bIsProgress
, bPrevCharIsSpace
);
2100 enum XMLTokenEnum eElem
=
2101 0 < nOutlineLevel
? XML_H
: XML_P
;
2102 SvXMLElementExport
aElem( GetExport(), eExtensionNS
== TextPNS::EXTENSION
? XML_NAMESPACE_LO_EXT
: XML_NAMESPACE_TEXT
, eElem
,
2104 if( bHasContentEnum
)
2106 exportTextContentEnumeration(
2107 xContentEnum
, bAutoStyles
, xSection
,
2110 exportTextRangeEnumeration(xTextEnum
, bAutoStyles
, bIsProgress
, bPrevCharIsSpace
);
2114 void XMLTextParagraphExport::exportTextRangeEnumeration(
2115 const Reference
< XEnumeration
> & rTextEnum
,
2116 bool bAutoStyles
, bool bIsProgress
,
2117 bool & rPrevCharIsSpace
)
2119 static const char sFieldMarkName
[] = "__FieldMark_";
2121 /* This is used for exporting to strict OpenDocument 1.2, in which case traditional
2122 * bookmarks are used instead of fieldmarks. */
2123 FieldmarkType openFieldMark
= NONE
;
2125 while( rTextEnum
->hasMoreElements() )
2127 Reference
<XPropertySet
> xPropSet(rTextEnum
->nextElement(), UNO_QUERY
);
2128 Reference
< XTextRange
> xTxtRange(xPropSet
, uno::UNO_QUERY
);
2129 Reference
<XPropertySetInfo
> xPropInfo(xPropSet
->getPropertySetInfo());
2131 if (xPropInfo
->hasPropertyByName(gsTextPortionType
))
2134 xPropSet
->getPropertyValue(gsTextPortionType
) >>= sType
;
2136 if( sType
== gsText
)
2138 exportTextRange( xTxtRange
, bAutoStyles
,
2139 rPrevCharIsSpace
, openFieldMark
);
2141 else if( sType
== gsTextField
)
2143 exportTextField(xTxtRange
, bAutoStyles
, bIsProgress
, &rPrevCharIsSpace
);
2145 else if ( sType
== "Annotation" )
2147 exportTextField(xTxtRange
, bAutoStyles
, bIsProgress
, &rPrevCharIsSpace
);
2149 else if ( sType
== "AnnotationEnd" )
2153 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2154 const OUString
& rName
= xBookmark
->getName();
2155 if (!rName
.isEmpty())
2157 GetExport().AddAttribute(XML_NAMESPACE_OFFICE
, XML_NAME
, rName
);
2159 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_OFFICE
, XML_ANNOTATION_END
, false, false );
2162 else if( sType
== gsFrame
)
2164 Reference
< XEnumeration
> xContentEnum
;
2165 Reference
< XContentEnumerationAccess
> xCEA( xTxtRange
,
2168 xContentEnum
.set(xCEA
->createContentEnumeration(
2169 gsTextContentService
));
2170 // frames are never in sections
2171 Reference
<XTextSection
> xSection
;
2172 if( xContentEnum
.is() )
2173 exportTextContentEnumeration( xContentEnum
,
2175 xSection
, bIsProgress
, true,
2179 else if (sType
== gsFootnote
)
2181 exportTextFootnote(xPropSet
,
2182 xTxtRange
->getString(),
2183 bAutoStyles
, bIsProgress
);
2185 else if (sType
== gsBookmark
)
2187 exportTextMark(xPropSet
,
2189 lcl_XmlBookmarkElements
,
2192 else if (sType
== gsReferenceMark
)
2194 exportTextMark(xPropSet
,
2196 lcl_XmlReferenceElements
,
2199 else if (sType
== gsDocumentIndexMark
)
2201 pIndexMarkExport
->ExportIndexMark(xPropSet
, bAutoStyles
);
2203 else if (sType
== gsRedline
)
2205 if (nullptr != pRedlineExport
)
2206 pRedlineExport
->ExportChange(xPropSet
, bAutoStyles
);
2208 else if (sType
== gsRuby
)
2210 exportRuby(xPropSet
, bAutoStyles
);
2212 else if (sType
== "InContentMetadata")
2214 exportMeta(xPropSet
, bAutoStyles
, bIsProgress
, rPrevCharIsSpace
);
2216 else if (sType
== "ContentControl")
2218 ExportContentControl(xPropSet
, bAutoStyles
, bIsProgress
, rPrevCharIsSpace
);
2220 else if (sType
== gsTextFieldStart
)
2222 Reference
< css::text::XFormField
> xFormField(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2224 /* As of now, textmarks are a proposed extension to the OpenDocument standard. */
2227 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2229 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2232 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
, xBookmark
->getName());
2235 if (xFormField
.is())
2237 GetExport().AddAttribute(XML_NAMESPACE_FIELD
, XML_TYPE
, xFormField
->getFieldType());
2240 GetExport().StartElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK_START
, false);
2241 if (xFormField
.is())
2243 FieldParamExporter(&GetExport(), xFormField
->getParameters()).Export();
2245 GetExport().EndElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK_START
, false);
2247 /* The OpenDocument standard does not include support for TextMarks for now, so use bookmarks instead. */
2250 if (xFormField
.is())
2253 Reference
< css::container::XNameAccess
> xParameters
= xFormField
->getParameters();
2254 if (xParameters
.is() && xParameters
->hasByName("Name"))
2256 const Any aValue
= xParameters
->getByName("Name");
2259 if (sName
.isEmpty())
2260 { // name attribute is mandatory, so have to pull a
2261 // rabbit out of the hat here
2262 sName
= sFieldMarkName
+ OUString::number(
2263 m_xImpl
->AddFieldMarkStart(xFormField
));
2265 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
,
2267 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2268 XML_NAMESPACE_TEXT
, XML_BOOKMARK_START
,
2270 const OUString sFieldType
= xFormField
->getFieldType();
2271 if (sFieldType
== ODF_FORMTEXT
)
2273 openFieldMark
= TEXT
;
2275 else if (sFieldType
== ODF_FORMCHECKBOX
)
2277 openFieldMark
= CHECK
;
2281 openFieldMark
= NONE
;
2287 else if (sType
== gsTextFieldEnd
)
2291 Reference
< css::text::XFormField
> xFormField(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2293 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2295 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2296 XML_NAMESPACE_FIELD
, XML_FIELDMARK_END
,
2301 if (xFormField
.is())
2304 Reference
< css::container::XNameAccess
> xParameters
= xFormField
->getParameters();
2305 if (xParameters
.is() && xParameters
->hasByName("Name"))
2307 const Any aValue
= xParameters
->getByName("Name");
2310 if (sName
.isEmpty())
2311 { // name attribute is mandatory, so have to pull a
2312 // rabbit out of the hat here
2313 sName
= sFieldMarkName
+ OUString::number(
2314 m_xImpl
->GetFieldMarkIndex(xFormField
));
2316 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
,
2318 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2319 XML_NAMESPACE_TEXT
, XML_BOOKMARK_END
,
2325 else if (sType
== gsTextFieldStartEnd
)
2329 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
2331 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2334 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
, xBookmark
->getName());
2336 Reference
< css::text::XFormField
> xFormField(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2337 if (xFormField
.is())
2339 GetExport().AddAttribute(XML_NAMESPACE_FIELD
, XML_TYPE
, xFormField
->getFieldType());
2341 GetExport().StartElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK
, false);
2342 if (xFormField
.is())
2344 FieldParamExporter(&GetExport(), xFormField
->getParameters()).Export();
2346 GetExport().EndElement(XML_NAMESPACE_FIELD
, XML_FIELDMARK
, false);
2350 Reference
<XNamed
> xBookmark(xPropSet
->getPropertyValue(gsBookmark
), UNO_QUERY
);
2353 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
, xBookmark
->getName());
2354 SvXMLElementExport
aElem( GetExport(), !bAutoStyles
,
2355 XML_NAMESPACE_TEXT
, XML_BOOKMARK
,
2361 else if (sType
== gsSoftPageBreak
)
2364 exportSoftPageBreak();
2366 else if (sType
== "LineBreak")
2368 exportTextLineBreak(xPropSet
);
2371 OSL_FAIL("unknown text portion type");
2376 Reference
<XServiceInfo
> xServiceInfo( xTxtRange
, UNO_QUERY
);
2377 if( xServiceInfo
->supportsService( gsTextFieldService
) )
2379 exportTextField(xTxtRange
, bAutoStyles
, bIsProgress
, &rPrevCharIsSpace
);
2383 // no TextPortionType property -> non-Writer app -> text
2384 exportTextRange(xTxtRange
, bAutoStyles
, rPrevCharIsSpace
, openFieldMark
);
2389 // now that there are nested enumerations for meta(-field), this may be valid!
2390 // SAL_WARN_IF( bOpenRuby, "xmloff", "Red Alert: Ruby still open!" );
2393 void XMLTextParagraphExport::exportTable(
2394 const Reference
< XTextContent
> &,
2395 bool /*bAutoStyles*/, bool /*bIsProgress*/ )
2399 void XMLTextParagraphExport::exportTextField(
2400 const Reference
< XTextRange
> & rTextRange
,
2401 bool bAutoStyles
, bool bIsProgress
, bool *const pPrevCharIsSpace
)
2403 Reference
< XPropertySet
> xPropSet( rTextRange
, UNO_QUERY
);
2404 // non-Writer apps need not support Property TextField, so test first
2405 if (!xPropSet
->getPropertySetInfo()->hasPropertyByName( gsTextField
))
2408 Reference
< XTextField
> xTxtFld(xPropSet
->getPropertyValue( gsTextField
), uno::UNO_QUERY
);
2409 SAL_WARN_IF( !xTxtFld
.is(), "xmloff", "text field missing" );
2412 exportTextField(xTxtFld
, bAutoStyles
, bIsProgress
, true, pPrevCharIsSpace
);
2416 // write only characters
2417 GetExport().Characters(rTextRange
->getString());
2421 void XMLTextParagraphExport::exportTextField(
2422 const Reference
< XTextField
> & xTextField
,
2423 const bool bAutoStyles
, const bool bIsProgress
,
2424 const bool bRecursive
, bool *const pPrevCharIsSpace
)
2428 pFieldExport
->ExportFieldAutoStyle( xTextField
, bIsProgress
,
2433 assert(pPrevCharIsSpace
);
2434 pFieldExport
->ExportField(xTextField
, bIsProgress
, *pPrevCharIsSpace
);
2438 void XMLTextParagraphExport::exportSoftPageBreak()
2440 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
2441 XML_SOFT_PAGE_BREAK
, false,
2445 void XMLTextParagraphExport::exportTextLineBreak(
2446 const uno::Reference
<beans::XPropertySet
>& xPropSet
)
2448 static const XMLTokenEnum aLineBreakClears
[] = {
2455 uno::Reference
<text::XTextContent
> xLineBreak
;
2456 xPropSet
->getPropertyValue("LineBreak") >>= xLineBreak
;
2457 if (!xLineBreak
.is())
2462 uno::Reference
<beans::XPropertySet
> xLineBreakProps(xLineBreak
, uno::UNO_QUERY
);
2463 if (!xLineBreakProps
.is())
2469 xLineBreakProps
->getPropertyValue("Clear") >>= eClear
;
2470 if (eClear
>= 0 && o3tl::make_unsigned(eClear
) < SAL_N_ELEMENTS(aLineBreakClears
))
2472 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_CLEAR
,
2473 GetXMLToken(aLineBreakClears
[eClear
]));
2475 SvXMLElementExport
aElem(GetExport(), XML_NAMESPACE_TEXT
, XML_LINE_BREAK
,
2476 /*bIgnWSOutside=*/false, /*bIgnWSInside=*/false);
2479 void XMLTextParagraphExport::exportTextMark(
2480 const Reference
<XPropertySet
> & rPropSet
,
2481 const OUString
& rProperty
,
2482 const ::xmloff::token::XMLTokenEnum pElements
[],
2485 // mib said: "Hau wech!"
2487 // (Originally, I'd export a span element in case the (book|reference)mark
2488 // was formatted. This actually makes a difference in case some pervert
2489 // sets a point reference mark in the document and, say, formats it bold.
2490 // This basically meaningless formatting will now been thrown away
2491 // (aka cleaned up), since mib said: ... dvo
2497 Reference
<XNamed
> xName(rPropSet
->getPropertyValue(rProperty
), UNO_QUERY
);
2498 GetExport().AddAttribute(XML_NAMESPACE_TEXT
, XML_NAME
,
2501 // start, end, or point-reference?
2503 if( *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsCollapsed
)) )
2509 nElement
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsStart
)) ? 1 : 2;
2512 // bookmark, bookmark-start: xml:id and RDFa for RDF metadata
2513 if( nElement
< 2 ) {
2514 GetExport().AddAttributeXmlId(xName
);
2515 const uno::Reference
<text::XTextContent
> xTextContent(
2516 xName
, uno::UNO_QUERY_THROW
);
2517 GetExport().AddAttributesRDFa(xTextContent
);
2520 // bookmark-start: add attributes hidden and condition
2523 Reference
<XPropertySet
> bkmkProps(rPropSet
->getPropertyValue(rProperty
), UNO_QUERY
);
2524 Reference
<XPropertySetInfo
> bkmkPropInfo
= bkmkProps
->getPropertySetInfo();
2525 OUString
sHidden("BookmarkHidden");
2526 if (bkmkPropInfo
->hasPropertyByName(sHidden
))
2528 bool bHidden
= false;
2529 bkmkProps
->getPropertyValue(sHidden
) >>= bHidden
;
2532 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, "hidden", "true");
2533 OUString
sCondition("BookmarkCondition");
2534 if (bkmkPropInfo
->hasPropertyByName(sCondition
))
2536 OUString sBookmarkCondition
;
2537 bkmkProps
->getPropertyValue(sCondition
) >>= sBookmarkCondition
;
2538 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, "condition", sBookmarkCondition
);
2545 assert(pElements
!= nullptr);
2546 assert(0 <= nElement
&& nElement
<= 2);
2547 SvXMLElementExport
aElem(GetExport(),
2548 XML_NAMESPACE_TEXT
, pElements
[nElement
],
2550 // else: no styles. (see above)
2553 static bool lcl_txtpara_isBoundAsChar(
2554 const Reference
< XPropertySet
> & rPropSet
,
2555 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
2557 bool bIsBoundAsChar
= false;
2558 OUString
sAnchorType( "AnchorType" );
2559 if( rPropSetInfo
->hasPropertyByName( sAnchorType
) )
2561 TextContentAnchorType eAnchor
;
2562 rPropSet
->getPropertyValue( sAnchorType
) >>= eAnchor
;
2563 bIsBoundAsChar
= TextContentAnchorType_AS_CHARACTER
== eAnchor
;
2566 return bIsBoundAsChar
;
2569 XMLShapeExportFlags
XMLTextParagraphExport::addTextFrameAttributes(
2570 const Reference
< XPropertySet
>& rPropSet
,
2572 basegfx::B2DPoint
* pCenter
,
2573 OUString
* pMinHeightValue
,
2574 OUString
* pMinWidthValue
)
2576 XMLShapeExportFlags nShapeFeatures
= SEF_DEFAULT
;
2578 // draw:name (#97662#: not for shapes, since those names will be
2579 // treated in the shape export)
2582 Reference
< XNamed
> xNamed( rPropSet
, UNO_QUERY
);
2585 OUString
sName( xNamed
->getName() );
2586 if( !sName
.isEmpty() )
2587 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_NAME
,
2588 xNamed
->getName() );
2592 OUStringBuffer sValue
;
2595 TextContentAnchorType eAnchor
= TextContentAnchorType_AT_PARAGRAPH
;
2596 rPropSet
->getPropertyValue( gsAnchorType
) >>= eAnchor
;
2598 XMLAnchorTypePropHdl aAnchorTypeHdl
;
2600 aAnchorTypeHdl
.exportXML( sTmp
, uno::makeAny(eAnchor
),
2601 GetExport().GetMM100UnitConverter() );
2602 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_ANCHOR_TYPE
, sTmp
);
2605 // text:anchor-page-number
2606 if( TextContentAnchorType_AT_PAGE
== eAnchor
)
2608 sal_Int16 nPage
= 0;
2609 rPropSet
->getPropertyValue( gsAnchorPageNo
) >>= nPage
;
2610 SAL_WARN_IF(nPage
<= 0, "xmloff",
2611 "ERROR: writing invalid anchor-page-number 0");
2612 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_ANCHOR_PAGE_NUMBER
,
2613 OUString::number( nPage
) );
2617 nShapeFeatures
|= XMLShapeExportFlags::NO_WS
;
2620 // OD 2004-06-01 #i27691# - correction: no export of svg:x, if object
2621 // is anchored as-character.
2623 eAnchor
!= TextContentAnchorType_AS_CHARACTER
)
2626 sal_Int16 nHoriOrient
= HoriOrientation::NONE
;
2627 rPropSet
->getPropertyValue( gsHoriOrient
) >>= nHoriOrient
;
2628 if( HoriOrientation::NONE
== nHoriOrient
)
2631 rPropSet
->getPropertyValue( gsHoriOrientPosition
) >>= nPos
;
2632 GetExport().GetMM100UnitConverter().convertMeasureToXML(
2634 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_X
,
2635 sValue
.makeStringAndClear() );
2636 if(nullptr != pCenter
)
2638 // add left edge to Center
2639 pCenter
->setX(pCenter
->getX() + nPos
);
2643 else if( TextContentAnchorType_AS_CHARACTER
== eAnchor
)
2644 nShapeFeatures
= (nShapeFeatures
& ~XMLShapeExportFlags::X
);
2646 if( !bShape
|| TextContentAnchorType_AS_CHARACTER
== eAnchor
)
2649 sal_Int16 nVertOrient
= VertOrientation::NONE
;
2650 rPropSet
->getPropertyValue( gsVertOrient
) >>= nVertOrient
;
2651 if( VertOrientation::NONE
== nVertOrient
)
2654 rPropSet
->getPropertyValue( gsVertOrientPosition
) >>= nPos
;
2655 GetExport().GetMM100UnitConverter().convertMeasureToXML(
2657 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_Y
,
2658 sValue
.makeStringAndClear() );
2659 if(nullptr != pCenter
)
2661 // add top edge to Center
2662 pCenter
->setY(pCenter
->getY() + nPos
);
2666 nShapeFeatures
= (nShapeFeatures
& ~XMLShapeExportFlags::Y
);
2669 Reference
< XPropertySetInfo
> xPropSetInfo(rPropSet
->getPropertySetInfo());
2672 sal_Int16 nWidthType
= SizeType::FIX
;
2673 if( xPropSetInfo
->hasPropertyByName( gsWidthType
) )
2675 rPropSet
->getPropertyValue( gsWidthType
) >>= nWidthType
;
2677 if( xPropSetInfo
->hasPropertyByName( gsWidth
) )
2679 sal_Int32 nWidth
= 0;
2680 // VAR size will be written as zero min-size
2681 if( SizeType::VARIABLE
!= nWidthType
)
2683 rPropSet
->getPropertyValue( gsWidth
) >>= nWidth
;
2685 GetExport().GetMM100UnitConverter().convertMeasureToXML(sValue
, nWidth
);
2686 if( SizeType::FIX
!= nWidthType
)
2688 assert(pMinWidthValue
);
2691 *pMinWidthValue
= sValue
.makeStringAndClear();
2696 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_WIDTH
,
2697 sValue
.makeStringAndClear() );
2698 if(nullptr != pCenter
)
2700 // add half width to Center
2701 pCenter
->setX(pCenter
->getX() + (0.5 * nWidth
));
2705 bool bSyncWidth
= false;
2706 if( xPropSetInfo
->hasPropertyByName( gsIsSyncWidthToHeight
) )
2708 bSyncWidth
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsIsSyncWidthToHeight
));
2710 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_WIDTH
,
2713 if( !bSyncWidth
&& xPropSetInfo
->hasPropertyByName( gsRelativeWidth
) )
2715 sal_Int16 nRelWidth
= 0;
2716 rPropSet
->getPropertyValue( gsRelativeWidth
) >>= nRelWidth
;
2717 SAL_WARN_IF( nRelWidth
< 0 || nRelWidth
> 254, "xmloff",
2718 "Got illegal relative width from API" );
2721 ::sax::Converter::convertPercent( sValue
, nRelWidth
);
2722 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_WIDTH
,
2723 sValue
.makeStringAndClear() );
2727 // svg:height, fo:min-height or style:rel-height
2728 sal_Int16 nSizeType
= SizeType::FIX
;
2729 if( xPropSetInfo
->hasPropertyByName( gsSizeType
) )
2731 rPropSet
->getPropertyValue( gsSizeType
) >>= nSizeType
;
2733 bool bSyncHeight
= false;
2734 if( xPropSetInfo
->hasPropertyByName( gsIsSyncHeightToWidth
) )
2736 bSyncHeight
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsIsSyncHeightToWidth
));
2738 sal_Int16 nRelHeight
= 0;
2739 if( !bSyncHeight
&& xPropSetInfo
->hasPropertyByName( gsRelativeHeight
) )
2741 rPropSet
->getPropertyValue( gsRelativeHeight
) >>= nRelHeight
;
2743 if( xPropSetInfo
->hasPropertyByName( gsHeight
) )
2745 sal_Int32 nHeight
= 0;
2746 if( SizeType::VARIABLE
!= nSizeType
)
2748 rPropSet
->getPropertyValue( gsHeight
) >>= nHeight
;
2750 GetExport().GetMM100UnitConverter().convertMeasureToXML( sValue
,
2752 if( SizeType::FIX
!= nSizeType
&& 0==nRelHeight
&& !bSyncHeight
&&
2755 *pMinHeightValue
= sValue
.makeStringAndClear();
2759 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_HEIGHT
,
2760 sValue
.makeStringAndClear() );
2761 if(nullptr != pCenter
)
2763 // add half height to Center
2764 pCenter
->setY(pCenter
->getY() + (0.5 * nHeight
));
2770 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_HEIGHT
,
2771 SizeType::MIN
== nSizeType
? XML_SCALE_MIN
: XML_SCALE
);
2774 else if( nRelHeight
> 0 )
2776 ::sax::Converter::convertPercent( sValue
, nRelHeight
);
2777 if( SizeType::MIN
== nSizeType
)
2779 assert(pMinHeightValue
);
2780 if (pMinHeightValue
)
2782 *pMinHeightValue
= sValue
.makeStringAndClear();
2786 GetExport().AddAttribute( XML_NAMESPACE_STYLE
, XML_REL_HEIGHT
,
2787 sValue
.makeStringAndClear() );
2790 OUString
sZOrder( "ZOrder" );
2791 if( xPropSetInfo
->hasPropertyByName( sZOrder
) )
2793 sal_Int32 nZIndex
= 0;
2794 rPropSet
->getPropertyValue( sZOrder
) >>= nZIndex
;
2797 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_ZINDEX
,
2798 OUString::number( nZIndex
) );
2802 return nShapeFeatures
;
2805 void XMLTextParagraphExport::exportAnyTextFrame(
2806 const Reference
< XTextContent
> & rTxtCntnt
,
2810 bool bExportContent
,
2811 const Reference
< XPropertySet
> *pRangePropSet
)
2813 Reference
< XPropertySet
> xPropSet( rTxtCntnt
, UNO_QUERY
);
2817 if( FrameType::Embedded
== eType
)
2818 _collectTextEmbeddedAutoStyles( xPropSet
);
2819 // No text frame style for shapes (#i28745#)
2820 else if ( FrameType::Shape
!= eType
)
2821 Add( XmlStyleFamily::TEXT_FRAME
, xPropSet
);
2823 if( pRangePropSet
&& lcl_txtpara_isBoundAsChar( xPropSet
,
2824 xPropSet
->getPropertySetInfo() ) )
2825 Add( XmlStyleFamily::TEXT_TEXT
, *pRangePropSet
);
2829 case FrameType::Text
:
2831 // frame bound frames
2832 if ( bExportContent
)
2834 Reference
< XTextFrame
> xTxtFrame( rTxtCntnt
, UNO_QUERY
);
2835 Reference
< XText
> xTxt(xTxtFrame
->getText());
2836 exportFrameFrames( true, bIsProgress
, &xTxtFrame
);
2837 exportText( xTxt
, bAutoStyles
, bIsProgress
, true );
2841 case FrameType::Shape
:
2843 Reference
< XShape
> xShape( rTxtCntnt
, UNO_QUERY
);
2844 GetExport().GetShapeExport()->collectShapeAutoStyles( xShape
);
2853 Reference
< XPropertySetInfo
> xPropSetInfo(xPropSet
->getPropertySetInfo());
2854 Reference
< XPropertyState
> xPropState( xPropSet
, UNO_QUERY
);
2856 bool bAddCharStyles
= pRangePropSet
&&
2857 lcl_txtpara_isBoundAsChar( xPropSet
, xPropSetInfo
);
2859 bool bIsUICharStyle
;
2860 bool bHasAutoStyle
= false;
2864 if( bAddCharStyles
)
2867 sStyle
= FindTextStyleAndHyperlink( *pRangePropSet
, bDummy
, bIsUICharStyle
, bHasAutoStyle
);
2870 bIsUICharStyle
= false;
2872 bool bDoSomething
= bIsUICharStyle
2873 && aCharStyleNamesPropInfoCache
.hasProperty( *pRangePropSet
);
2874 XMLTextCharStyleNamesElementExport
aCharStylesExport(
2875 GetExport(), bDoSomething
, bHasAutoStyle
,
2876 bDoSomething
? *pRangePropSet
: Reference
<XPropertySet
>(),
2879 if( !sStyle
.isEmpty() )
2880 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
2881 GetExport().EncodeStyleName( sStyle
) );
2883 SvXMLElementExport
aElem( GetExport(), !sStyle
.isEmpty(),
2884 XML_NAMESPACE_TEXT
, XML_SPAN
, false, false );
2886 SvXMLElementExport
aElement( GetExport(),
2887 FrameType::Shape
!= eType
&&
2888 addHyperlinkAttributes( xPropSet
,
2889 xPropState
,xPropSetInfo
),
2890 XML_NAMESPACE_DRAW
, XML_A
, false, false );
2893 case FrameType::Text
:
2894 _exportTextFrame( xPropSet
, xPropSetInfo
, bIsProgress
);
2896 case FrameType::Graphic
:
2897 _exportTextGraphic( xPropSet
, xPropSetInfo
);
2899 case FrameType::Embedded
:
2900 _exportTextEmbedded( xPropSet
, xPropSetInfo
);
2902 case FrameType::Shape
:
2904 Reference
< XShape
> xShape( rTxtCntnt
, UNO_QUERY
);
2905 XMLShapeExportFlags nFeatures
=
2906 addTextFrameAttributes( xPropSet
, true );
2907 GetExport().GetShapeExport()
2908 ->exportShape( xShape
, nFeatures
);
2918 void XMLTextParagraphExport::_exportTextFrame(
2919 const Reference
< XPropertySet
> & rPropSet
,
2920 const Reference
< XPropertySetInfo
> & rPropSetInfo
,
2923 Reference
< XTextFrame
> xTxtFrame( rPropSet
, UNO_QUERY
);
2924 Reference
< XText
> xTxt(xTxtFrame
->getText());
2927 if( rPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
2929 rPropSet
->getPropertyValue( gsFrameStyleName
) >>= sStyle
;
2932 OUString aMinHeightValue
;
2933 OUString sMinWidthValue
;
2934 OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_FRAME
, rPropSet
, sStyle
);
2935 if ( sAutoStyle
.isEmpty() )
2936 sAutoStyle
= sStyle
;
2937 if( !sAutoStyle
.isEmpty() )
2938 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_STYLE_NAME
,
2939 GetExport().EncodeStyleName( sAutoStyle
) );
2940 addTextFrameAttributes(rPropSet
, false, nullptr, &aMinHeightValue
, &sMinWidthValue
);
2942 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
,
2943 XML_FRAME
, false, true );
2945 if( !aMinHeightValue
.isEmpty() )
2946 GetExport().AddAttribute( XML_NAMESPACE_FO
, XML_MIN_HEIGHT
,
2949 if (!sMinWidthValue
.isEmpty())
2951 GetExport().AddAttribute( XML_NAMESPACE_FO
, XML_MIN_WIDTH
,
2955 // draw:chain-next-name
2956 if( rPropSetInfo
->hasPropertyByName( gsChainNextName
) )
2959 if( (rPropSet
->getPropertyValue( gsChainNextName
) >>= sNext
) && !sNext
.isEmpty() )
2960 GetExport().AddAttribute( XML_NAMESPACE_DRAW
,
2961 XML_CHAIN_NEXT_NAME
,
2966 SvXMLElementExport
aElement( GetExport(), XML_NAMESPACE_DRAW
,
2967 XML_TEXT_BOX
, true, true );
2969 // frames bound to frame
2970 exportFrameFrames( false, bIsProgress
, &xTxtFrame
);
2972 exportText( xTxt
, false, bIsProgress
, true );
2976 Reference
<XEventsSupplier
> xEventsSupp( xTxtFrame
, UNO_QUERY
);
2977 GetExport().GetEventExport().Export(xEventsSupp
);
2980 GetExport().GetImageMapExport().Export( rPropSet
);
2982 // svg:title and svg:desc (#i73249#)
2983 exportTitleAndDescription( rPropSet
, rPropSetInfo
);
2986 void XMLTextParagraphExport::exportContour(
2987 const Reference
< XPropertySet
> & rPropSet
,
2988 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
2990 if( !rPropSetInfo
->hasPropertyByName( gsContourPolyPolygon
) )
2995 PointSequenceSequence aSourcePolyPolygon
;
2996 rPropSet
->getPropertyValue( gsContourPolyPolygon
) >>= aSourcePolyPolygon
;
2997 const basegfx::B2DPolyPolygon
aPolyPolygon(
2998 basegfx::utils::UnoPointSequenceSequenceToB2DPolyPolygon(
2999 aSourcePolyPolygon
));
3000 const sal_uInt32
nPolygonCount(aPolyPolygon
.count());
3007 const basegfx::B2DRange
aPolyPolygonRange(aPolyPolygon
.getB2DRange());
3010 if( rPropSetInfo
->hasPropertyByName( gsIsPixelContour
) )
3012 bPixel
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsIsPixelContour
));
3016 OUStringBuffer
aStringBuffer( 10 );
3020 ::sax::Converter::convertMeasurePx(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getWidth()));
3024 GetExport().GetMM100UnitConverter().convertMeasureToXML(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getWidth()));
3027 GetExport().AddAttribute(XML_NAMESPACE_SVG
, XML_WIDTH
, aStringBuffer
.makeStringAndClear());
3032 ::sax::Converter::convertMeasurePx(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getHeight()));
3036 GetExport().GetMM100UnitConverter().convertMeasureToXML(aStringBuffer
, basegfx::fround(aPolyPolygonRange
.getHeight()));
3039 GetExport().AddAttribute(XML_NAMESPACE_SVG
, XML_HEIGHT
, aStringBuffer
.makeStringAndClear());
3042 SdXMLImExViewBox
aViewBox(0.0, 0.0, aPolyPolygonRange
.getWidth(), aPolyPolygonRange
.getHeight());
3043 GetExport().AddAttribute(XML_NAMESPACE_SVG
, XML_VIEWBOX
, aViewBox
.GetExportString());
3044 enum XMLTokenEnum eElem
= XML_TOKEN_INVALID
;
3046 if(1 == nPolygonCount
)
3048 // simple polygon shape, can be written as svg:points sequence
3049 const OUString
aPointString(
3050 basegfx::utils::exportToSvgPoints(
3051 aPolyPolygon
.getB2DPolygon(0)));
3053 // write point array
3054 GetExport().AddAttribute(XML_NAMESPACE_DRAW
, XML_POINTS
, aPointString
);
3055 eElem
= XML_CONTOUR_POLYGON
;
3059 // polypolygon, needs to be written as a svg:path sequence
3060 const OUString
aPolygonString(
3061 basegfx::utils::exportToSvgD(
3063 true, // bUseRelativeCoordinates
3064 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
3065 true)); // bHandleRelativeNextPointCompatible
3067 // write point array
3068 GetExport().AddAttribute( XML_NAMESPACE_SVG
, XML_D
, aPolygonString
);
3069 eElem
= XML_CONTOUR_PATH
;
3072 if( rPropSetInfo
->hasPropertyByName( gsIsAutomaticContour
) )
3074 bool bTmp
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(
3075 gsIsAutomaticContour
));
3076 GetExport().AddAttribute( XML_NAMESPACE_DRAW
,
3077 XML_RECREATE_ON_EDIT
, bTmp
? XML_TRUE
: XML_FALSE
);
3081 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_DRAW
, eElem
,
3085 void XMLTextParagraphExport::_exportTextGraphic(
3086 const Reference
< XPropertySet
> & rPropSet
,
3087 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
3090 if( rPropSetInfo
->hasPropertyByName( gsFrameStyleName
) )
3092 rPropSet
->getPropertyValue( gsFrameStyleName
) >>= sStyle
;
3095 OUString sAutoStyle
= Find( XmlStyleFamily::TEXT_FRAME
, rPropSet
, sStyle
);
3096 if ( sAutoStyle
.isEmpty() )
3097 sAutoStyle
= sStyle
;
3098 if( !sAutoStyle
.isEmpty() )
3099 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_STYLE_NAME
,
3100 GetExport().EncodeStyleName( sAutoStyle
) );
3102 // check if we need to use svg:transform
3103 sal_Int16
nRotation(0);
3104 rPropSet
->getPropertyValue( gsGraphicRotation
) >>= nRotation
;
3105 const bool bUseRotation(0 != nRotation
);
3106 basegfx::B2DPoint
aCenter(0.0, 0.0);
3108 // add TextFrame attributes like svg:x/y/width/height, also get back
3109 // object's center point if rotation is used and has to be exported
3110 addTextFrameAttributes(rPropSet
, false, bUseRotation
? &aCenter
: nullptr);
3115 // RotateFlyFrameFix: im/export full 'draw:transform' using existing tooling.
3116 // Currently only rotation is used, but combinations with 'draw:transform'
3117 // may be necessary in the future, so that svg:x/svg:y/svg:width/svg:height
3118 // may be extended/replaced with 'draw:transform' (see draw objects)
3119 SdXMLImExTransform2D aSdXMLImExTransform2D
;
3121 // Convert from 10th degree integer to deg.
3122 // CAUTION: internal rotation is classically mathematically 'wrong' defined by ignoring that
3123 // we have a right-handed coordinate system, so need to correct this by mirroring
3124 // the rotation to get the correct transformation. See also case XML_TOK_TEXT_FRAME_TRANSFORM
3125 // in XMLTextFrameContext_Impl::XMLTextFrameContext_Impl and #i78696#
3126 // CAUTION-II: due to tdf#115782 it is better for current ODF to indeed write it with the wrong
3127 // orientation as in all other cases - ARGH! We will need to correct this in future ODF ASAP!
3128 const double fRotate(basegfx::deg2rad
<10>(nRotation
));
3130 // transform to rotation center which is the object's center
3131 aSdXMLImExTransform2D
.AddTranslate(-aCenter
);
3133 // add rotation itself
3134 // tdf#115529 but correct value modulo 2PI to have it positive and in the range of [0.0 .. 2PI[
3135 aSdXMLImExTransform2D
.AddRotate(basegfx::normalizeToRange(fRotate
, 2 * M_PI
));
3137 // back-transform after rotation
3138 aSdXMLImExTransform2D
.AddTranslate(aCenter
);
3140 // Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed,
3141 // but is not generally available (as it should be, a 'current' UnitConverter should
3142 // be available at GetExport() - and maybe was once). May have to be addressed as soon
3143 // as translate transformations are used here.
3144 GetExport().AddAttribute(
3147 aSdXMLImExTransform2D
.GetExportString(GetExport().GetMM100UnitConverter()));
3151 SvXMLElementExport
aElem(GetExport(), XML_NAMESPACE_DRAW
, XML_FRAME
, false, true);
3155 uno::Reference
<graphic::XGraphic
> xGraphic
;
3156 rPropSet
->getPropertyValue("Graphic") >>= xGraphic
;
3158 OUString sInternalURL
;
3159 OUString sOutMimeType
;
3163 sInternalURL
= GetExport().AddEmbeddedXGraphic(xGraphic
, sOutMimeType
);
3166 // If there still is no url, then graphic is empty
3167 if (!sInternalURL
.isEmpty())
3169 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sInternalURL
);
3170 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3171 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3172 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3176 OUString sGrfFilter
;
3177 rPropSet
->getPropertyValue( gsGraphicFilter
) >>= sGrfFilter
;
3178 if( !sGrfFilter
.isEmpty() )
3179 GetExport().AddAttribute( XML_NAMESPACE_DRAW
, XML_FILTER_NAME
,
3182 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
3184 if (sOutMimeType
.isEmpty())
3186 GetExport().GetGraphicMimeTypeFromStream(xGraphic
, sOutMimeType
);
3188 if (!sOutMimeType
.isEmpty())
3189 { // ODF 1.3 OFFICE-3943
3190 GetExport().AddAttribute(
3191 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
3192 ? XML_NAMESPACE_DRAW
3193 : XML_NAMESPACE_LO_EXT
,
3194 "mime-type", sOutMimeType
);
3199 // optional office:binary-data
3202 SvXMLElementExport
aElement(GetExport(), XML_NAMESPACE_DRAW
, XML_IMAGE
, false, true );
3203 GetExport().AddEmbeddedXGraphicAsBase64(xGraphic
);
3207 const bool bAddReplacementImages
= officecfg::Office::Common::Save::Graphic::AddReplacementImages::get();
3208 if (bAddReplacementImages
)
3210 // replacement graphic for backwards compatibility, but
3211 // only for SVG and metafiles currently
3212 uno::Reference
<graphic::XGraphic
> xReplacementGraphic
;
3213 rPropSet
->getPropertyValue("ReplacementGraphic") >>= xReplacementGraphic
;
3215 OUString sInternalURL
;
3216 OUString sOutMimeType
;
3218 //Resolves: fdo#62461 put preferred image first above, followed by
3220 if (xReplacementGraphic
.is())
3222 sInternalURL
= GetExport().AddEmbeddedXGraphic(xReplacementGraphic
, sOutMimeType
);
3225 // If there is no url, then graphic is empty
3226 if (!sInternalURL
.isEmpty())
3228 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_HREF
, sInternalURL
);
3229 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3230 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_SHOW
, XML_EMBED
);
3231 GetExport().AddAttribute(XML_NAMESPACE_XLINK
, XML_ACTUATE
, XML_ONLOAD
);
3234 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012
)
3236 if (sOutMimeType
.isEmpty())
3238 GetExport().GetGraphicMimeTypeFromStream(xReplacementGraphic
, sOutMimeType
);
3240 if (!sOutMimeType
.isEmpty())
3241 { // ODF 1.3 OFFICE-3943
3242 GetExport().AddAttribute(
3243 SvtSaveOptions::ODFSVER_013
<= GetExport().getSaneDefaultVersion()
3244 ? XML_NAMESPACE_DRAW
3245 : XML_NAMESPACE_LO_EXT
,
3246 "mime-type", sOutMimeType
);
3251 // optional office:binary-data
3252 if (xReplacementGraphic
.is())
3254 SvXMLElementExport
aElement(GetExport(), XML_NAMESPACE_DRAW
, XML_IMAGE
, true, true);
3255 GetExport().AddEmbeddedXGraphicAsBase64(xReplacementGraphic
);
3260 Reference
<XEventsSupplier
> xEventsSupp( rPropSet
, UNO_QUERY
);
3261 GetExport().GetEventExport().Export(xEventsSupp
);
3264 GetExport().GetImageMapExport().Export( rPropSet
);
3266 // svg:title and svg:desc (#i73249#)
3267 exportTitleAndDescription( rPropSet
, rPropSetInfo
);
3270 exportContour( rPropSet
, rPropSetInfo
);
3273 void XMLTextParagraphExport::_collectTextEmbeddedAutoStyles(const Reference
< XPropertySet
> & )
3275 SAL_WARN( "xmloff", "no API implementation available" );
3278 void XMLTextParagraphExport::_exportTextEmbedded(
3279 const Reference
< XPropertySet
> &,
3280 const Reference
< XPropertySetInfo
> & )
3282 SAL_WARN( "xmloff", "no API implementation available" );
3285 void XMLTextParagraphExport::exportEvents( const Reference
< XPropertySet
> & rPropSet
)
3288 Reference
<XEventsSupplier
> xEventsSupp( rPropSet
, UNO_QUERY
);
3289 GetExport().GetEventExport().Export(xEventsSupp
);
3292 if (rPropSet
->getPropertySetInfo()->hasPropertyByName("ImageMap"))
3293 GetExport().GetImageMapExport().Export( rPropSet
);
3296 // Implement Title/Description Elements UI (#i73249#)
3297 void XMLTextParagraphExport::exportTitleAndDescription(
3298 const Reference
< XPropertySet
> & rPropSet
,
3299 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
3302 if( rPropSetInfo
->hasPropertyByName( gsTitle
) )
3305 rPropSet
->getPropertyValue( gsTitle
) >>= sObjTitle
;
3306 if( !sObjTitle
.isEmpty() )
3308 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_SVG
,
3309 XML_TITLE
, true, false );
3310 GetExport().Characters( sObjTitle
);
3315 if( rPropSetInfo
->hasPropertyByName( gsDescription
) )
3318 rPropSet
->getPropertyValue( gsDescription
) >>= sObjDesc
;
3319 if( !sObjDesc
.isEmpty() )
3321 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_SVG
,
3322 XML_DESC
, true, false );
3323 GetExport().Characters( sObjDesc
);
3328 bool XMLTextParagraphExport::addHyperlinkAttributes(
3329 const Reference
< XPropertySet
> & rPropSet
,
3330 const Reference
< XPropertyState
> & rPropState
,
3331 const Reference
< XPropertySetInfo
> & rPropSetInfo
)
3333 bool bExport
= false;
3334 OUString sHRef
, sName
, sTargetFrame
, sUStyleName
, sVStyleName
;
3335 bool bServerMap
= false;
3337 if( rPropSetInfo
->hasPropertyByName( gsHyperLinkURL
) &&
3338 ( !rPropState
.is() || PropertyState_DIRECT_VALUE
==
3339 rPropState
->getPropertyState( gsHyperLinkURL
) ) )
3341 rPropSet
->getPropertyValue( gsHyperLinkURL
) >>= sHRef
;
3343 if( !sHRef
.isEmpty() )
3347 if ( sHRef
.isEmpty() )
3349 // hyperlink without a URL does not make sense
3350 OSL_ENSURE( false, "hyperlink without a URL --> no export to ODF" );
3354 if ( rPropSetInfo
->hasPropertyByName( gsHyperLinkName
)
3355 && ( !rPropState
.is()
3356 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsHyperLinkName
) ) )
3358 rPropSet
->getPropertyValue( gsHyperLinkName
) >>= sName
;
3359 if( !sName
.isEmpty() )
3363 if ( rPropSetInfo
->hasPropertyByName( gsHyperLinkTarget
)
3364 && ( !rPropState
.is()
3365 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsHyperLinkTarget
) ) )
3367 rPropSet
->getPropertyValue( gsHyperLinkTarget
) >>= sTargetFrame
;
3368 if( !sTargetFrame
.isEmpty() )
3372 if ( rPropSetInfo
->hasPropertyByName( gsServerMap
)
3373 && ( !rPropState
.is()
3374 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsServerMap
) ) )
3376 bServerMap
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue( gsServerMap
));
3381 if ( rPropSetInfo
->hasPropertyByName( gsUnvisitedCharStyleName
)
3382 && ( !rPropState
.is()
3383 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsUnvisitedCharStyleName
) ) )
3385 rPropSet
->getPropertyValue( gsUnvisitedCharStyleName
) >>= sUStyleName
;
3386 if( !sUStyleName
.isEmpty() )
3390 if ( rPropSetInfo
->hasPropertyByName( gsVisitedCharStyleName
)
3391 && ( !rPropState
.is()
3392 || PropertyState_DIRECT_VALUE
== rPropState
->getPropertyState( gsVisitedCharStyleName
) ) )
3394 rPropSet
->getPropertyValue( gsVisitedCharStyleName
) >>= sVStyleName
;
3395 if( !sVStyleName
.isEmpty() )
3401 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_TYPE
, XML_SIMPLE
);
3402 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
, GetExport().GetRelativeReference( sHRef
) );
3404 if( !sName
.isEmpty() )
3405 GetExport().AddAttribute( XML_NAMESPACE_OFFICE
, XML_NAME
, sName
);
3407 if( !sTargetFrame
.isEmpty() )
3409 GetExport().AddAttribute( XML_NAMESPACE_OFFICE
,
3410 XML_TARGET_FRAME_NAME
, sTargetFrame
);
3411 enum XMLTokenEnum eTok
= sTargetFrame
== "_blank" ? XML_NEW
: XML_REPLACE
;
3412 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_SHOW
, eTok
);
3416 GetExport().AddAttribute( XML_NAMESPACE_OFFICE
,
3417 XML_SERVER_MAP
, XML_TRUE
);
3419 if( !sUStyleName
.isEmpty() )
3420 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
3421 XML_STYLE_NAME
, GetExport().EncodeStyleName( sUStyleName
) );
3423 if( !sVStyleName
.isEmpty() )
3424 GetExport().AddAttribute( XML_NAMESPACE_TEXT
,
3425 XML_VISITED_STYLE_NAME
, GetExport().EncodeStyleName( sVStyleName
) );
3431 void XMLTextParagraphExport::exportTextRangeSpan(
3432 const css::uno::Reference
< css::text::XTextRange
> & rTextRange
,
3433 Reference
< XPropertySet
> const & xPropSet
,
3434 Reference
< XPropertySetInfo
> & xPropSetInfo
,
3435 const bool bIsUICharStyle
,
3436 const bool bHasAutoStyle
,
3437 const OUString
& sStyle
,
3438 bool& rPrevCharIsSpace
,
3439 FieldmarkType
& openFieldMark
)
3441 XMLTextCharStyleNamesElementExport
aCharStylesExport(
3443 bIsUICharStyle
&& aCharStyleNamesPropInfoCache
.hasProperty( xPropSet
, xPropSetInfo
),
3448 if ( !sStyle
.isEmpty() )
3450 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_STYLE_NAME
, GetExport().EncodeStyleName( sStyle
) );
3453 SvXMLElementExport
aElement( GetExport(), !sStyle
.isEmpty(), XML_NAMESPACE_TEXT
, XML_SPAN
, false, false );
3454 const OUString
aText( rTextRange
->getString() );
3455 SvXMLElementExport
aElem2( GetExport(), TEXT
== openFieldMark
,
3456 XML_NAMESPACE_TEXT
, XML_TEXT_INPUT
,
3458 exportCharacterData(aText
, rPrevCharIsSpace
);
3459 openFieldMark
= NONE
;
3463 void XMLTextParagraphExport::exportTextRange(
3464 const Reference
< XTextRange
> & rTextRange
,
3466 bool& rPrevCharIsSpace
,
3467 FieldmarkType
& openFieldMark
)
3469 Reference
< XPropertySet
> xPropSet( rTextRange
, UNO_QUERY
);
3472 Add( XmlStyleFamily::TEXT_TEXT
, xPropSet
);
3476 bool bHyperlink
= false;
3477 bool bIsUICharStyle
= false;
3478 bool bHasAutoStyle
= false;
3479 const OUString
sStyle(
3480 FindTextStyleAndHyperlink( xPropSet
, bHyperlink
, bIsUICharStyle
, bHasAutoStyle
) );
3482 Reference
< XPropertySetInfo
> xPropSetInfo
;
3483 bool bHyperlinkAttrsAdded
= false;
3486 Reference
< XPropertyState
> xPropState( xPropSet
, UNO_QUERY
);
3487 xPropSetInfo
.set( xPropSet
->getPropertySetInfo() );
3488 bHyperlinkAttrsAdded
= addHyperlinkAttributes( xPropSet
, xPropState
, xPropSetInfo
);
3491 if ( bHyperlink
&& bHyperlinkAttrsAdded
)
3493 SvXMLElementExport
aElem( GetExport(), true, XML_NAMESPACE_TEXT
, XML_A
, false, false );
3495 // export events (if supported)
3496 OUString
sHyperLinkEvents(
3498 if (xPropSetInfo
->hasPropertyByName(sHyperLinkEvents
))
3500 Reference
< XNameReplace
> xName( xPropSet
->getPropertyValue( sHyperLinkEvents
), uno::UNO_QUERY
);
3501 GetExport().GetEventExport().Export( xName
, false );
3504 exportTextRangeSpan( rTextRange
, xPropSet
, xPropSetInfo
, bIsUICharStyle
, bHasAutoStyle
, sStyle
, rPrevCharIsSpace
, openFieldMark
);
3508 exportTextRangeSpan( rTextRange
, xPropSet
, xPropSetInfo
, bIsUICharStyle
, bHasAutoStyle
, sStyle
, rPrevCharIsSpace
, openFieldMark
);
3513 void XMLTextParagraphExport::exportCharacterData(const OUString
& rText
,
3514 bool& rPrevCharIsSpace
)
3516 sal_Int32 nExpStartPos
= 0;
3517 sal_Int32 nEndPos
= rText
.getLength();
3518 sal_Int32 nSpaceChars
= 0;
3519 for( sal_Int32 nPos
= 0; nPos
< nEndPos
; nPos
++ )
3521 sal_Unicode cChar
= rText
[nPos
];
3522 bool bExpCharAsText
= true;
3523 bool bExpCharAsElement
= false;
3524 bool bCurrCharIsSpace
= false;
3529 // These characters are exported as text.
3530 bExpCharAsElement
= true;
3531 bExpCharAsText
= false;
3534 break; // legal character
3535 case 0x0020: // Blank
3536 if( rPrevCharIsSpace
)
3538 // If the previous character is a space character,
3539 // too, export a special space element.
3540 bExpCharAsText
= false;
3542 bCurrCharIsSpace
= true;
3545 if( cChar
< 0x0020 )
3548 OSL_ENSURE( txtparae_bContainsIllegalCharacters
||
3550 "illegal character in text content" );
3551 txtparae_bContainsIllegalCharacters
= true;
3553 bExpCharAsText
= false;
3558 // If the current character is not exported as text
3559 // the text that has not been exported by now has to be exported now.
3560 if( nPos
> nExpStartPos
&& !bExpCharAsText
)
3562 SAL_WARN_IF( 0 != nSpaceChars
, "xmloff", "pending spaces" );
3563 OUString
sExp( rText
.copy( nExpStartPos
, nPos
- nExpStartPos
) );
3564 GetExport().Characters( sExp
);
3565 nExpStartPos
= nPos
;
3568 // If there are spaces left that have not been exported and the
3569 // current character is not a space , the pending spaces have to be
3571 if( nSpaceChars
> 0 && !bCurrCharIsSpace
)
3573 SAL_WARN_IF( nExpStartPos
!= nPos
, "xmloff", " pending characters" );
3575 if( nSpaceChars
> 1 )
3577 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_C
,
3578 OUString::number(nSpaceChars
) );
3581 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
3582 XML_S
, false, false );
3587 // If the current character has to be exported as a special
3588 // element, the element will be exported now.
3589 if( bExpCharAsElement
)
3595 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
3602 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
,
3603 XML_LINE_BREAK
, false,
3610 // If the current character is a space, and the previous one
3611 // is a space, too, the number of pending spaces is incremented
3613 if( bCurrCharIsSpace
&& rPrevCharIsSpace
)
3615 rPrevCharIsSpace
= bCurrCharIsSpace
;
3617 // If the current character is not exported as text, the start
3618 // position for text is the position behind the current position.
3619 if( !bExpCharAsText
)
3621 SAL_WARN_IF( nExpStartPos
!= nPos
, "xmloff", "wrong export start pos" );
3622 nExpStartPos
= nPos
+1;
3626 if( nExpStartPos
< nEndPos
)
3628 SAL_WARN_IF( 0 != nSpaceChars
, "xmloff", " pending spaces " );
3629 OUString
sExp( rText
.copy( nExpStartPos
, nEndPos
- nExpStartPos
) );
3630 GetExport().Characters( sExp
);
3633 // If there are some spaces left, they have to be exported now.
3634 if( nSpaceChars
> 0 )
3636 if( nSpaceChars
> 1 )
3638 GetExport().AddAttribute( XML_NAMESPACE_TEXT
, XML_C
,
3639 OUString::number(nSpaceChars
) );
3642 SvXMLElementExport
aElem( GetExport(), XML_NAMESPACE_TEXT
, XML_S
,
3647 void XMLTextParagraphExport::exportTextDeclarations()
3649 pFieldExport
->ExportFieldDeclarations();
3651 // get XPropertySet from the document and ask for AutoMarkFileURL.
3652 // If it exists, export the auto-mark-file element.
3653 Reference
<XPropertySet
> xPropertySet( GetExport().GetModel(), UNO_QUERY
);
3654 if (!xPropertySet
.is())
3658 OUString
sIndexAutoMarkFileURL(
3659 "IndexAutoMarkFileURL");
3660 if (!xPropertySet
->getPropertySetInfo()->hasPropertyByName(
3661 sIndexAutoMarkFileURL
))
3664 xPropertySet
->getPropertyValue(sIndexAutoMarkFileURL
) >>= sUrl
;
3665 if (!sUrl
.isEmpty())
3667 GetExport().AddAttribute( XML_NAMESPACE_XLINK
, XML_HREF
,
3668 GetExport().GetRelativeReference(sUrl
) );
3669 SvXMLElementExport
aAutoMarkElement(
3670 GetExport(), XML_NAMESPACE_TEXT
,
3671 XML_ALPHABETICAL_INDEX_AUTO_MARK_FILE
,
3676 void XMLTextParagraphExport::exportTextDeclarations(
3677 const Reference
<XText
> & rText
)
3679 pFieldExport
->ExportFieldDeclarations(rText
);
3682 void XMLTextParagraphExport::exportUsedDeclarations()
3684 pFieldExport
->SetExportOnlyUsedFieldDeclarations( false/*bOnlyUsed*/ );
3687 void XMLTextParagraphExport::exportTrackedChanges(bool bAutoStyles
)
3689 if (nullptr != pRedlineExport
)
3690 pRedlineExport
->ExportChangesList( bAutoStyles
);
3693 void XMLTextParagraphExport::exportTrackedChanges(
3694 const Reference
<XText
> & rText
,
3697 if (nullptr != pRedlineExport
)
3698 pRedlineExport
->ExportChangesList(rText
, bAutoStyle
);
3701 void XMLTextParagraphExport::recordTrackedChangesForXText(
3702 const Reference
<XText
> & rText
)
3704 if (nullptr != pRedlineExport
)
3705 pRedlineExport
->SetCurrentXText(rText
);
3708 void XMLTextParagraphExport::recordTrackedChangesNoXText()
3710 if (nullptr != pRedlineExport
)
3711 pRedlineExport
->SetCurrentXText();
3714 void XMLTextParagraphExport::exportTableAutoStyles() {}
3716 void XMLTextParagraphExport::exportTextAutoStyles()
3718 // tdf#135942: do not collect styles during their export: this may modify iterated containers
3720 exportTableAutoStyles();
3722 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_PARAGRAPH
);
3724 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_TEXT
);
3726 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_FRAME
);
3728 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_SECTION
);
3730 GetAutoStylePool().exportXML( XmlStyleFamily::TEXT_RUBY
);
3732 maListAutoPool
.exportXML();
3735 void XMLTextParagraphExport::exportRuby(
3736 const Reference
<XPropertySet
> & rPropSet
,
3739 // early out: a collapsed ruby makes no sense
3740 if (*o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsCollapsed
)))
3744 bool bStart
= *o3tl::doAccess
<bool>(rPropSet
->getPropertyValue(gsIsStart
));
3750 Add( XmlStyleFamily::TEXT_RUBY
, rPropSet
);
3758 // we can only start a ruby if none is open
3759 assert(!bOpenRuby
&& "Can't open a ruby inside of ruby!");
3763 // save ruby text + ruby char style
3764 rPropSet
->getPropertyValue(gsRubyText
) >>= sOpenRubyText
;
3765 rPropSet
->getPropertyValue(gsRubyCharStyleName
) >>= sOpenRubyCharStyle
;
3768 GetExport().CheckAttrList();
3769 OUString
sStyleName(Find(XmlStyleFamily::TEXT_RUBY
, rPropSet
, ""));
3770 SAL_WARN_IF(sStyleName
.isEmpty(), "xmloff", "Can't find ruby style!");
3771 GetExport().AddAttribute(XML_NAMESPACE_TEXT
,
3772 XML_STYLE_NAME
, sStyleName
);
3774 // export <text:ruby> and <text:ruby-base> start elements
3775 GetExport().StartElement( XML_NAMESPACE_TEXT
, XML_RUBY
, false);
3776 GetExport().ClearAttrList();
3777 GetExport().StartElement( XML_NAMESPACE_TEXT
, XML_RUBY_BASE
,
3785 // check for an open ruby
3786 assert(bOpenRuby
&& "Can't close a ruby if none is open!");
3790 // close <text:ruby-base>
3791 GetExport().EndElement(XML_NAMESPACE_TEXT
, XML_RUBY_BASE
,
3794 // write the ruby text (with char style)
3796 if (!sOpenRubyCharStyle
.isEmpty())
3797 GetExport().AddAttribute(
3798 XML_NAMESPACE_TEXT
, XML_STYLE_NAME
,
3799 GetExport().EncodeStyleName( sOpenRubyCharStyle
) );
3801 SvXMLElementExport
aRubyElement(
3802 GetExport(), XML_NAMESPACE_TEXT
, XML_RUBY_TEXT
,
3805 GetExport().Characters(sOpenRubyText
);
3808 // and finally, close the ruby
3809 GetExport().EndElement(XML_NAMESPACE_TEXT
, XML_RUBY
, false);
3815 void XMLTextParagraphExport::exportMeta(
3816 const Reference
<XPropertySet
> & i_xPortion
,
3817 bool i_bAutoStyles
, bool i_isProgress
, bool & rPrevCharIsSpace
)
3819 bool doExport(!i_bAutoStyles
); // do not export element if autostyles
3820 // check version >= 1.2
3821 switch (GetExport().getSaneDefaultVersion()) {
3822 case SvtSaveOptions::ODFSVER_011
: // fall through
3823 case SvtSaveOptions::ODFSVER_010
: doExport
= false; break;
3827 const Reference
< XTextContent
> xTextContent(
3828 i_xPortion
->getPropertyValue("InContentMetadata"), UNO_QUERY_THROW
);
3829 const Reference
< XEnumerationAccess
> xEA( xTextContent
, UNO_QUERY_THROW
);
3830 const Reference
< XEnumeration
> xTextEnum( xEA
->createEnumeration() );
3834 const Reference
<rdf::XMetadatable
> xMeta(xTextContent
, UNO_QUERY_THROW
);
3836 // text:meta with neither xml:id nor RDFa is invalid
3837 xMeta
->ensureMetadataReference();
3839 // xml:id and RDFa for RDF metadata
3840 GetExport().AddAttributeXmlId(xMeta
);
3841 GetExport().AddAttributesRDFa(xTextContent
);
3844 SvXMLElementExport
aElem( GetExport(), doExport
,
3845 XML_NAMESPACE_TEXT
, XML_META
, false, false );
3847 // recurse to export content
3848 exportTextRangeEnumeration(xTextEnum
, i_bAutoStyles
, i_isProgress
, rPrevCharIsSpace
);
3851 void XMLTextParagraphExport::ExportContentControl(
3852 const uno::Reference
<beans::XPropertySet
>& xPortion
, bool bAutoStyles
, bool isProgress
,
3853 bool& rPrevCharIsSpace
)
3855 // Do not export the element in the autostyle case.
3856 bool bExport
= !bAutoStyles
;
3857 if (!(GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
))
3862 uno::Reference
<text::XTextContent
> xTextContent(xPortion
->getPropertyValue("ContentControl"),
3863 uno::UNO_QUERY_THROW
);
3864 uno::Reference
<container::XEnumerationAccess
> xEA(xTextContent
, uno::UNO_QUERY_THROW
);
3865 uno::Reference
<container::XEnumeration
> xTextEnum
= xEA
->createEnumeration();
3867 uno::Reference
<beans::XPropertySet
> xPropertySet(xTextContent
, uno::UNO_QUERY_THROW
);
3870 bool bShowingPlaceHolder
= false;
3871 xPropertySet
->getPropertyValue("ShowingPlaceHolder") >>= bShowingPlaceHolder
;
3872 if (bShowingPlaceHolder
)
3874 OUStringBuffer aBuffer
;
3875 sax::Converter::convertBool(aBuffer
, bShowingPlaceHolder
);
3876 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_SHOWING_PLACE_HOLDER
,
3877 aBuffer
.makeStringAndClear());
3880 bool bCheckbox
= false;
3881 xPropertySet
->getPropertyValue("Checkbox") >>= bCheckbox
;
3884 OUStringBuffer aBuffer
;
3885 sax::Converter::convertBool(aBuffer
, bCheckbox
);
3886 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_CHECKBOX
, aBuffer
.makeStringAndClear());
3889 bool bChecked
= false;
3890 xPropertySet
->getPropertyValue("Checked") >>= bChecked
;
3893 OUStringBuffer aBuffer
;
3894 sax::Converter::convertBool(aBuffer
, bChecked
);
3895 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_CHECKED
, aBuffer
.makeStringAndClear());
3898 OUString aCheckedState
;
3899 xPropertySet
->getPropertyValue("CheckedState") >>= aCheckedState
;
3900 if (!aCheckedState
.isEmpty())
3902 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_CHECKED_STATE
, aCheckedState
);
3905 OUString aUncheckedState
;
3906 xPropertySet
->getPropertyValue("UncheckedState") >>= aUncheckedState
;
3907 if (!aUncheckedState
.isEmpty())
3909 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_UNCHECKED_STATE
, aUncheckedState
);
3912 bool bPicture
= false;
3913 xPropertySet
->getPropertyValue("Picture") >>= bPicture
;
3916 OUStringBuffer aBuffer
;
3917 sax::Converter::convertBool(aBuffer
, bPicture
);
3918 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PICTURE
,
3919 aBuffer
.makeStringAndClear());
3923 xPropertySet
->getPropertyValue("Date") >>= bDate
;
3926 OUStringBuffer aBuffer
;
3927 sax::Converter::convertBool(aBuffer
, bDate
);
3928 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DATE
, aBuffer
.makeStringAndClear());
3931 OUString aDateFormat
;
3932 xPropertySet
->getPropertyValue("DateFormat") >>= aDateFormat
;
3933 if (!aDateFormat
.isEmpty())
3935 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DATE_FORMAT
, aDateFormat
);
3938 OUString aDateLanguage
;
3939 xPropertySet
->getPropertyValue("DateLanguage") >>= aDateLanguage
;
3940 if (!aDateLanguage
.isEmpty())
3942 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DATE_RFC_LANGUAGE_TAG
, aDateLanguage
);
3944 OUString aCurrentDate
;
3945 xPropertySet
->getPropertyValue("CurrentDate") >>= aCurrentDate
;
3946 if (!aCurrentDate
.isEmpty())
3948 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_CURRENT_DATE
, aCurrentDate
);
3951 bool bPlainText
= false;
3952 xPropertySet
->getPropertyValue("PlainText") >>= bPlainText
;
3955 OUStringBuffer aBuffer
;
3956 sax::Converter::convertBool(aBuffer
, bPlainText
);
3957 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_PLAIN_TEXT
, aBuffer
.makeStringAndClear());
3960 bool bComboBox
= false;
3961 xPropertySet
->getPropertyValue("ComboBox") >>= bComboBox
;
3964 OUStringBuffer aBuffer
;
3965 sax::Converter::convertBool(aBuffer
, bComboBox
);
3966 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_COMBOBOX
, aBuffer
.makeStringAndClear());
3969 bool bDropDown
= false;
3970 xPropertySet
->getPropertyValue("DropDown") >>= bDropDown
;
3973 OUStringBuffer aBuffer
;
3974 sax::Converter::convertBool(aBuffer
, bDropDown
);
3975 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DROPDOWN
, aBuffer
.makeStringAndClear());
3979 xPropertySet
->getPropertyValue("Alias") >>= aAlias
;
3980 if (!aAlias
.isEmpty())
3982 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_ALIAS
, aAlias
);
3986 xPropertySet
->getPropertyValue("Tag") >>= aTag
;
3987 if (!aTag
.isEmpty())
3989 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_TAG
, aTag
);
3993 SvXMLElementExport
aElem(GetExport(), bExport
, XML_NAMESPACE_LO_EXT
, XML_CONTENT_CONTROL
, false,
3998 // Export list items of dropdowns.
3999 uno::Sequence
<beans::PropertyValues
> aListItems
;
4000 xPropertySet
->getPropertyValue("ListItems") >>= aListItems
;
4001 for (const auto& rListItem
: aListItems
)
4003 comphelper::SequenceAsHashMap
aMap(rListItem
);
4004 auto it
= aMap
.find("DisplayText");
4006 if (it
!= aMap
.end() && (it
->second
>>= aValue
) && !aValue
.isEmpty())
4008 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_DISPLAY_TEXT
, aValue
);
4011 it
= aMap
.find("Value");
4012 if (it
!= aMap
.end() && (it
->second
>>= aValue
))
4014 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT
, XML_VALUE
, aValue
);
4017 SvXMLElementExport
aItem(GetExport(), bExport
, XML_NAMESPACE_LO_EXT
, XML_LIST_ITEM
, false,
4022 // Recurse to export content.
4023 exportTextRangeEnumeration(xTextEnum
, bAutoStyles
, isProgress
, rPrevCharIsSpace
);
4026 void XMLTextParagraphExport::PreventExportOfControlsInMuteSections(
4027 const Reference
<XIndexAccess
> & rShapes
,
4028 const rtl::Reference
<xmloff::OFormLayerXMLExport
>& xFormExport
)
4030 // check parameters ad pre-conditions
4031 if( ( ! rShapes
.is() ) || ( ! xFormExport
.is() ) )
4033 // if we don't have shapes or a form export, there's nothing to do
4036 SAL_WARN_IF( pSectionExport
== nullptr, "xmloff", "We need the section export." );
4038 Reference
<XEnumeration
> xShapesEnum
= pBoundFrameSets
->GetShapes()->createEnumeration();
4039 if(!xShapesEnum
.is())
4041 while( xShapesEnum
->hasMoreElements() )
4043 // now we need to check
4044 // 1) if this is a control shape, and
4045 // 2) if it's in a mute section
4046 // if both answers are 'yes', notify the form layer export
4048 // we join accessing the shape and testing for control
4049 Reference
<XControlShape
> xControlShape(xShapesEnum
->nextElement(), UNO_QUERY
);
4050 if( xControlShape
.is() )
4052 // Reference<XPropertySet> xPropSet( xControlShape, UNO_QUERY );
4053 // Reference<XTextContent> xTextContent;
4054 // xPropSet->getPropertyValue("TextRange") >>= xTextContent;
4056 Reference
<XTextContent
> xTextContent( xControlShape
, UNO_QUERY
);
4057 if( xTextContent
.is() )
4059 if( pSectionExport
->IsMuteSection( xTextContent
, false ) )
4061 // Ah, we've found a shape that
4062 // 1) is a control shape
4063 // 2) is anchored in a mute section
4064 // so: don't export it!
4065 xFormExport
->excludeFromExport(
4066 xControlShape
->getControl() );
4068 // else: not in mute section -> should be exported -> nothing
4071 // else: no anchor -> ignore
4073 // else: no control shape -> nothing to do
4077 void XMLTextParagraphExport::PushNewTextListsHelper()
4079 maTextListsHelperStack
.emplace_back( new XMLTextListsHelper() );
4080 mpTextListsHelper
= maTextListsHelperStack
.back().get();
4083 void XMLTextParagraphExport::PopTextListsHelper()
4085 mpTextListsHelper
= nullptr;
4086 maTextListsHelperStack
.pop_back();
4087 if ( !maTextListsHelperStack
.empty() )
4089 mpTextListsHelper
= maTextListsHelperStack
.back().get();
4093 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */