LibreOffice Module xmloff (master) 1
txtparae.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <sal/config.h>
21
22#include <o3tl/any.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/beans/UnknownPropertyException.hpp>
36#include <com/sun/star/graphic/XGraphic.hpp>
37#include <com/sun/star/text/XTextDocument.hpp>
38#include <com/sun/star/text/XTextSectionsSupplier.hpp>
39#include <com/sun/star/text/XTextTablesSupplier.hpp>
40#include <com/sun/star/text/XNumberingRulesSupplier.hpp>
41#include <com/sun/star/text/XChapterNumberingSupplier.hpp>
42#include <com/sun/star/text/XTextTable.hpp>
43#include <com/sun/star/text/XText.hpp>
44#include <com/sun/star/text/XTextContent.hpp>
45#include <com/sun/star/text/XTextRange.hpp>
46#include <com/sun/star/text/XTextField.hpp>
47#include <com/sun/star/container/XNamed.hpp>
48#include <com/sun/star/container/XContentEnumerationAccess.hpp>
49#include <com/sun/star/text/XTextFrame.hpp>
50#include <com/sun/star/container/XNameAccess.hpp>
51#include <com/sun/star/text/SizeType.hpp>
52#include <com/sun/star/text/HoriOrientation.hpp>
53#include <com/sun/star/text/VertOrientation.hpp>
54#include <com/sun/star/text/TextContentAnchorType.hpp>
55#include <com/sun/star/text/XTextFramesSupplier.hpp>
56#include <com/sun/star/text/XTextGraphicObjectsSupplier.hpp>
57#include <com/sun/star/text/XTextEmbeddedObjectsSupplier.hpp>
58#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
59#include <com/sun/star/document/XEmbeddedObjectSupplier.hpp>
60#include <com/sun/star/document/XEventsSupplier.hpp>
61#include <com/sun/star/document/XRedlinesSupplier.hpp>
62#include <com/sun/star/text/XFormField.hpp>
63#include <com/sun/star/text/XTextSection.hpp>
64#include <com/sun/star/drawing/XShape.hpp>
65#include <com/sun/star/style/XAutoStylesSupplier.hpp>
66#include <com/sun/star/style/XAutoStyleFamily.hpp>
67#include <com/sun/star/text/XTextFieldsSupplier.hpp>
68#include <com/sun/star/drawing/XControlShape.hpp>
69#include <com/sun/star/util/DateTime.hpp>
70
72
74#include <xmloff/xmlaustp.hxx>
75#include <xmloff/families.hxx>
76#include "txtexppr.hxx"
77#include <xmloff/xmluconv.hxx>
79#include <xexptran.hxx>
82#include <xmloff/xmlexp.hxx>
83#include <txtflde.hxx>
84#include <xmloff/txtprmap.hxx>
85#include <XMLImageMapExport.hxx>
88#include <xmloff/txtparae.hxx>
89#include "XMLSectionExport.hxx"
92#include "XMLRedlineExport.hxx"
96#include <xmloff/odffields.hxx>
97#include <xmloff/maptype.hxx>
101#include <com/sun/star/embed/ElementModes.hpp>
102#include <com/sun/star/embed/XTransactedObject.hpp>
103#include <com/sun/star/document/XStorageBasedDocument.hpp>
104#include <txtlists.hxx>
105#include <com/sun/star/rdf/XMetadatable.hpp>
106#include <list>
107#include <unordered_map>
108#include <memory>
109#include <vector>
110#include <algorithm>
111#include <iterator>
112#include <officecfg/Office/Common.hxx>
113#include <o3tl/safeint.hxx>
116
117using namespace ::com::sun::star;
118using namespace ::com::sun::star::uno;
119using namespace ::com::sun::star::lang;
120using namespace ::com::sun::star::beans;
121using namespace ::com::sun::star::container;
122using namespace ::com::sun::star::text;
123using namespace ::com::sun::star::style;
124using namespace ::com::sun::star::util;
125using namespace ::com::sun::star::drawing;
126using namespace ::com::sun::star::document;
127using namespace ::com::sun::star::graphic;
128using namespace ::xmloff;
129using namespace ::xmloff::token;
130
131// Implement Title/Description Elements UI (#i73249#)
132constexpr OUStringLiteral gsTitle(u"Title");
133constexpr OUStringLiteral gsDescription(u"Description");
134constexpr OUStringLiteral gsAnchorPageNo(u"AnchorPageNo");
135constexpr OUStringLiteral gsAnchorType(u"AnchorType");
136constexpr OUStringLiteral gsBookmark(u"Bookmark");
137constexpr OUStringLiteral gsChainNextName(u"ChainNextName");
138constexpr OUStringLiteral gsContourPolyPolygon(u"ContourPolyPolygon");
139constexpr OUStringLiteral gsDocumentIndexMark(u"DocumentIndexMark");
140constexpr OUStringLiteral gsFrame(u"Frame");
141constexpr OUStringLiteral gsGraphicFilter(u"GraphicFilter");
142constexpr OUStringLiteral gsGraphicRotation(u"GraphicRotation");
143constexpr OUStringLiteral gsHeight(u"Height");
144constexpr OUStringLiteral gsHoriOrient(u"HoriOrient");
145constexpr OUStringLiteral gsHoriOrientPosition(u"HoriOrientPosition");
146constexpr OUStringLiteral gsHyperLinkName(u"HyperLinkName");
147constexpr OUStringLiteral gsHyperLinkTarget(u"HyperLinkTarget");
148constexpr OUStringLiteral gsHyperLinkURL(u"HyperLinkURL");
149constexpr OUStringLiteral gsIsAutomaticContour(u"IsAutomaticContour");
150constexpr OUStringLiteral gsIsCollapsed(u"IsCollapsed");
151constexpr OUStringLiteral gsIsPixelContour(u"IsPixelContour");
152constexpr OUStringLiteral gsIsStart(u"IsStart");
153constexpr OUStringLiteral gsIsSyncHeightToWidth(u"IsSyncHeightToWidth");
154constexpr OUStringLiteral gsIsSyncWidthToHeight(u"IsSyncWidthToHeight");
155constexpr OUStringLiteral gsNumberingRules(u"NumberingRules");
156constexpr OUStringLiteral gsParaConditionalStyleName(u"ParaConditionalStyleName");
157constexpr OUStringLiteral gsParagraphService(u"com.sun.star.text.Paragraph");
158constexpr OUStringLiteral gsRedline(u"Redline");
159constexpr OUStringLiteral gsReferenceMark(u"ReferenceMark");
160constexpr OUStringLiteral gsRelativeHeight(u"RelativeHeight");
161constexpr OUStringLiteral gsRelativeWidth(u"RelativeWidth");
162constexpr OUStringLiteral gsRuby(u"Ruby");
163constexpr OUStringLiteral gsRubyCharStyleName(u"RubyCharStyleName");
164constexpr OUStringLiteral gsRubyText(u"RubyText");
165constexpr OUStringLiteral gsServerMap(u"ServerMap");
166constexpr OUStringLiteral gsShapeService(u"com.sun.star.drawing.Shape");
167constexpr OUStringLiteral gsSizeType(u"SizeType");
168constexpr OUStringLiteral gsSoftPageBreak( u"SoftPageBreak" );
169constexpr OUStringLiteral gsTableService(u"com.sun.star.text.TextTable");
170constexpr OUStringLiteral gsText(u"Text");
171constexpr OUStringLiteral gsTextContentService(u"com.sun.star.text.TextContent");
172constexpr OUStringLiteral gsTextEmbeddedService(u"com.sun.star.text.TextEmbeddedObject");
173constexpr OUStringLiteral gsTextField(u"TextField");
174constexpr OUStringLiteral gsTextFieldService(u"com.sun.star.text.TextField");
175constexpr OUStringLiteral gsTextFrameService(u"com.sun.star.text.TextFrame");
176constexpr OUStringLiteral gsTextGraphicService(u"com.sun.star.text.TextGraphicObject");
177constexpr OUStringLiteral gsTextPortionType(u"TextPortionType");
178constexpr OUStringLiteral gsUnvisitedCharStyleName(u"UnvisitedCharStyleName");
179constexpr OUStringLiteral gsVertOrient(u"VertOrient");
180constexpr OUStringLiteral gsVertOrientPosition(u"VertOrientPosition");
181constexpr OUStringLiteral gsVisitedCharStyleName(u"VisitedCharStyleName");
182constexpr OUStringLiteral gsWidth(u"Width");
183constexpr OUStringLiteral gsWidthType( u"WidthType" );
184constexpr OUStringLiteral gsTextFieldStart( u"TextFieldStart" );
185constexpr OUStringLiteral gsTextFieldSep(u"TextFieldSeparator");
186constexpr OUStringLiteral gsTextFieldEnd( u"TextFieldEnd" );
187constexpr OUStringLiteral gsTextFieldStartEnd( u"TextFieldStartEnd" );
188
189namespace
190{
191 class TextContentSet
192 {
193 public:
194 typedef std::list<Reference<XTextContent>> contents_t;
195 typedef std::back_insert_iterator<contents_t> inserter_t;
196 typedef contents_t::const_iterator const_iterator_t;
197
198 inserter_t getInserter()
199 { return std::back_insert_iterator<contents_t>(m_vTextContents); };
200 const_iterator_t getBegin() const
201 { return m_vTextContents.begin(); };
202 const_iterator_t getEnd() const
203 { return m_vTextContents.end(); };
204
205 private:
206 contents_t m_vTextContents;
207 };
208
209 struct FrameRefHash
210 {
211 size_t operator()(const Reference<XTextFrame>& rFrame) const
212 { return sal::static_int_cast<size_t>(reinterpret_cast<sal_uIntPtr>(rFrame.get())); }
213 };
214
215 bool lcl_TextContentsUnfiltered(const Reference<XTextContent>&)
216 { return true; };
217
218 bool lcl_ShapeFilter(const Reference<XTextContent>& xTxtContent)
219 {
220 Reference<XShape> xShape(xTxtContent, UNO_QUERY);
221 if(!xShape.is())
222 return false;
223 Reference<XServiceInfo> xServiceInfo(xTxtContent, UNO_QUERY);
224 return !xServiceInfo->supportsService("com.sun.star.text.TextFrame") &&
225 !xServiceInfo->supportsService("com.sun.star.text.TextGraphicObject") &&
226 !xServiceInfo->supportsService("com.sun.star.text.TextEmbeddedObject");
227 };
228
229 class BoundFrames
230 {
231 public:
232 typedef bool (*filter_t)(const Reference<XTextContent>&);
233 BoundFrames(
234 const Reference<XEnumerationAccess>& rEnumAccess,
235 const filter_t& rFilter)
236 : m_xEnumAccess(rEnumAccess)
237 {
238 Fill(rFilter);
239 };
240 BoundFrames()
241 {};
242 const TextContentSet& GetPageBoundContents() const
243 { return m_vPageBounds; };
244 const TextContentSet* GetFrameBoundContents(const Reference<XTextFrame>& rParentFrame) const
245 {
246 framebound_map_t::const_iterator it = m_vFrameBoundsOf.find(rParentFrame);
247 if(it == m_vFrameBoundsOf.end())
248 return nullptr;
249 return &(it->second);
250 };
251 Reference<XEnumeration> createEnumeration() const
252 {
253 if(!m_xEnumAccess.is())
254 return Reference<XEnumeration>();
255 return m_xEnumAccess->createEnumeration();
256 };
257
258 private:
259 typedef std::unordered_map<
260 Reference<XTextFrame>,
261 TextContentSet,
262 FrameRefHash> framebound_map_t;
263 TextContentSet m_vPageBounds;
264 framebound_map_t m_vFrameBoundsOf;
265 const Reference<XEnumerationAccess> m_xEnumAccess;
266 void Fill(const filter_t& rFilter);
267 };
268
269 class FieldParamExporter
270 {
271 public:
272 FieldParamExporter(SvXMLExport* const pExport, Reference<XNameContainer> const & xFieldParams)
273 : m_pExport(pExport)
274 , m_xFieldParams(xFieldParams)
275 { };
276 void Export();
277
278 private:
279 SvXMLExport* const m_pExport;
280 const Reference<XNameContainer> m_xFieldParams;
281
282 void ExportParameter(const OUString& sKey, const OUString& sValue);
283 };
284
285 struct HyperlinkData
286 {
287 OUString href, name, targetFrame, ustyleName, vstyleName;
288 bool serverMap = false;
289 css::uno::Reference<css::container::XNameReplace> events;
290
291 HyperlinkData() = default;
292 HyperlinkData(const css::uno::Reference<css::beans::XPropertySet>& rPropSet);
293
294 bool operator==(const HyperlinkData&);
295 bool operator!=(const HyperlinkData& rOther) { return !operator==(rOther); }
296
297 bool addHyperlinkAttributes(SvXMLExport& rExport);
298 void exportEvents(SvXMLExport& rExport);
299 };
300
301 HyperlinkData::HyperlinkData(const css::uno::Reference<css::beans::XPropertySet>& rPropSet)
302 {
303 const css::uno::Reference<css::beans::XPropertyState> xPropState(rPropSet, UNO_QUERY);
304 const auto xPropSetInfo(rPropSet->getPropertySetInfo());
305 if (xPropSetInfo->hasPropertyByName(gsHyperLinkURL)
306 && (!xPropState.is()
307 || PropertyState_DIRECT_VALUE == xPropState->getPropertyState(gsHyperLinkURL)))
308 {
309 rPropSet->getPropertyValue(gsHyperLinkURL) >>= href;
310 }
311
312 if (href.isEmpty())
313 return;
314
315 if (xPropSetInfo->hasPropertyByName(gsHyperLinkName)
316 && (!xPropState.is()
317 || PropertyState_DIRECT_VALUE == xPropState->getPropertyState(gsHyperLinkName)))
318 {
319 rPropSet->getPropertyValue(gsHyperLinkName) >>= name;
320 }
321
322 if (xPropSetInfo->hasPropertyByName(gsHyperLinkTarget)
323 && (!xPropState.is()
324 || PropertyState_DIRECT_VALUE == xPropState->getPropertyState(gsHyperLinkTarget)))
325 {
326 rPropSet->getPropertyValue(gsHyperLinkTarget) >>= targetFrame;
327 }
328
329 if (xPropSetInfo->hasPropertyByName(gsServerMap)
330 && (!xPropState.is()
331 || PropertyState_DIRECT_VALUE == xPropState->getPropertyState(gsServerMap)))
332 {
333 serverMap = *o3tl::doAccess<bool>(rPropSet->getPropertyValue(gsServerMap));
334 }
335
336 if (xPropSetInfo->hasPropertyByName(gsUnvisitedCharStyleName)
337 && (!xPropState.is()
338 || PropertyState_DIRECT_VALUE
339 == xPropState->getPropertyState(gsUnvisitedCharStyleName)))
340 {
341 rPropSet->getPropertyValue(gsUnvisitedCharStyleName) >>= ustyleName;
342 }
343
344 if (xPropSetInfo->hasPropertyByName(gsVisitedCharStyleName)
345 && (!xPropState.is()
346 || PropertyState_DIRECT_VALUE
347 == xPropState->getPropertyState(gsVisitedCharStyleName)))
348 {
349 rPropSet->getPropertyValue(gsVisitedCharStyleName) >>= vstyleName;
350 }
351
352 static constexpr OUStringLiteral sHyperLinkEvents(u"HyperLinkEvents");
353 if (xPropSetInfo->hasPropertyByName(sHyperLinkEvents))
354 {
355 events.set(rPropSet->getPropertyValue(sHyperLinkEvents), uno::UNO_QUERY);
356 }
357 }
358
359 bool HyperlinkData::operator==(const HyperlinkData& rOther)
360 {
361 if (href != rOther.href || name != rOther.name || targetFrame != rOther.targetFrame
362 || ustyleName != rOther.ustyleName || vstyleName != rOther.vstyleName
363 || serverMap != rOther.serverMap)
364 return false;
365
366 if (events == rOther.events)
367 return true;
368 if (!events || !rOther.events)
369 return false;
370
371 const css::uno::Sequence<OUString> aNames = events->getElementNames();
372 if (aNames != rOther.events->getElementNames())
373 return false;
374 for (const auto& rName : aNames)
375 {
376 const css::uno::Any aAny = events->getByName(rName);
377 const css::uno::Any aOtherAny = rOther.events->getByName(rName);
378 if (aAny != aOtherAny)
379 return false;
380 }
381 return true;
382 }
383
384 bool HyperlinkData::addHyperlinkAttributes(SvXMLExport& rExport)
385 {
386 if (href.isEmpty())
387 {
388 // hyperlink without a URL does not make sense
389 OSL_ENSURE(false, "hyperlink without a URL --> no export to ODF");
390 return false;
391 }
392
395
396 if (!name.isEmpty())
398
399 if (!targetFrame.isEmpty())
400 {
402 enum XMLTokenEnum eTok = targetFrame == "_blank" ? XML_NEW : XML_REPLACE;
404 }
405
406 if (serverMap)
408
409 if (!ustyleName.isEmpty())
411 rExport.EncodeStyleName(ustyleName));
412
413 if (!vstyleName.isEmpty())
415 rExport.EncodeStyleName(vstyleName));
416
417 return true;
418 }
419
420 void HyperlinkData::exportEvents(SvXMLExport& rExport)
421 {
422 // export events (if supported)
423 if (events)
424 rExport.GetEventExport().Export(events, false);
425 }
426}
427
428namespace xmloff
429{
431 {
432 public:
433 explicit BoundFrameSets(const Reference<XInterface>& rModel);
434 const BoundFrames* GetTexts() const
435 { return m_pTexts.get(); };
436 const BoundFrames* GetGraphics() const
437 { return m_pGraphics.get(); };
438 const BoundFrames* GetEmbeddeds() const
439 { return m_pEmbeddeds.get(); };
440 const BoundFrames* GetShapes() const
441 { return m_pShapes.get(); };
442 private:
443 std::unique_ptr<BoundFrames> m_pTexts;
444 std::unique_ptr<BoundFrames> m_pGraphics;
445 std::unique_ptr<BoundFrames> m_pEmbeddeds;
446 std::unique_ptr<BoundFrames> m_pShapes;
447 };
448}
449
450#ifdef DBG_UTIL
452#endif
453
454// The following map shows which property values are required:
455
456// property auto style pass export
457
458// ParaStyleName if style exists always
459// ParaConditionalStyleName if style exists always
460// NumberingRules if style exists always
461// TextSection always always
462// ParaChapterNumberingLevel never always
463// NumberingIsNumber never always
464
465// The conclusion is that for auto styles the first three properties
466// should be queried using a multi property set if, and only if, an
467// auto style needs to be exported. TextSection should be queried by
468// an individual call to getPropertyvalue, because this seems to be
469// less expensive than querying the first three properties if they aren't
470// required.
471
472// For the export pass all properties can be queried using a multi property
473// set.
474
475static const char* aParagraphPropertyNamesAuto[] =
476{
477 "NumberingRules",
478 "ParaConditionalStyleName",
479 "ParaStyleName",
480 nullptr
481};
482
483namespace {
484
485enum eParagraphPropertyNamesEnumAuto
486{
487 NUMBERING_RULES_AUTO = 0,
488 PARA_CONDITIONAL_STYLE_NAME_AUTO = 1,
489 PARA_STYLE_NAME_AUTO = 2
490};
491
492}
493
494static const char* aParagraphPropertyNames[] =
495{
496 "NumberingIsNumber",
497 "NumberingStyleName",
498 "OutlineLevel",
499 "ParaConditionalStyleName",
500 "ParaStyleName",
501 "TextSection",
502 "OutlineContentVisible",
503 nullptr
504};
505
506namespace {
507
508enum eParagraphPropertyNamesEnum
509{
510 NUMBERING_IS_NUMBER = 0,
511 PARA_NUMBERING_STYLENAME = 1,
512 PARA_OUTLINE_LEVEL=2,
513 PARA_CONDITIONAL_STYLE_NAME = 3,
514 PARA_STYLE_NAME = 4,
515 TEXT_SECTION = 5,
516 PARA_OUTLINE_CONTENT_VISIBLE = 6
517};
518
519}
520
521void BoundFrames::Fill(const filter_t& rFilter)
522{
523 if(!m_xEnumAccess.is())
524 return;
525 const Reference< XEnumeration > xEnum = m_xEnumAccess->createEnumeration();
526 if(!xEnum.is())
527 return;
528 static constexpr OUStringLiteral our_sAnchorType(u"AnchorType");
529 static constexpr OUStringLiteral our_sAnchorFrame(u"AnchorFrame");
530 while(xEnum->hasMoreElements())
531 {
532 Reference<XPropertySet> xPropSet(xEnum->nextElement(), UNO_QUERY);
533 Reference<XTextContent> xTextContent(xPropSet, UNO_QUERY);
534 if(!xPropSet.is() || !xTextContent.is())
535 continue;
536 TextContentAnchorType eAnchor;
537 xPropSet->getPropertyValue(our_sAnchorType) >>= eAnchor;
538 if(TextContentAnchorType_AT_PAGE != eAnchor && TextContentAnchorType_AT_FRAME != eAnchor)
539 continue;
540 if(!rFilter(xTextContent))
541 continue;
542
543 TextContentSet::inserter_t pInserter = m_vPageBounds.getInserter();
544 if(TextContentAnchorType_AT_FRAME == eAnchor)
545 {
546 Reference<XTextFrame> xAnchorTxtFrame(
547 xPropSet->getPropertyValue(our_sAnchorFrame),
548 uno::UNO_QUERY);
549 pInserter = m_vFrameBoundsOf[xAnchorTxtFrame].getInserter();
550 }
551 *pInserter++ = xTextContent;
552 }
553}
554
555BoundFrameSets::BoundFrameSets(const Reference<XInterface>& rModel)
556 : m_pTexts(new BoundFrames())
557 , m_pGraphics(new BoundFrames())
558 , m_pEmbeddeds(new BoundFrames())
559 , m_pShapes(new BoundFrames())
560{
561 const Reference<XTextFramesSupplier> xTFS(rModel, UNO_QUERY);
562 const Reference<XTextGraphicObjectsSupplier> xGOS(rModel, UNO_QUERY);
563 const Reference<XTextEmbeddedObjectsSupplier> xEOS(rModel, UNO_QUERY);
564 const Reference<XDrawPageSupplier> xDPS(rModel, UNO_QUERY);
565 if(xTFS.is())
566 m_pTexts.reset(new BoundFrames(
567 Reference<XEnumerationAccess>(xTFS->getTextFrames(), UNO_QUERY),
568 &lcl_TextContentsUnfiltered));
569 if(xGOS.is())
570 m_pGraphics.reset(new BoundFrames(
571 Reference<XEnumerationAccess>(xGOS->getGraphicObjects(), UNO_QUERY),
572 &lcl_TextContentsUnfiltered));
573 if(xEOS.is())
574 m_pEmbeddeds.reset(new BoundFrames(
575 Reference<XEnumerationAccess>(xEOS->getEmbeddedObjects(), UNO_QUERY),
576 &lcl_TextContentsUnfiltered));
577 if(xDPS.is())
578 m_pShapes.reset(new BoundFrames(
579 Reference<XEnumerationAccess>(xDPS->getDrawPage(), UNO_QUERY),
580 &lcl_ShapeFilter));
581};
582
583void FieldParamExporter::Export()
584{
585 const Type aStringType = ::cppu::UnoType<OUString>::get();
586 const Type aBoolType = cppu::UnoType<sal_Bool>::get();
587 const Type aSeqType = cppu::UnoType<Sequence<OUString>>::get();
588 const Type aIntType = ::cppu::UnoType<sal_Int32>::get();
589 const Sequence<OUString> vParameters(m_xFieldParams->getElementNames());
590 for(const auto & rParameter : vParameters)
591 {
592 const Any aValue = m_xFieldParams->getByName(rParameter);
593 const Type& aValueType = aValue.getValueType();
594 if(aValueType == aStringType)
595 {
596 OUString sValue;
597 aValue >>= sValue;
598 ExportParameter(rParameter,sValue);
599
600 if ( rParameter == ODF_OLE_PARAM )
601 {
602 // Save the OLE object
603 Reference< embed::XStorage > xTargetStg = m_pExport->GetTargetStorage();
604 if (xTargetStg.is()) {
605 Reference< embed::XStorage > xDstStg = xTargetStg->openStorageElement(
606 "OLELinks", embed::ElementModes::WRITE );
607
608 if ( !xDstStg->hasByName( sValue ) ) {
609 Reference< XStorageBasedDocument > xStgDoc (
610 m_pExport->GetModel( ), UNO_QUERY );
611 Reference< embed::XStorage > xDocStg = xStgDoc->getDocumentStorage();
612 Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement(
613 "OLELinks", embed::ElementModes::READ );
614
615 xOleStg->copyElementTo( sValue, xDstStg, sValue );
616 Reference< embed::XTransactedObject > xTransact( xDstStg, UNO_QUERY );
617 if ( xTransact.is( ) )
618 xTransact->commit( );
619 }
620 } else {
621 SAL_WARN("xmloff", "no target storage");
622 }
623 }
624 }
625 else if(aValueType == aBoolType)
626 {
627 bool bValue = false;
628 aValue >>= bValue;
629 ExportParameter(rParameter, OUString::boolean(bValue) );
630 }
631 else if(aValueType == aSeqType)
632 {
633 Sequence<OUString> vValue;
634 aValue >>= vValue;
635 for(const OUString & i : std::as_const(vValue))
636 {
637 ExportParameter(rParameter, i);
638 }
639 }
640 else if(aValueType == aIntType)
641 {
642 sal_Int32 nValue = 0;
643 aValue >>= nValue;
644 ExportParameter(rParameter, OUString::number(nValue));
645 }
646 }
647}
648
649void FieldParamExporter::ExportParameter(const OUString& sKey, const OUString& sValue)
650{
651 m_pExport->AddAttribute(XML_NAMESPACE_FIELD, XML_NAME, sKey);
652 m_pExport->AddAttribute(XML_NAMESPACE_FIELD, XML_VALUE, sValue);
653 m_pExport->StartElement(XML_NAMESPACE_FIELD, XML_PARAM, false);
654 m_pExport->EndElement(XML_NAMESPACE_FIELD, XML_PARAM, false);
655}
656
658 const Reference < XPropertySet > & rPropSet,
659 const o3tl::span<const XMLPropertyState> aAddStates,
660 bool bDontSeek )
661{
663 switch( nFamily )
664 {
666 xPropMapper = GetParaPropMapper();
667 break;
669 xPropMapper = GetTextPropMapper();
670 break;
672 xPropMapper = GetAutoFramePropMapper();
673 break;
675 xPropMapper = GetSectionPropMapper();
676 break;
678 xPropMapper = GetRubyPropMapper();
679 break;
680 default: break;
681 }
682 SAL_WARN_IF( !xPropMapper.is(), "xmloff", "There is the property mapper?" );
683
684 std::vector< XMLPropertyState > aPropStates =
685 xPropMapper->Filter(GetExport(), rPropSet);
686
687 aPropStates.insert( aPropStates.end(), aAddStates.begin(), aAddStates.end() );
688
689 if( aPropStates.empty() )
690 return;
691
692 Reference< XPropertySetInfo > xPropSetInfo(rPropSet->getPropertySetInfo());
693 OUString sParent, sCondParent;
694 switch( nFamily )
695 {
697 if( xPropSetInfo->hasPropertyByName( gsParaStyleName ) )
698 {
699 rPropSet->getPropertyValue( gsParaStyleName ) >>= sParent;
700 }
701 if( xPropSetInfo->hasPropertyByName( gsParaConditionalStyleName ) )
702 {
703 rPropSet->getPropertyValue( gsParaConditionalStyleName ) >>= sCondParent;
704 }
705 if( xPropSetInfo->hasPropertyByName( gsNumberingRules ) )
706 {
707 Reference < XIndexReplace > xNumRule(rPropSet->getPropertyValue( gsNumberingRules ), uno::UNO_QUERY);
708 if( xNumRule.is() && xNumRule->getCount() )
709 {
710 Reference < XNamed > xNamed( xNumRule, UNO_QUERY );
711 OUString sName;
712 if( xNamed.is() )
713 sName = xNamed->getName();
714 bool bAdd = sName.isEmpty();
715 if( !bAdd )
716 {
717 Reference < XPropertySet > xNumPropSet( xNumRule,
718 UNO_QUERY );
719 if( xNumPropSet.is() &&
720 xNumPropSet->getPropertySetInfo()
721 ->hasPropertyByName( "IsAutomatic" ) )
722 {
723 bAdd = *o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "IsAutomatic" ));
724 // Check on outline style (#i73361#)
725 if ( bAdd &&
726 xNumPropSet->getPropertySetInfo()
727 ->hasPropertyByName( "NumberingIsOutline" ) )
728 {
729 bAdd = !(*o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "NumberingIsOutline" )));
730 }
731 }
732 else
733 {
734 bAdd = true;
735 }
736 }
737 if( bAdd )
738 maListAutoPool.Add( xNumRule );
739 }
740 }
741 break;
743 {
744 // Get parent and remove hyperlinks (they aren't of interest)
745 rtl::Reference< XMLPropertySetMapper > xPM(xPropMapper->getPropertySetMapper());
746 sal_uInt16 nIgnoreProps = 0;
747 for( ::std::vector< XMLPropertyState >::iterator i(aPropStates.begin());
748 nIgnoreProps < 2 && i != aPropStates.end(); )
749 {
750 if( i->mnIndex == -1 )
751 {
752 ++i;
753 continue;
754 }
755
756 switch( xPM->GetEntryContextId(i->mnIndex) )
757 {
760 i->mnIndex = -1;
761 nIgnoreProps++;
762 i = aPropStates.erase( i );
763 break;
764 default:
765 ++i;
766 break;
767 }
768 }
769 }
770 break;
772 if( xPropSetInfo->hasPropertyByName( gsFrameStyleName ) )
773 {
774 rPropSet->getPropertyValue( gsFrameStyleName ) >>= sParent;
775 }
776 break;
779 ; // section styles have no parents
780 break;
781 default: break;
782 }
783 if (aPropStates.size()) // could change after the previous check
784 {
785 GetAutoStylePool().Add( nFamily, sParent, std::vector(aPropStates), bDontSeek );
786 if( !sCondParent.isEmpty() && sParent != sCondParent )
787 GetAutoStylePool().Add( nFamily, sCondParent, std::move(aPropStates) );
788 }
789}
790
791static bool lcl_validPropState( const XMLPropertyState& rState )
792{
793 return rState.mnIndex != -1;
794}
795
797 MultiPropertySetHelper& rPropSetHelper,
798 const Reference < XPropertySet > & rPropSet)
799{
801 switch( nFamily )
802 {
804 xPropMapper = GetParaPropMapper();
805 break;
806 default: break;
807 }
808 SAL_WARN_IF( !xPropMapper.is(), "xmloff", "There is the property mapper?" );
809
810 std::vector<XMLPropertyState> aPropStates(xPropMapper->Filter(GetExport(), rPropSet));
811
812 if( rPropSetHelper.hasProperty( NUMBERING_RULES_AUTO ) )
813 {
814 Reference < XIndexReplace > xNumRule(rPropSetHelper.getValue( NUMBERING_RULES_AUTO,
815 rPropSet, true ), uno::UNO_QUERY);
816 if( xNumRule.is() && xNumRule->getCount() )
817 {
818 Reference < XNamed > xNamed( xNumRule, UNO_QUERY );
819 OUString sName;
820 if( xNamed.is() )
821 sName = xNamed->getName();
822 bool bAdd = sName.isEmpty();
823 if( !bAdd )
824 {
825 Reference < XPropertySet > xNumPropSet( xNumRule,
826 UNO_QUERY );
827 if( xNumPropSet.is() &&
828 xNumPropSet->getPropertySetInfo()
829 ->hasPropertyByName( "IsAutomatic" ) )
830 {
831 bAdd = *o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "IsAutomatic" ));
832 // Check on outline style (#i73361#)
833 if ( bAdd &&
834 xNumPropSet->getPropertySetInfo()
835 ->hasPropertyByName( "NumberingIsOutline" ) )
836 {
837 bAdd = !(*o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "NumberingIsOutline" )));
838 }
839 }
840 else
841 {
842 bAdd = true;
843 }
844 }
845 if( bAdd )
846 maListAutoPool.Add( xNumRule );
847 }
848 }
849
850 if( aPropStates.empty() )
851 return;
852
853 OUString sParent, sCondParent;
854 switch( nFamily )
855 {
857 if( rPropSetHelper.hasProperty( PARA_STYLE_NAME_AUTO ) )
858 {
859 rPropSetHelper.getValue( PARA_STYLE_NAME_AUTO, rPropSet,
860 true ) >>= sParent;
861 }
862 if( rPropSetHelper.hasProperty( PARA_CONDITIONAL_STYLE_NAME_AUTO ) )
863 {
864 rPropSetHelper.getValue( PARA_CONDITIONAL_STYLE_NAME_AUTO,
865 rPropSet, true ) >>= sCondParent;
866 }
867
868 break;
869 default: break;
870 }
871
872 if( std::any_of( aPropStates.begin(), aPropStates.end(), lcl_validPropState ) )
873 {
874 GetAutoStylePool().Add( nFamily, sParent, std::vector(aPropStates) );
875 if( !sCondParent.isEmpty() && sParent != sCondParent )
876 GetAutoStylePool().Add( nFamily, sCondParent, std::move(aPropStates) );
877 }
878}
879
881 XmlStyleFamily nFamily,
882 const Reference < XPropertySet > & rPropSet,
883 const OUString& rParent,
884 const o3tl::span<const XMLPropertyState> aAddStates) const
885{
886 OUString sName( rParent );
888 switch( nFamily )
889 {
891 xPropMapper = GetParaPropMapper();
892 break;
894 xPropMapper = GetAutoFramePropMapper();
895 break;
897 xPropMapper = GetSectionPropMapper();
898 break;
900 xPropMapper = GetRubyPropMapper();
901 break;
902 default: break;
903 }
904 SAL_WARN_IF( !xPropMapper.is(), "xmloff", "There is the property mapper?" );
905 if( !xPropMapper.is() )
906 return sName;
907 std::vector<XMLPropertyState> aPropStates(xPropMapper->Filter(GetExport(), rPropSet));
908 aPropStates.insert( aPropStates.end(), aAddStates.begin(), aAddStates.end() );
909 if( std::any_of( aPropStates.begin(), aPropStates.end(), lcl_validPropState ) )
910 sName = GetAutoStylePool().Find( nFamily, sName, aPropStates );
911
912 return sName;
913}
914
916 const Reference < XPropertySet > & rPropSet,
917 bool& rbHasCharStyle,
918 bool& rbHasAutoStyle,
919 const XMLPropertyState** ppAddStates ) const
920{
921 rtl::Reference < SvXMLExportPropertyMapper > xPropMapper(GetTextPropMapper());
922 std::vector<XMLPropertyState> aPropStates(xPropMapper->Filter(GetExport(), rPropSet));
923
924 // Get parent and remove hyperlinks (they aren't of interest)
925 OUString sName;
926 rbHasCharStyle = rbHasAutoStyle = false;
927 sal_uInt16 nIgnoreProps = 0;
928 rtl::Reference< XMLPropertySetMapper > xPM(xPropMapper->getPropertySetMapper());
929 ::std::vector< XMLPropertyState >::iterator aFirstDel = aPropStates.end();
930 ::std::vector< XMLPropertyState >::iterator aSecondDel = aPropStates.end();
931
932 for( ::std::vector< XMLPropertyState >::iterator
933 i = aPropStates.begin();
934 nIgnoreProps < 2 && i != aPropStates.end();
935 ++i )
936 {
937 if( i->mnIndex == -1 )
938 continue;
939
940 switch( xPM->GetEntryContextId(i->mnIndex) )
941 {
943 i->maValue >>= sName;
944 i->mnIndex = -1;
945 rbHasCharStyle = !sName.isEmpty();
946 if( nIgnoreProps )
947 aSecondDel = i;
948 else
949 aFirstDel = i;
950 nIgnoreProps++;
951 break;
953 i->mnIndex = -1;
954 if( nIgnoreProps )
955 aSecondDel = i;
956 else
957 aFirstDel = i;
958 nIgnoreProps++;
959 break;
960 }
961 }
962 if( ppAddStates )
963 {
964 while( *ppAddStates )
965 {
966 aPropStates.push_back( **ppAddStates );
967 ppAddStates++;
968 }
969 }
970 if (aPropStates.size() - nIgnoreProps)
971 {
972 // erase the character style, otherwise the autostyle cannot be found!
973 // erase the hyperlink, otherwise the autostyle cannot be found!
974 if ( nIgnoreProps )
975 {
976 // If two elements of a vector have to be deleted,
977 // we should delete the second one first.
978 if( --nIgnoreProps )
979 aPropStates.erase( aSecondDel );
980 aPropStates.erase( aFirstDel );
981 }
982 sName = GetAutoStylePool().Find(
984 OUString(), // AutoStyles should not have parents!
985 aPropStates );
986 rbHasAutoStyle = true;
987 }
988
989 return sName;
990}
991
992// adjustments to support lists independent from list style
994 const XMLTextNumRuleInfo& rPrevInfo,
995 const XMLTextNumRuleInfo& rNextInfo )
996{
997 // end a list
998 if ( rPrevInfo.GetLevel() > 0 )
999 {
1000 sal_uInt32 nListLevelsToBeClosed = 0; // unsigned larger type to safely multiply and compare
1001 if ( !rNextInfo.BelongsToSameList( rPrevInfo ) ||
1002 rNextInfo.GetLevel() <= 0 )
1003 {
1004 // close complete previous list
1005 nListLevelsToBeClosed = rPrevInfo.GetLevel();
1006 }
1007 else if ( rPrevInfo.GetLevel() > rNextInfo.GetLevel() )
1008 {
1009 // close corresponding sub lists
1010 nListLevelsToBeClosed = rPrevInfo.GetLevel() - rNextInfo.GetLevel();
1011 }
1012
1013 if ( nListLevelsToBeClosed > 0 &&
1014 maListElements.size() >= 2 * nListLevelsToBeClosed )
1015 {
1016 do {
1017 for(size_t j = 0; j < 2; ++j)
1018 {
1019 OUString aElem(maListElements.back());
1020 maListElements.pop_back();
1021 GetExport().EndElement(aElem, true);
1022 }
1023
1024 // remove closed list from list stack
1025 mpTextListsHelper->PopListFromStack();
1026
1027 --nListLevelsToBeClosed;
1028 } while ( nListLevelsToBeClosed > 0 );
1029 }
1030 }
1031
1032 // start a new list
1033 if ( rNextInfo.GetLevel() > 0 )
1034 {
1035 bool bRootListToBeStarted = false;
1036 sal_Int16 nListLevelsToBeOpened = 0;
1037 if ( !rPrevInfo.BelongsToSameList( rNextInfo ) ||
1038 rPrevInfo.GetLevel() <= 0 )
1039 {
1040 // new root list
1041 bRootListToBeStarted = true;
1042 nListLevelsToBeOpened = rNextInfo.GetLevel();
1043 }
1044 else if ( rNextInfo.GetLevel() > rPrevInfo.GetLevel() )
1045 {
1046 // open corresponding sub lists
1047 nListLevelsToBeOpened = rNextInfo.GetLevel() - rPrevInfo.GetLevel();
1048 }
1049
1050 if ( nListLevelsToBeOpened > 0 )
1051 {
1052 const OUString& sListStyleName( rNextInfo.GetNumRulesName() );
1053 // Currently only the text documents support <ListId>.
1054 // Thus, for other document types <sListId> is empty.
1055 const OUString& sListId( rNextInfo.GetListId() );
1056 bool bExportListStyle( true );
1057 bool bRestartNumberingAtContinuedList( false );
1058 sal_Int32 nRestartValueForContinuedList( -1 );
1059 bool bContinueingPreviousSubList = !bRootListToBeStarted &&
1060 rNextInfo.IsContinueingPreviousSubTree();
1061 do {
1062 GetExport().CheckAttrList();
1063
1064 if ( bRootListToBeStarted )
1065 {
1066 if ( !mpTextListsHelper->IsListProcessed( sListId ) )
1067 {
1068 if ( ExportListId() &&
1069 !sListId.isEmpty() && !rNextInfo.IsListIdDefault() )
1070 {
1071 /* Property text:id at element <text:list> has to be
1072 replaced by property xml:id (#i92221#)
1073 */
1074 GetExport().AddAttribute( XML_NAMESPACE_XML,
1075 XML_ID,
1076 sListId );
1077 }
1078 mpTextListsHelper->KeepListAsProcessed( sListId,
1079 sListStyleName,
1080 OUString() );
1081 }
1082 else
1083 {
1084 const OUString sNewListId(
1085 mpTextListsHelper->GenerateNewListId() );
1086 if ( ExportListId() &&
1087 !sListId.isEmpty() && !rNextInfo.IsListIdDefault() )
1088 {
1089 /* Property text:id at element <text:list> has to be
1090 replaced by property xml:id (#i92221#)
1091 */
1092 GetExport().AddAttribute( XML_NAMESPACE_XML,
1093 XML_ID,
1094 sNewListId );
1095 }
1096
1097 const OUString sContinueListId =
1098 mpTextListsHelper->GetLastContinuingListId( sListId );
1099 // store that list with list id <sNewListId> is last list,
1100 // which has continued list with list id <sListId>
1101 mpTextListsHelper->StoreLastContinuingList( sListId,
1102 sNewListId );
1103 if ( sListStyleName ==
1104 mpTextListsHelper->GetListStyleOfLastProcessedList() &&
1105 // Inconsistent behavior regarding lists (#i92811#)
1106 sContinueListId ==
1107 mpTextListsHelper->GetLastProcessedListId() )
1108 {
1109 GetExport().AddAttribute( XML_NAMESPACE_TEXT,
1111 XML_TRUE );
1112 }
1113 else
1114 {
1115 if ( ExportListId() &&
1116 !sListId.isEmpty() )
1117 {
1118 GetExport().AddAttribute( XML_NAMESPACE_TEXT,
1120 sContinueListId );
1121 }
1122 }
1123
1124 if ( rNextInfo.IsRestart() &&
1125 ( nListLevelsToBeOpened != 1 ||
1126 !rNextInfo.HasStartValue() ) )
1127 {
1128 bRestartNumberingAtContinuedList = true;
1129 nRestartValueForContinuedList =
1130 rNextInfo.GetListLevelStartValue();
1131 }
1132
1133 mpTextListsHelper->KeepListAsProcessed( sNewListId,
1134 sListStyleName,
1135 sContinueListId );
1136 }
1137
1138 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
1139 GetExport().EncodeStyleName( sListStyleName ) );
1140 bExportListStyle = false;
1141
1142 bRootListToBeStarted = false;
1143 }
1144 else if ( bExportListStyle &&
1145 !mpTextListsHelper->EqualsToTopListStyleOnStack( sListStyleName ) )
1146 {
1147 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
1148 GetExport().EncodeStyleName( sListStyleName ) );
1149 bExportListStyle = false;
1150
1151 }
1152 else
1153 {
1154 // rhbz#746174: also export list restart for non root list
1155 if (rNextInfo.IsRestart() && !rNextInfo.HasStartValue())
1156 {
1157 bRestartNumberingAtContinuedList = true;
1158 nRestartValueForContinuedList =
1159 rNextInfo.GetListLevelStartValue();
1160 }
1161 }
1162
1163 if ( bContinueingPreviousSubList )
1164 {
1165 GetExport().AddAttribute( XML_NAMESPACE_TEXT,
1167 bContinueingPreviousSubList = false;
1168 }
1169
1170 enum XMLTokenEnum eLName = XML_LIST;
1171
1172 OUString aElem(GetExport().GetNamespaceMap().GetQNameByKey(
1174 GetXMLToken(eLName) ) );
1175 GetExport().IgnorableWhitespace();
1176 GetExport().StartElement(aElem, false);
1177
1178 maListElements.push_back(aElem);
1179
1180 mpTextListsHelper->PushListOnStack( sListId,
1181 sListStyleName );
1182
1183 // <text:list-header> or <text:list-item>
1184 GetExport().CheckAttrList();
1185
1186 /* Export start value at correct list item (#i97309#) */
1187 if ( nListLevelsToBeOpened == 1 )
1188 {
1189 if ( rNextInfo.HasStartValue() )
1190 {
1191 OUString aTmp = OUString::number( static_cast<sal_Int32>(rNextInfo.GetStartValue()) );
1192 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE,
1193 aTmp );
1194 }
1195 else if (bRestartNumberingAtContinuedList)
1196 {
1197 GetExport().AddAttribute( XML_NAMESPACE_TEXT,
1199 OUString::number(nRestartValueForContinuedList) );
1200 bRestartNumberingAtContinuedList = false;
1201 }
1202 }
1203
1204 eLName = ( rNextInfo.IsNumbered() || nListLevelsToBeOpened > 1 )
1207 aElem = GetExport().GetNamespaceMap().GetQNameByKey(
1209 GetXMLToken(eLName) );
1210 GetExport().IgnorableWhitespace();
1211 GetExport().StartElement(aElem, false);
1212 maListElements.push_back(aElem);
1213
1214 // export of <text:number> element for last opened <text:list-item>, if requested
1215 if ( GetExport().exportTextNumberElement() &&
1216 eLName == XML_LIST_ITEM && nListLevelsToBeOpened == 1 && // last iteration --> last opened <text:list-item>
1217 !rNextInfo.ListLabelString().isEmpty() )
1218 {
1219 const OUString aTextNumberElem =
1220 GetExport().GetNamespaceMap().GetQNameByKey(
1223 GetExport().IgnorableWhitespace();
1224 GetExport().StartElement( aTextNumberElem, false );
1225 GetExport().Characters( rNextInfo.ListLabelString() );
1226 GetExport().EndElement( aTextNumberElem, true );
1227 }
1228 --nListLevelsToBeOpened;
1229 } while ( nListLevelsToBeOpened > 0 );
1230 }
1231 }
1232
1233 bool bEndElement = false;
1234
1235 if ( rNextInfo.GetLevel() > 0 &&
1236 rNextInfo.IsNumbered() &&
1237 rPrevInfo.BelongsToSameList( rNextInfo ) &&
1238 rPrevInfo.GetLevel() >= rNextInfo.GetLevel() )
1239 {
1240 assert(maListElements.size() >= 2 && "list elements missing");
1241 bEndElement = maListElements.size() >= 2;
1242 }
1243
1244 if (!bEndElement)
1245 return;
1246
1247 // close previous list-item
1248 GetExport().EndElement(maListElements.back(), true );
1249 maListElements.pop_back();
1250
1251 // Only for sub lists (#i103745#)
1252 if ( rNextInfo.IsRestart() && !rNextInfo.HasStartValue() &&
1253 rNextInfo.GetLevel() != 1 )
1254 {
1255 // start new sub list respectively list on same list level
1256 GetExport().EndElement(maListElements.back(), true );
1257 GetExport().IgnorableWhitespace();
1258 GetExport().StartElement(maListElements.back(), false);
1259 }
1260
1261 // open new list-item
1262 GetExport().CheckAttrList();
1263 if( rNextInfo.HasStartValue() )
1264 {
1265 OUString aTmp = OUString::number( static_cast<sal_Int32>(rNextInfo.GetStartValue()) );
1266 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE, aTmp );
1267 }
1268 // Handle restart without start value on list level 1 (#i103745#)
1269 else if ( rNextInfo.IsRestart() &&
1270 rNextInfo.GetLevel() == 1 )
1271 {
1272 OUString aTmp = OUString::number( static_cast<sal_Int32>(rNextInfo.GetListLevelStartValue()) );
1273 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_START_VALUE, aTmp );
1274 }
1275 if ( ( GetExport().getExportFlags() & SvXMLExportFlags::OASIS ) &&
1276 GetExport().getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
1277 {
1278 const OUString& sListStyleName( rNextInfo.GetNumRulesName() );
1279 if ( !mpTextListsHelper->EqualsToTopListStyleOnStack( sListStyleName ) )
1280 {
1281 GetExport().AddAttribute( XML_NAMESPACE_TEXT,
1283 GetExport().EncodeStyleName( sListStyleName ) );
1284 }
1285 }
1286 OUString aElem( GetExport().GetNamespaceMap().GetQNameByKey(
1289 GetExport().IgnorableWhitespace();
1290 GetExport().StartElement(aElem, false );
1291 maListElements.push_back(aElem);
1292
1293 // export of <text:number> element for <text:list-item>, if requested
1294 if ( GetExport().exportTextNumberElement() &&
1295 !rNextInfo.ListLabelString().isEmpty() )
1296 {
1297 const OUString aTextNumberElem =
1298 GetExport().GetNamespaceMap().GetQNameByKey(
1301 GetExport().IgnorableWhitespace();
1302 GetExport().StartElement( aTextNumberElem, false );
1303 GetExport().Characters( rNextInfo.ListLabelString() );
1304 GetExport().EndElement( aTextNumberElem, true );
1305 }
1306
1307}
1308
1310{
1311 typedef ::std::map<Reference<XFormField>, sal_Int32> FieldMarkMap_t;
1313
1314 explicit Impl() {}
1315 sal_Int32 AddFieldMarkStart(Reference<XFormField> const& i_xFieldMark)
1316 {
1317 assert(m_FieldMarkMap.find(i_xFieldMark) == m_FieldMarkMap.end());
1318 sal_Int32 const ret(m_FieldMarkMap.size());
1319 m_FieldMarkMap.insert(::std::make_pair(i_xFieldMark, ret));
1320 return ret;
1321 }
1322 sal_Int32 GetFieldMarkIndex(Reference<XFormField> const& i_xFieldMark)
1323 {
1324 FieldMarkMap_t::const_iterator const it(
1325 m_FieldMarkMap.find(i_xFieldMark));
1326 // rely on SwXFieldmark::CreateXFieldmark returning the same instance
1327 // because the Reference in m_FieldMarkMap will keep it alive
1328 assert(it != m_FieldMarkMap.end());
1329 return it->second;
1330 }
1331};
1332
1334{
1336 {
1337 sal_Int32 index; // see SwNode::GetIndex and SwNodeOffset
1338 sal_uInt64 style_id; // actually a pointer to NumRule
1339 OUString list_id;
1340 };
1341 std::vector<NodeData> docListNodes;
1342 DocumentListNodes(const css::uno::Reference<css::frame::XModel>& xModel)
1343 {
1344 // Sequence of nodes, each of them represented by three-element sequence,
1345 // corresponding to NodeData members
1346 css::uno::Sequence<css::uno::Sequence<css::uno::Any>> nodes;
1347 if (auto xPropSet = xModel.query<css::beans::XPropertySet>())
1348 {
1349 try
1350 {
1351 // See SwXTextDocument::getPropertyValue
1352 xPropSet->getPropertyValue("ODFExport_ListNodes") >>= nodes;
1353 }
1354 catch (css::beans::UnknownPropertyException&)
1355 {
1356 // That's absolutely fine!
1357 }
1358 }
1359
1360 docListNodes.reserve(nodes.getLength());
1361 for (const auto& node : nodes)
1362 {
1363 assert(node.getLength() == 3);
1364 docListNodes.push_back({ node[0].get<sal_Int32>(), node[1].get<sal_uInt64>(),
1365 node[2].get<OUString>() });
1366 }
1367
1368 std::sort(docListNodes.begin(), docListNodes.end(),
1369 [](const NodeData& lhs, const NodeData& rhs) { return lhs.index < rhs.index; });
1370 }
1371 bool ShouldSkipListId(const Reference<XTextContent>& xTextContent) const
1372 {
1373 if (docListNodes.empty())
1374 return false;
1375
1376 if (auto xPropSet = xTextContent.query<css::beans::XPropertySet>())
1377 {
1378 sal_Int32 index = 0;
1379 try
1380 {
1381 // See SwXParagraph::Impl::GetPropertyValues_Impl
1382 xPropSet->getPropertyValue("ODFExport_NodeIndex") >>= index;
1383 }
1384 catch (css::beans::UnknownPropertyException&)
1385 {
1386 // That's absolutely fine!
1387 return false;
1388 }
1389
1390 auto it = std::lower_bound(docListNodes.begin(), docListNodes.end(), index,
1391 [](const NodeData& lhs, sal_Int32 rhs)
1392 { return lhs.index < rhs; });
1393 if (it == docListNodes.end() || it->index != index)
1394 return false;
1395
1396 // We need to write the id, when there will be continuation of the list either with
1397 // a different list style, or after another list.
1398
1399 for (auto next = it + 1; next != docListNodes.end(); ++next)
1400 {
1401 if (it->list_id != next->list_id)
1402 {
1403 // List changed. We will have to refer to this id, only if there will
1404 // appear a continuation of this list
1405 return std::find_if(next + 1, docListNodes.end(),
1406 [list_id = it->list_id](const NodeData& data)
1407 { return data.list_id == list_id; })
1408 == docListNodes.end();
1409 }
1410
1411 if (it->style_id != next->style_id)
1412 {
1413 // Same list, new style -> this "next" will refer to the id, no skipping
1414 return false;
1415 }
1416 if (it->index + 1 != next->index)
1417 {
1418 // we have a gap before the next node with the same list and style,
1419 // with no other lists in between. There will be a continuation with a
1420 // simple 'text:continue-numbering="true"'.
1421 return true;
1422 }
1423 it = next; // walk through adjacent nodes of the same list
1424 }
1425 // all nodes were adjacent and of the same list and style -> no continuation, skip id
1426 return true;
1427 }
1428
1429 return false;
1430 }
1431};
1432
1434 SvXMLExport& rExp,
1435 SvXMLAutoStylePoolP & rASP
1436 ) :
1437 XMLStyleExport( rExp, &rASP ),
1438 m_xImpl(new Impl),
1439 m_rAutoStylePool( rASP ),
1440 m_pBoundFrameSets(new BoundFrameSets(GetExport().GetModel())),
1441 maListAutoPool( GetExport() ),
1442 m_bProgress( false ),
1443 m_bBlock( false ),
1444 m_bOpenRuby( false ),
1445 mpTextListsHelper( nullptr ),
1446 mbCollected(false),
1447 m_aCharStyleNamesPropInfoCache( gsCharStyleNames )
1448{
1451 GetExport() );
1452
1453 OUString sFamily( GetXMLToken(XML_PARAGRAPH) );
1454 OUString aPrefix(u'P');
1456 m_xParaPropMapper, aPrefix );
1457
1458 xPropMapper = new XMLTextPropertySetMapper( TextPropMap::TEXT, true );
1460 GetExport() );
1461 sFamily = GetXMLToken(XML_TEXT);
1462 aPrefix = "T";
1464 m_xTextPropMapper, aPrefix );
1465
1466 xPropMapper = new XMLTextPropertySetMapper( TextPropMap::AUTO_FRAME, true );
1468 GetExport() );
1470 aPrefix = "fr";
1472 m_xAutoFramePropMapper, aPrefix );
1473
1474 xPropMapper = new XMLTextPropertySetMapper( TextPropMap::SECTION, true );
1476 GetExport() );
1477 sFamily = GetXMLToken( XML_SECTION );
1478 aPrefix = "Sect" ;
1480 m_xSectionPropMapper, aPrefix );
1481
1482 xPropMapper = new XMLTextPropertySetMapper( TextPropMap::RUBY, true );
1483 m_xRubyPropMapper = new SvXMLExportPropertyMapper( xPropMapper );
1484 sFamily = GetXMLToken( XML_RUBY );
1485 aPrefix = "Ru";
1487 m_xRubyPropMapper, aPrefix );
1488
1489 xPropMapper = new XMLTextPropertySetMapper( TextPropMap::FRAME, true );
1491 GetExport() );
1492
1493 m_pSectionExport.reset( new XMLSectionExport( rExp, *this ) );
1494 m_pIndexMarkExport.reset( new XMLIndexMarkExport( rExp ) );
1495
1496 if( ! IsBlockMode() &&
1497 Reference<XRedlinesSupplier>( GetExport().GetModel(), UNO_QUERY ).is())
1498 m_pRedlineExport.reset( new XMLRedlineExport( rExp ) );
1499
1500 // The text field helper needs a pre-constructed XMLPropertyState
1501 // to export the combined characters field. We construct that
1502 // here, because we need the text property mapper to do it.
1503
1504 // construct Any value, then find index
1505 sal_Int32 nIndex = m_xTextPropMapper->getPropertySetMapper()->FindEntryIndex(
1508 m_pFieldExport.reset( new XMLTextFieldExport( rExp, std::make_unique<XMLPropertyState>( nIndex, uno::Any(true) ) ) );
1510}
1511
1513{
1514 m_pRedlineExport.reset();
1515 m_pIndexMarkExport.reset();
1516 m_pSectionExport.reset();
1517 m_pFieldExport.reset();
1518#ifdef DBG_UTIL
1520#endif
1522 SAL_WARN_IF( !maTextListsHelperStack.empty(), "xmloff",
1523 "misusage of text lists helper stack - it is not empty. Serious defect" );
1524}
1525
1527 SvXMLExport& rExport )
1528{
1531 return new XMLTextExportPropertySetMapper( xPropMapper, rExport );
1532}
1533
1535 SvXMLExport& rExport)
1536{
1537 XMLPropertySetMapper *pPropMapper =
1539 return new XMLTextExportPropertySetMapper( pPropMapper, rExport );
1540}
1541
1543 SvXMLExport& rExport)
1544{
1545 XMLPropertySetMapper *pPropMapper =
1547 return new XMLTextExportPropertySetMapper( pPropMapper, rExport );
1548}
1549
1551 SvXMLExport& rExport)
1552{
1553 XMLPropertySetMapper *pPropMapper =
1555 return new XMLTextExportPropertySetMapper( pPropMapper, rExport );
1556}
1557
1559{
1560 const TextContentSet& rTexts = m_pBoundFrameSets->GetTexts()->GetPageBoundContents();
1561 const TextContentSet& rGraphics = m_pBoundFrameSets->GetGraphics()->GetPageBoundContents();
1562 const TextContentSet& rEmbeddeds = m_pBoundFrameSets->GetEmbeddeds()->GetPageBoundContents();
1563 const TextContentSet& rShapes = m_pBoundFrameSets->GetShapes()->GetPageBoundContents();
1564 for(TextContentSet::const_iterator_t it = rTexts.getBegin();
1565 it != rTexts.getEnd();
1566 ++it)
1567 exportTextFrame(*it, false/*bAutoStyles*/, bIsProgress, true);
1568 for(TextContentSet::const_iterator_t it = rGraphics.getBegin();
1569 it != rGraphics.getEnd();
1570 ++it)
1571 exportTextGraphic(*it, false/*bAutoStyles*/);
1572 for(TextContentSet::const_iterator_t it = rEmbeddeds.getBegin();
1573 it != rEmbeddeds.getEnd();
1574 ++it)
1575 exportTextEmbedded(*it, false/*bAutoStyles*/);
1576 for(TextContentSet::const_iterator_t it = rShapes.getBegin();
1577 it != rShapes.getEnd();
1578 ++it)
1579 exportShape(*it, false/*bAutoStyles*/);
1580}
1581
1583 bool bAutoStyles,
1584 bool bIsProgress,
1585 const Reference < XTextFrame >& rParentTxtFrame )
1586{
1587 const TextContentSet* const pTexts = m_pBoundFrameSets->GetTexts()->GetFrameBoundContents(rParentTxtFrame);
1588 if(pTexts)
1589 for(TextContentSet::const_iterator_t it = pTexts->getBegin();
1590 it != pTexts->getEnd();
1591 ++it)
1592 exportTextFrame(*it, bAutoStyles, bIsProgress, true);
1593 const TextContentSet* const pGraphics = m_pBoundFrameSets->GetGraphics()->GetFrameBoundContents(rParentTxtFrame);
1594 if(pGraphics)
1595 for(TextContentSet::const_iterator_t it = pGraphics->getBegin();
1596 it != pGraphics->getEnd();
1597 ++it)
1598 exportTextGraphic(*it, bAutoStyles);
1599 const TextContentSet* const pEmbeddeds = m_pBoundFrameSets->GetEmbeddeds()->GetFrameBoundContents(rParentTxtFrame);
1600 if(pEmbeddeds)
1601 for(TextContentSet::const_iterator_t it = pEmbeddeds->getBegin();
1602 it != pEmbeddeds->getEnd();
1603 ++it)
1604 exportTextEmbedded(*it, bAutoStyles);
1605 const TextContentSet* const pShapes = m_pBoundFrameSets->GetShapes()->GetFrameBoundContents(rParentTxtFrame);
1606 if(pShapes)
1607 for(TextContentSet::const_iterator_t it = pShapes->getBegin();
1608 it != pShapes->getEnd();
1609 ++it)
1610 exportShape(*it, bAutoStyles);
1611}
1612
1613// bookmarks, reference marks (and TOC marks) are the same except for the
1614// element names. We use the same method for export and it an array with
1615// the proper element names
1620
1621// This function replaces the text portion iteration during auto style
1622// collection.
1624{
1625 GetExport().GetShapeExport(); // make sure the graphics styles family is added
1626
1627 if (mbCollected)
1628 return;
1629
1630 const bool bAutoStyles = true;
1631 const bool bExportContent = false;
1632
1633 // Export AutoStyles:
1634 Reference< XAutoStylesSupplier > xAutoStylesSupp( GetExport().GetModel(), UNO_QUERY );
1635 if ( xAutoStylesSupp.is() )
1636 {
1637 Reference< XAutoStyles > xAutoStyleFamilies = xAutoStylesSupp->getAutoStyles();
1638 const auto collectFamily = [this, &xAutoStyleFamilies](const OUString& sName,
1639 XmlStyleFamily nFamily) {
1640 Any aAny = xAutoStyleFamilies->getByName( sName );
1641 Reference< XAutoStyleFamily > xAutoStyles = *o3tl::doAccess<Reference<XAutoStyleFamily>>(aAny);
1642 Reference < XEnumeration > xAutoStylesEnum( xAutoStyles->createEnumeration() );
1643
1644 while ( xAutoStylesEnum->hasMoreElements() )
1645 {
1646 aAny = xAutoStylesEnum->nextElement();
1647 Reference< XAutoStyle > xAutoStyle = *o3tl::doAccess<Reference<XAutoStyle>>(aAny);
1648 Reference < XPropertySet > xPSet( xAutoStyle, uno::UNO_QUERY );
1649 Add( nFamily, xPSet, {}, true );
1650 }
1651 };
1652 collectFamily("CharacterStyles", XmlStyleFamily::TEXT_TEXT);
1653 collectFamily("RubyStyles", XmlStyleFamily::TEXT_RUBY);
1654 collectFamily("ParagraphStyles", XmlStyleFamily::TEXT_PARAGRAPH);
1655 }
1656
1657 // Export Field AutoStyles:
1658 Reference< XTextFieldsSupplier > xTextFieldsSupp( GetExport().GetModel(), UNO_QUERY );
1659 if ( xTextFieldsSupp.is() )
1660 {
1661 Reference< XEnumerationAccess > xTextFields = xTextFieldsSupp->getTextFields();
1662 Reference < XEnumeration > xTextFieldsEnum( xTextFields->createEnumeration() );
1663
1664 while ( xTextFieldsEnum->hasMoreElements() )
1665 {
1666 Any aAny = xTextFieldsEnum->nextElement();
1667 Reference< XTextField > xTextField = *o3tl::doAccess<Reference<XTextField>>(aAny);
1668 exportTextField( xTextField, bAutoStyles, bIsProgress,
1669 !xAutoStylesSupp.is(), nullptr );
1670 try
1671 {
1672 Reference < XPropertySet > xSet( xTextField, UNO_QUERY );
1673 Reference < XText > xText;
1674 Any a = xSet->getPropertyValue("TextRange");
1675 a >>= xText;
1676 if ( xText.is() )
1677 {
1678 exportText( xText, true, bIsProgress, bExportContent );
1680 ->collectTextAutoStyles( xText );
1681 }
1682 }
1683 catch (Exception&)
1684 {
1685 }
1686 }
1687 }
1688
1689 // Export text frames:
1690 Reference<XEnumeration> xTextFramesEnum = m_pBoundFrameSets->GetTexts()->createEnumeration();
1691 if(xTextFramesEnum.is())
1692 while(xTextFramesEnum->hasMoreElements())
1693 {
1694 Reference<XTextContent> xTxtCntnt(xTextFramesEnum->nextElement(), UNO_QUERY);
1695 if(xTxtCntnt.is())
1696 exportTextFrame(xTxtCntnt, bAutoStyles, bIsProgress, bExportContent);
1697 }
1698
1699 // Export graphic objects:
1700 Reference<XEnumeration> xGraphicsEnum = m_pBoundFrameSets->GetGraphics()->createEnumeration();
1701 if(xGraphicsEnum.is())
1702 while(xGraphicsEnum->hasMoreElements())
1703 {
1704 Reference<XTextContent> xTxtCntnt(xGraphicsEnum->nextElement(), UNO_QUERY);
1705 if(xTxtCntnt.is())
1706 exportTextGraphic(xTxtCntnt, true);
1707 }
1708
1709 // Export embedded objects:
1710 Reference<XEnumeration> xEmbeddedsEnum = m_pBoundFrameSets->GetEmbeddeds()->createEnumeration();
1711 if(xEmbeddedsEnum.is())
1712 while(xEmbeddedsEnum->hasMoreElements())
1713 {
1714 Reference<XTextContent> xTxtCntnt(xEmbeddedsEnum->nextElement(), UNO_QUERY);
1715 if(xTxtCntnt.is())
1716 exportTextEmbedded(xTxtCntnt, true);
1717 }
1718
1719 // Export shapes:
1720 Reference<XEnumeration> xShapesEnum = m_pBoundFrameSets->GetShapes()->createEnumeration();
1721 if(xShapesEnum.is())
1722 while(xShapesEnum->hasMoreElements())
1723 {
1724 Reference<XTextContent> xTxtCntnt(xShapesEnum->nextElement(), UNO_QUERY);
1725 if(xTxtCntnt.is())
1726 {
1727 Reference<XServiceInfo> xServiceInfo(xTxtCntnt, UNO_QUERY);
1728 if( xServiceInfo->supportsService(gsShapeService))
1729 exportShape(xTxtCntnt, true);
1730 }
1731 }
1732
1733 sal_Int32 nCount;
1734 // AutoStyles for sections
1735 Reference< XTextSectionsSupplier > xSectionsSupp( GetExport().GetModel(), UNO_QUERY );
1736 if ( xSectionsSupp.is() )
1737 {
1738 Reference< XIndexAccess > xSections( xSectionsSupp->getTextSections(), UNO_QUERY );
1739 if ( xSections.is() )
1740 {
1741 nCount = xSections->getCount();
1742 for( sal_Int32 i = 0; i < nCount; ++i )
1743 {
1744 Any aAny = xSections->getByIndex( i );
1745 Reference< XTextSection > xSection = *o3tl::doAccess<Reference<XTextSection>>(aAny);
1746 Reference < XPropertySet > xPSet( xSection, uno::UNO_QUERY );
1748 }
1749 }
1750 }
1751
1752 // AutoStyles for tables (Note: suppress autostyle collection for paragraphs in exportTable)
1753 Reference< XTextTablesSupplier > xTablesSupp( GetExport().GetModel(), UNO_QUERY );
1754 if ( xTablesSupp.is() )
1755 {
1756 Reference< XIndexAccess > xTables( xTablesSupp->getTextTables(), UNO_QUERY );
1757 if ( xTables.is() )
1758 {
1759 nCount = xTables->getCount();
1760 for( sal_Int32 i = 0; i < nCount; ++i )
1761 {
1762 Any aAny = xTables->getByIndex( i );
1763 Reference< XTextTable > xTable = *o3tl::doAccess<Reference<XTextTable>>(aAny);
1764 exportTable( xTable, true, true );
1765 }
1766 }
1767 }
1768
1769 Reference< XNumberingRulesSupplier > xNumberingRulesSupp( GetExport().GetModel(), UNO_QUERY );
1770 if ( xNumberingRulesSupp.is() )
1771 {
1772 Reference< XIndexAccess > xNumberingRules = xNumberingRulesSupp->getNumberingRules();
1773 nCount = xNumberingRules->getCount();
1774 // Custom outline assignment lost after re-importing sxw (#i73361#)
1775 for( sal_Int32 i = 0; i < nCount; ++i )
1776 {
1777 Reference< XIndexReplace > xNumRule( xNumberingRules->getByIndex( i ), UNO_QUERY );
1778 if( xNumRule.is() && xNumRule->getCount() )
1779 {
1780 Reference < XNamed > xNamed( xNumRule, UNO_QUERY );
1781 OUString sName;
1782 if( xNamed.is() )
1783 sName = xNamed->getName();
1784 bool bAdd = sName.isEmpty();
1785 if( !bAdd )
1786 {
1787 Reference < XPropertySet > xNumPropSet( xNumRule,
1788 UNO_QUERY );
1789 if( xNumPropSet.is() &&
1790 xNumPropSet->getPropertySetInfo()
1791 ->hasPropertyByName( "IsAutomatic" ) )
1792 {
1793 bAdd = *o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "IsAutomatic" ));
1794 // Check on outline style (#i73361#)
1795 if ( bAdd &&
1796 xNumPropSet->getPropertySetInfo()
1797 ->hasPropertyByName( "NumberingIsOutline" ) )
1798 {
1799 bAdd = !(*o3tl::doAccess<bool>(xNumPropSet->getPropertyValue( "NumberingIsOutline" )));
1800 }
1801 }
1802 else
1803 {
1804 bAdd = true;
1805 }
1806 }
1807 if( bAdd )
1808 maListAutoPool.Add( xNumRule );
1809 }
1810 }
1811 }
1812 mbCollected = true;
1813}
1814
1816 const Reference < XText > & rText,
1817 bool bAutoStyles,
1818 bool bIsProgress,
1819 bool bExportParagraph,
1820 TextPNS eExtensionNS)
1821{
1822 if( bAutoStyles )
1823 GetExport().GetShapeExport(); // make sure the graphics styles family
1824 // is added
1825 Reference < XEnumerationAccess > xEA( rText, UNO_QUERY );
1826 if( ! xEA.is() )
1827 return;
1828
1829 Reference < XEnumeration > xParaEnum(xEA->createEnumeration());
1830 Reference < XPropertySet > xPropertySet( rText, UNO_QUERY );
1831 Reference < XTextSection > xBaseSection;
1832
1833 // #97718# footnotes don't supply paragraph enumerations in some cases
1834 // This is always a bug, but at least we don't want to crash.
1835 SAL_WARN_IF( !xParaEnum.is(), "xmloff", "We need a paragraph enumeration" );
1836 if( ! xParaEnum.is() )
1837 return;
1838
1839 if (xPropertySet.is())
1840 {
1841 Reference < XPropertySetInfo > xInfo ( xPropertySet->getPropertySetInfo() );
1842
1843 if( xInfo.is() )
1844 {
1845 if (xInfo->hasPropertyByName( gsTextSection ))
1846 {
1847 xPropertySet->getPropertyValue(gsTextSection) >>= xBaseSection ;
1848 }
1849 }
1850 }
1851
1852 // #96530# Export redlines at start & end of XText before & after
1853 // exporting the text content enumeration
1854 if( !bAutoStyles && (m_pRedlineExport != nullptr) )
1855 m_pRedlineExport->ExportStartOrEndRedline( xPropertySet, true );
1856 exportTextContentEnumeration( xParaEnum, bAutoStyles, xBaseSection,
1857 bIsProgress, bExportParagraph, nullptr, eExtensionNS );
1858 if( !bAutoStyles && (m_pRedlineExport != nullptr) )
1859 m_pRedlineExport->ExportStartOrEndRedline( xPropertySet, false );
1860}
1861
1863 const Reference < XText > & rText,
1864 const Reference < XTextSection > & rBaseSection,
1865 bool bAutoStyles,
1866 bool bIsProgress,
1867 bool bExportParagraph)
1868{
1869 if( bAutoStyles )
1870 GetExport().GetShapeExport(); // make sure the graphics styles family
1871 // is added
1872 Reference < XEnumerationAccess > xEA( rText, UNO_QUERY );
1873 Reference < XEnumeration > xParaEnum(xEA->createEnumeration());
1874
1875 // #98165# don't continue without a paragraph enumeration
1876 if( ! xParaEnum.is() )
1877 return;
1878
1879 // #96530# Export redlines at start & end of XText before & after
1880 // exporting the text content enumeration
1881 Reference<XPropertySet> xPropertySet;
1882 if( !bAutoStyles && (m_pRedlineExport != nullptr) )
1883 {
1884 xPropertySet.set(rText, uno::UNO_QUERY );
1885 m_pRedlineExport->ExportStartOrEndRedline( xPropertySet, true );
1886 }
1887 exportTextContentEnumeration( xParaEnum, bAutoStyles, rBaseSection,
1888 bIsProgress, bExportParagraph );
1889 if( !bAutoStyles && (m_pRedlineExport != nullptr) )
1890 m_pRedlineExport->ExportStartOrEndRedline( xPropertySet, false );
1891}
1892
1894{
1895 return (GetExport().getExportFlags() & SvXMLExportFlags::OASIS)
1897}
1898
1899bool XMLTextParagraphExport::ShouldSkipListId(const Reference<XTextContent>& xTextContent)
1900{
1902 {
1903 if (ExportListId())
1904 mpDocumentListNodes.reset(new DocumentListNodes(GetExport().GetModel()));
1905 else
1907 }
1908
1909 return mpDocumentListNodes->ShouldSkipListId(xTextContent);
1910}
1911
1913 const Reference < XEnumeration > & rContEnum,
1914 bool bAutoStyles,
1915 const Reference < XTextSection > & rBaseSection,
1916 bool bIsProgress,
1917 bool bExportParagraph,
1918 const Reference < XPropertySet > *pRangePropSet,
1919 TextPNS eExtensionNS )
1920{
1921 SAL_WARN_IF( !rContEnum.is(), "xmloff", "No enumeration to export!" );
1922 bool bHasMoreElements = rContEnum->hasMoreElements();
1923 if( !bHasMoreElements )
1924 return;
1925
1926 XMLTextNumRuleInfo aPrevNumInfo;
1927 XMLTextNumRuleInfo aNextNumInfo;
1928
1929 bool bHasContent = false;
1930 Reference<XTextSection> xCurrentTextSection(rBaseSection);
1931
1932 MultiPropertySetHelper aPropSetHelper(
1933 bAutoStyles ? aParagraphPropertyNamesAuto :
1935
1936 bool bHoldElement = false;
1937 Reference < XTextContent > xTxtCntnt;
1938 while( bHoldElement || bHasMoreElements )
1939 {
1940 if (bHoldElement)
1941 {
1942 bHoldElement = false;
1943 }
1944 else
1945 {
1946 xTxtCntnt.set(rContEnum->nextElement(), uno::UNO_QUERY);
1947
1948 aPropSetHelper.resetValues();
1949
1950 }
1951
1952 Reference<XServiceInfo> xServiceInfo( xTxtCntnt, UNO_QUERY );
1953 if( xServiceInfo->supportsService( gsParagraphService ) )
1954 {
1955 if( bAutoStyles )
1956 {
1957 exportListAndSectionChange( xCurrentTextSection, xTxtCntnt,
1958 aPrevNumInfo, aNextNumInfo,
1959 bAutoStyles );
1960 }
1961 else
1962 {
1963 /* Pass list auto style pool to <XMLTextNumRuleInfo> instance
1964 Pass info about request to export <text:number> element
1965 to <XMLTextNumRuleInfo> instance (#i69627#)
1966 */
1967 aNextNumInfo.Set( xTxtCntnt,
1968 GetExport().writeOutlineStyleAsNormalListStyle(),
1970 GetExport().exportTextNumberElement(),
1971 ShouldSkipListId(xTxtCntnt) );
1972
1973 exportListAndSectionChange( xCurrentTextSection, aPropSetHelper,
1974 TEXT_SECTION, xTxtCntnt,
1975 aPrevNumInfo, aNextNumInfo,
1976 bAutoStyles );
1977 }
1978
1979 // if we found a mute section: skip all section content
1980 if (m_pSectionExport->IsMuteSection(xCurrentTextSection))
1981 {
1982 // Make sure headings are exported anyway.
1983 if( !bAutoStyles )
1984 m_pSectionExport->ExportMasterDocHeadingDummies();
1985
1986 while (rContEnum->hasMoreElements() &&
1987 XMLSectionExport::IsInSection( xCurrentTextSection,
1988 xTxtCntnt, true ))
1989 {
1990 xTxtCntnt.set(rContEnum->nextElement(), uno::UNO_QUERY);
1991 aPropSetHelper.resetValues();
1992 aNextNumInfo.Reset();
1993 }
1994 // the first non-mute element still needs to be processed
1995 bHoldElement =
1996 ! XMLSectionExport::IsInSection( xCurrentTextSection,
1997 xTxtCntnt, false );
1998 }
1999 else
2000 exportParagraph( xTxtCntnt, bAutoStyles, bIsProgress,
2001 bExportParagraph, aPropSetHelper, eExtensionNS );
2002 bHasContent = true;
2003 }
2004 else if( xServiceInfo->supportsService( gsTableService ) )
2005 {
2006 if( !bAutoStyles )
2007 {
2008 aNextNumInfo.Reset();
2009 }
2010
2011 exportListAndSectionChange( xCurrentTextSection, xTxtCntnt,
2012 aPrevNumInfo, aNextNumInfo,
2013 bAutoStyles );
2014
2015 if (! m_pSectionExport->IsMuteSection(xCurrentTextSection))
2016 {
2017 // export start + end redlines (for wholly redlined tables)
2018 if ((! bAutoStyles) && (nullptr != m_pRedlineExport))
2019 m_pRedlineExport->ExportStartOrEndRedline(xTxtCntnt, true);
2020
2021 exportTable( xTxtCntnt, bAutoStyles, bIsProgress );
2022
2023 if ((! bAutoStyles) && (nullptr != m_pRedlineExport))
2024 m_pRedlineExport->ExportStartOrEndRedline(xTxtCntnt, false);
2025 }
2026 else if( !bAutoStyles )
2027 {
2028 // Make sure headings are exported anyway.
2029 m_pSectionExport->ExportMasterDocHeadingDummies();
2030 }
2031
2032 bHasContent = true;
2033 }
2034 else if( xServiceInfo->supportsService( gsTextFrameService ) )
2035 {
2036 exportTextFrame( xTxtCntnt, bAutoStyles, bIsProgress, true, pRangePropSet );
2037 }
2038 else if( xServiceInfo->supportsService( gsTextGraphicService ) )
2039 {
2040 exportTextGraphic( xTxtCntnt, bAutoStyles, pRangePropSet );
2041 }
2042 else if( xServiceInfo->supportsService( gsTextEmbeddedService ) )
2043 {
2044 exportTextEmbedded( xTxtCntnt, bAutoStyles, pRangePropSet );
2045 }
2046 else if( xServiceInfo->supportsService( gsShapeService ) )
2047 {
2048 exportShape( xTxtCntnt, bAutoStyles, pRangePropSet );
2049 }
2050 else
2051 {
2052 SAL_WARN_IF( xTxtCntnt.is(), "xmloff", "unknown text content" );
2053 }
2054
2055 if( !bAutoStyles )
2056 {
2057 aPrevNumInfo = aNextNumInfo;
2058 }
2059
2060 bHasMoreElements = rContEnum->hasMoreElements();
2061 }
2062
2063 if( bHasContent && !bAutoStyles )
2064 {
2065 aNextNumInfo.Reset();
2066
2067 // close open lists and sections; no new styles
2068 exportListAndSectionChange( xCurrentTextSection, rBaseSection,
2069 aPrevNumInfo, aNextNumInfo,
2070 bAutoStyles );
2071 }
2072}
2073
2075 const Reference < XTextContent > & rTextContent,
2076 bool bAutoStyles, bool bIsProgress, bool bExportParagraph,
2077 MultiPropertySetHelper& rPropSetHelper, TextPNS eExtensionNS)
2078{
2079 sal_Int16 nOutlineLevel = -1;
2080
2081 if( bIsProgress )
2082 {
2084 pProgress->SetValue( pProgress->GetValue()+1 );
2085 }
2086
2087 // get property set or multi property set and initialize helper
2088 Reference<XMultiPropertySet> xMultiPropSet( rTextContent, UNO_QUERY );
2089 Reference<XPropertySet> xPropSet( rTextContent, UNO_QUERY );
2090
2091 // check for supported properties
2092 if( !rPropSetHelper.checkedProperties() )
2093 rPropSetHelper.hasProperties( xPropSet->getPropertySetInfo() );
2094
2095// if( xMultiPropSet.is() )
2096// rPropSetHelper.getValues( xMultiPropSet );
2097// else
2098// rPropSetHelper.getValues( xPropSet );
2099
2100 if( bExportParagraph )
2101 {
2102 if( bAutoStyles )
2103 {
2104 Add( XmlStyleFamily::TEXT_PARAGRAPH, rPropSetHelper, xPropSet );
2105 }
2106 else
2107 {
2108 // xml:id for RDF metadata
2109 GetExport().AddAttributeXmlId(rTextContent);
2110 GetExport().AddAttributesRDFa(rTextContent);
2111
2112 OUString sStyle;
2113 if( rPropSetHelper.hasProperty( PARA_STYLE_NAME ) )
2114 {
2115 if( xMultiPropSet.is() )
2116 rPropSetHelper.getValue( PARA_STYLE_NAME,
2117 xMultiPropSet ) >>= sStyle;
2118 else
2119 rPropSetHelper.getValue( PARA_STYLE_NAME,
2120 xPropSet ) >>= sStyle;
2121 }
2122
2123 if( rTextContent.is() )
2124 {
2125 const OUString& rIdentifier = GetExport().getInterfaceToIdentifierMapper().getIdentifier( rTextContent );
2126 if( !rIdentifier.isEmpty() )
2127 {
2128 // FIXME: this is just temporary until EditEngine
2129 // paragraphs implement XMetadatable.
2130 // then that must be used and not the mapper, because
2131 // when both can be used we get two xml:id!
2132 uno::Reference<rdf::XMetadatable> const xMeta(rTextContent,
2133 uno::UNO_QUERY);
2134 OSL_ENSURE(!xMeta.is(), "paragraph that implements "
2135 "XMetadatable used in interfaceToIdentifierMapper?");
2137 rIdentifier);
2138 }
2139 }
2140
2141 OUString sAutoStyle = Find( XmlStyleFamily::TEXT_PARAGRAPH, xPropSet, sStyle );
2142 if ( sAutoStyle.isEmpty() )
2143 sAutoStyle = sStyle;
2144 if( !sAutoStyle.isEmpty() )
2146 GetExport().EncodeStyleName( sAutoStyle ) );
2147
2148 if( rPropSetHelper.hasProperty( PARA_CONDITIONAL_STYLE_NAME ) )
2149 {
2150 OUString sCondStyle;
2151 if( xMultiPropSet.is() )
2152 rPropSetHelper.getValue( PARA_CONDITIONAL_STYLE_NAME,
2153 xMultiPropSet ) >>= sCondStyle;
2154 else
2155 rPropSetHelper.getValue( PARA_CONDITIONAL_STYLE_NAME,
2156 xPropSet ) >>= sCondStyle;
2157 if( sCondStyle != sStyle )
2158 {
2159 sCondStyle = Find( XmlStyleFamily::TEXT_PARAGRAPH, xPropSet,
2160 sCondStyle );
2161 if( !sCondStyle.isEmpty() )
2164 GetExport().EncodeStyleName( sCondStyle ) );
2165 }
2166 }
2167
2168 if( rPropSetHelper.hasProperty( PARA_OUTLINE_LEVEL ) )
2169 {
2170 if( xMultiPropSet.is() )
2171 rPropSetHelper.getValue( PARA_OUTLINE_LEVEL,
2172 xMultiPropSet ) >>= nOutlineLevel;
2173 else
2174 rPropSetHelper.getValue( PARA_OUTLINE_LEVEL,
2175 xPropSet ) >>= nOutlineLevel;
2176
2177 if( 0 < nOutlineLevel )
2178 {
2181 OUString::number( sal_Int32( nOutlineLevel) ) );
2182
2183 if ( rPropSetHelper.hasProperty( PARA_OUTLINE_CONTENT_VISIBLE ) )
2184 {
2185 uno::Sequence<beans::PropertyValue> propList;
2186 bool bIsOutlineContentVisible = true;
2187 if( xMultiPropSet.is() )
2188 rPropSetHelper.getValue(
2189 PARA_OUTLINE_CONTENT_VISIBLE, xMultiPropSet ) >>= propList;
2190 else
2191 rPropSetHelper.getValue(
2192 PARA_OUTLINE_CONTENT_VISIBLE, xPropSet ) >>= propList;
2193 for (const auto& rProp : std::as_const(propList))
2194 {
2195 OUString propName = rProp.Name;
2196 if (propName == "OutlineContentVisibleAttr")
2197 {
2198 rProp.Value >>= bIsOutlineContentVisible;
2199 break;
2200 }
2201 }
2202 if (!bIsOutlineContentVisible)
2203 {
2206 XML_FALSE);
2207 }
2208 }
2209
2210 if( rPropSetHelper.hasProperty( NUMBERING_IS_NUMBER ) )
2211 {
2212 bool bIsNumber = false;
2213 if( xMultiPropSet.is() )
2214 rPropSetHelper.getValue(
2215 NUMBERING_IS_NUMBER, xMultiPropSet ) >>= bIsNumber;
2216 else
2217 rPropSetHelper.getValue(
2218 NUMBERING_IS_NUMBER, xPropSet ) >>= bIsNumber;
2219
2220 OUString sListStyleName;
2221 if( xMultiPropSet.is() )
2222 rPropSetHelper.getValue(
2223 PARA_NUMBERING_STYLENAME, xMultiPropSet ) >>= sListStyleName;
2224 else
2225 rPropSetHelper.getValue(
2226 PARA_NUMBERING_STYLENAME, xPropSet ) >>= sListStyleName;
2227
2228 bool bAssignedtoOutlineStyle = false;
2229 {
2230 Reference< XChapterNumberingSupplier > xCNSupplier( GetExport().GetModel(), UNO_QUERY );
2231
2232 if (xCNSupplier.is())
2233 {
2234 Reference< XIndexReplace > xNumRule ( xCNSupplier->getChapterNumberingRules() );
2235 SAL_WARN_IF( !xNumRule.is(), "xmloff", "no chapter numbering rules" );
2236
2237 if (xNumRule.is())
2238 {
2239 Reference< XPropertySet > xNumRulePropSet( xNumRule, UNO_QUERY );
2240 OUString sOutlineName;
2241 xNumRulePropSet->getPropertyValue(
2242 "Name" ) >>= sOutlineName;
2243 bAssignedtoOutlineStyle = ( sListStyleName == sOutlineName );
2244 }
2245 }
2246 }
2247
2248 if( ! bIsNumber && bAssignedtoOutlineStyle )
2251 XML_TRUE );
2252 }
2253
2254 {
2255 bool bIsRestartNumbering = false;
2256
2257 Reference< XPropertySetInfo >
2258 xPropSetInfo(xMultiPropSet.is() ?
2259 xMultiPropSet->getPropertySetInfo():
2260 xPropSet->getPropertySetInfo());
2261
2262 if (xPropSetInfo->
2263 hasPropertyByName("ParaIsNumberingRestart"))
2264 {
2265 xPropSet->getPropertyValue("ParaIsNumberingRestart")
2266 >>= bIsRestartNumbering;
2267 }
2268
2269 if (bIsRestartNumbering)
2270 {
2273 XML_TRUE);
2274
2275 if (xPropSetInfo->
2276 hasPropertyByName("NumberingStartValue"))
2277 {
2278 sal_Int32 nStartValue = 0;
2279
2280 xPropSet->getPropertyValue("NumberingStartValue")
2281 >>= nStartValue;
2282
2283 GetExport().
2284 AddAttribute(XML_NAMESPACE_TEXT,
2286 OUString::number(nStartValue));
2287 }
2288 }
2289 }
2290 }
2291 }
2292 }
2293
2294 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
2295 {
2296 try
2297 {
2298 // ParaMarkerAutoStyleSpan is a hidden property, just to pass the autostyle here
2299 // See SwXParagraph::Impl::GetPropertyValues_Impl
2300 css::uno::Any aVal = xPropSet->getPropertyValue("ParaMarkerAutoStyleSpan");
2301 if (auto xFakeSpan = aVal.query<css::beans::XPropertySet>())
2302 {
2303 if (bAutoStyles)
2304 {
2305 Add(XmlStyleFamily::TEXT_TEXT, xFakeSpan);
2306 }
2307 else
2308 {
2309 bool bIsUICharStyle, bHasAutoStyle;
2310 OUString sStyle = FindTextStyle(xFakeSpan, bIsUICharStyle, bHasAutoStyle);
2311 if (!sStyle.isEmpty())
2312 {
2314 sStyle);
2315 }
2316 }
2317 }
2318 }
2319 catch (const css::beans::UnknownPropertyException&)
2320 {
2321 // No problem
2322 }
2323 }
2324 }
2325
2326 Reference < XEnumerationAccess > xEA( rTextContent, UNO_QUERY );
2327 Reference < XEnumeration > xTextEnum = xEA->createEnumeration();
2328 const bool bHasPortions = xTextEnum.is();
2329
2330 Reference < XEnumeration> xContentEnum;
2331 Reference < XContentEnumerationAccess > xCEA( rTextContent, UNO_QUERY );
2332 if( xCEA.is() )
2333 xContentEnum.set(xCEA->createContentEnumeration( gsTextContentService ));
2334 const bool bHasContentEnum = xContentEnum.is() &&
2335 xContentEnum->hasMoreElements();
2336
2337 Reference < XTextSection > xSection;
2338 if( bHasContentEnum )
2339 {
2340 // For the auto styles, the multi property set helper is only used
2341 // if hard attributes are existing. Therefore, it seems to be a better
2342 // strategy to have the TextSection property separate, because otherwise
2343 // we always retrieve the style names even if they are not required.
2344 if( bAutoStyles )
2345 {
2346 if( xPropSet->getPropertySetInfo()->hasPropertyByName( gsTextSection ) )
2347 {
2348 xSection.set(xPropSet->getPropertyValue( gsTextSection ), uno::UNO_QUERY);
2349 }
2350 }
2351 else
2352 {
2353 if( rPropSetHelper.hasProperty( TEXT_SECTION ) )
2354 {
2355 xSection.set(rPropSetHelper.getValue( TEXT_SECTION ), uno::UNO_QUERY);
2356 }
2357 }
2358 }
2359
2360 bool bPrevCharIsSpace(true); // true because whitespace at start is ignored
2361
2362 if( bAutoStyles )
2363 {
2364 if( bHasContentEnum )
2366 xContentEnum, bAutoStyles, xSection,
2367 bIsProgress );
2368 if ( bHasPortions )
2369 {
2370 exportTextRangeEnumeration(xTextEnum, bAutoStyles, bIsProgress, bPrevCharIsSpace);
2371 }
2372 }
2373 else
2374 {
2375 enum XMLTokenEnum eElem =
2376 0 < nOutlineLevel ? XML_H : XML_P;
2378 true, false );
2379 if( bHasContentEnum )
2380 {
2382 xContentEnum, bAutoStyles, xSection,
2383 bIsProgress );
2384 }
2385 exportTextRangeEnumeration(xTextEnum, bAutoStyles, bIsProgress, bPrevCharIsSpace);
2386 }
2387}
2388
2390 const Reference < XEnumeration > & rTextEnum,
2391 bool bAutoStyles, bool bIsProgress,
2392 bool & rPrevCharIsSpace)
2393{
2394 static const char sFieldMarkName[] = "__FieldMark_";
2395
2396 /* This is used for exporting to strict OpenDocument 1.2, in which case traditional
2397 * bookmarks are used instead of fieldmarks. */
2398 FieldmarkType openFieldMark = NONE;
2399
2400 std::optional<SvXMLElementExport> oTextA;
2401 HyperlinkData aHyperlinkData;
2402
2403 while( rTextEnum->hasMoreElements() )
2404 {
2405 Reference<XPropertySet> xPropSet(rTextEnum->nextElement(), UNO_QUERY);
2406 Reference < XTextRange > xTxtRange(xPropSet, uno::UNO_QUERY);
2407 Reference<XPropertySetInfo> xPropInfo(xPropSet->getPropertySetInfo());
2408
2409 if (!bAutoStyles)
2410 {
2411 if (HyperlinkData aNewHyperlinkData(xPropSet); aNewHyperlinkData != aHyperlinkData)
2412 {
2413 aHyperlinkData = aNewHyperlinkData;
2414 oTextA.reset();
2415 if (aHyperlinkData.addHyperlinkAttributes(GetExport()))
2416 {
2417 oTextA.emplace(GetExport(), true, XML_NAMESPACE_TEXT, XML_A, false, false);
2418 aHyperlinkData.exportEvents(GetExport());
2419 }
2420 }
2421 }
2422
2423 if (xPropInfo->hasPropertyByName(gsTextPortionType))
2424 {
2425 OUString sType;
2426 xPropSet->getPropertyValue(gsTextPortionType) >>= sType;
2427
2428 if( sType == gsText)
2429 {
2430 exportTextRange( xTxtRange, bAutoStyles,
2431 rPrevCharIsSpace, openFieldMark);
2432 }
2433 else if( sType == gsTextField)
2434 {
2435 exportTextField(xTxtRange, bAutoStyles, bIsProgress, &rPrevCharIsSpace);
2436 }
2437 else if ( sType == "Annotation" )
2438 {
2439 exportTextField(xTxtRange, bAutoStyles, bIsProgress, &rPrevCharIsSpace);
2440 }
2441 else if ( sType == "AnnotationEnd" )
2442 {
2443 if (!bAutoStyles)
2444 {
2445 Reference<XNamed> xBookmark(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
2446 const OUString& rName = xBookmark->getName();
2447 if (!rName.isEmpty())
2448 {
2450 }
2452 }
2453 }
2454 else if( sType == gsFrame )
2455 {
2456 Reference < XEnumeration> xContentEnum;
2457 Reference < XContentEnumerationAccess > xCEA( xTxtRange,
2458 UNO_QUERY );
2459 if( xCEA.is() )
2460 xContentEnum.set(xCEA->createContentEnumeration(
2462 // frames are never in sections
2463 Reference<XTextSection> xSection;
2464 if( xContentEnum.is() )
2465 exportTextContentEnumeration( xContentEnum,
2466 bAutoStyles,
2467 xSection, bIsProgress, true,
2468 &xPropSet );
2469
2470 }
2471 else if (sType == gsFootnote)
2472 {
2473 exportTextFootnote(xPropSet,
2474 xTxtRange->getString(),
2475 bAutoStyles, bIsProgress );
2476 }
2477 else if (sType == gsBookmark)
2478 {
2479 exportTextMark(xPropSet,
2480 gsBookmark,
2482 bAutoStyles);
2483 }
2484 else if (sType == gsReferenceMark)
2485 {
2486 exportTextMark(xPropSet,
2489 bAutoStyles);
2490 }
2491 else if (sType == gsDocumentIndexMark)
2492 {
2493 m_pIndexMarkExport->ExportIndexMark(xPropSet, bAutoStyles);
2494 }
2495 else if (sType == gsRedline)
2496 {
2497 if (nullptr != m_pRedlineExport)
2498 m_pRedlineExport->ExportChange(xPropSet, bAutoStyles);
2499 }
2500 else if (sType == gsRuby)
2501 {
2502 exportRuby(xPropSet, bAutoStyles);
2503 }
2504 else if (sType == "InContentMetadata")
2505 {
2506 exportMeta(xPropSet, bAutoStyles, bIsProgress, rPrevCharIsSpace);
2507 }
2508 else if (sType == "ContentControl")
2509 {
2510 ExportContentControl(xPropSet, bAutoStyles, bIsProgress, rPrevCharIsSpace);
2511 }
2512 else if (sType == gsTextFieldStart)
2513 {
2514 Reference< css::text::XFormField > xFormField(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
2515
2516 /* As of now, textmarks are a proposed extension to the OpenDocument standard. */
2517 if (!bAutoStyles)
2518 {
2519 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
2520 {
2521 Reference<XNamed> xBookmark(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
2522 if (xBookmark.is())
2523 {
2524 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
2525 }
2526
2527 if (xFormField.is())
2528 {
2529 GetExport().AddAttribute(XML_NAMESPACE_FIELD, XML_TYPE, xFormField->getFieldType());
2530 }
2531
2533 if (xFormField.is())
2534 {
2535 FieldParamExporter(&GetExport(), xFormField->getParameters()).Export();
2536 }
2538 }
2539 /* The OpenDocument standard does not include support for TextMarks for now, so use bookmarks instead. */
2540 else
2541 {
2542 if (xFormField.is())
2543 {
2544 OUString sName;
2545 Reference< css::container::XNameAccess > xParameters = xFormField->getParameters();
2546 if (xParameters.is() && xParameters->hasByName("Name"))
2547 {
2548 const Any aValue = xParameters->getByName("Name");
2549 aValue >>= sName;
2550 }
2551 if (sName.isEmpty())
2552 { // name attribute is mandatory, so have to pull a
2553 // rabbit out of the hat here
2554 sName = sFieldMarkName + OUString::number(
2555 m_xImpl->AddFieldMarkStart(xFormField));
2556 }
2558 sName);
2559 SvXMLElementExport aElem( GetExport(), !bAutoStyles,
2561 false, false );
2562 const OUString sFieldType = xFormField->getFieldType();
2563 if (sFieldType == ODF_FORMTEXT)
2564 {
2565 openFieldMark = TEXT;
2566 }
2567 else if (sFieldType == ODF_FORMCHECKBOX)
2568 {
2569 openFieldMark = CHECK;
2570 }
2571 else
2572 {
2573 openFieldMark = NONE;
2574 }
2575 }
2576 }
2577 }
2578 }
2579 else if (sType == gsTextFieldSep)
2580 {
2581 if (!bAutoStyles)
2582 {
2583 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
2584 {
2585 SvXMLElementExport aElem( GetExport(), !bAutoStyles,
2587 false, false );
2588 }
2589 }
2590 }
2591 else if (sType == gsTextFieldEnd)
2592 {
2593 if (!bAutoStyles)
2594 {
2595 Reference< css::text::XFormField > xFormField(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
2596
2597 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
2598 {
2599 SvXMLElementExport aElem( GetExport(), !bAutoStyles,
2601 false, false );
2602 }
2603 else
2604 {
2605 if (xFormField.is())
2606 {
2607 OUString sName;
2608 Reference< css::container::XNameAccess > xParameters = xFormField->getParameters();
2609 if (xParameters.is() && xParameters->hasByName("Name"))
2610 {
2611 const Any aValue = xParameters->getByName("Name");
2612 aValue >>= sName;
2613 }
2614 if (sName.isEmpty())
2615 { // name attribute is mandatory, so have to pull a
2616 // rabbit out of the hat here
2617 sName = sFieldMarkName + OUString::number(
2618 m_xImpl->GetFieldMarkIndex(xFormField));
2619 }
2621 sName);
2622 SvXMLElementExport aElem( GetExport(), !bAutoStyles,
2624 false, false );
2625 }
2626 }
2627 }
2628 }
2629 else if (sType == gsTextFieldStartEnd)
2630 {
2631 if (!bAutoStyles)
2632 {
2633 if (GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
2634 {
2635 Reference<XNamed> xBookmark(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
2636 if (xBookmark.is())
2637 {
2638 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
2639 }
2640 Reference< css::text::XFormField > xFormField(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
2641 if (xFormField.is())
2642 {
2643 GetExport().AddAttribute(XML_NAMESPACE_FIELD, XML_TYPE, xFormField->getFieldType());
2644 }
2646 if (xFormField.is())
2647 {
2648 FieldParamExporter(&GetExport(), xFormField->getParameters()).Export();
2649 }
2651 }
2652 else
2653 {
2654 Reference<XNamed> xBookmark(xPropSet->getPropertyValue(gsBookmark), UNO_QUERY);
2655 if (xBookmark.is())
2656 {
2657 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xBookmark->getName());
2658 SvXMLElementExport aElem( GetExport(), !bAutoStyles,
2660 false, false );
2661 }
2662 }
2663 }
2664 }
2665 else if (sType == gsSoftPageBreak)
2666 {
2667 if (!bAutoStyles)
2669 }
2670 else if (sType == "LineBreak")
2671 {
2672 if (!bAutoStyles)
2673 exportTextLineBreak(xPropSet);
2674 }
2675 else {
2676 OSL_FAIL("unknown text portion type");
2677 }
2678 }
2679 else
2680 {
2681 Reference<XServiceInfo> xServiceInfo( xTxtRange, UNO_QUERY );
2682 if( xServiceInfo->supportsService( gsTextFieldService ) )
2683 {
2684 exportTextField(xTxtRange, bAutoStyles, bIsProgress, &rPrevCharIsSpace);
2685 }
2686 else
2687 {
2688 // no TextPortionType property -> non-Writer app -> text
2689 exportTextRange(xTxtRange, bAutoStyles, rPrevCharIsSpace, openFieldMark);
2690 }
2691 }
2692 }
2693
2694// now that there are nested enumerations for meta(-field), this may be valid!
2695// SAL_WARN_IF( bOpenRuby, "xmloff", "Red Alert: Ruby still open!" );
2696}
2697
2699 const Reference < XTextContent > &,
2700 bool /*bAutoStyles*/, bool /*bIsProgress*/ )
2701{
2702}
2703
2705 const Reference < XTextRange > & rTextRange,
2706 bool bAutoStyles, bool bIsProgress, bool *const pPrevCharIsSpace)
2707{
2708 Reference < XPropertySet > xPropSet( rTextRange, UNO_QUERY );
2709 // non-Writer apps need not support Property TextField, so test first
2710 if (!xPropSet->getPropertySetInfo()->hasPropertyByName( gsTextField ))
2711 return;
2712
2713 Reference < XTextField > xTxtFld(xPropSet->getPropertyValue( gsTextField ), uno::UNO_QUERY);
2714 SAL_WARN_IF( !xTxtFld.is(), "xmloff", "text field missing" );
2715 if( xTxtFld.is() )
2716 {
2717 exportTextField(xTxtFld, bAutoStyles, bIsProgress, true, pPrevCharIsSpace);
2718 }
2719 else
2720 {
2721 // write only characters
2722 GetExport().Characters(rTextRange->getString());
2723 }
2724}
2725
2727 const Reference < XTextField > & xTextField,
2728 const bool bAutoStyles, const bool bIsProgress,
2729 const bool bRecursive, bool *const pPrevCharIsSpace)
2730{
2731 if ( bAutoStyles )
2732 {
2733 m_pFieldExport->ExportFieldAutoStyle( xTextField, bIsProgress,
2734 bRecursive );
2735 }
2736 else
2737 {
2738 assert(pPrevCharIsSpace);
2739 m_pFieldExport->ExportField(xTextField, bIsProgress, *pPrevCharIsSpace);
2740 }
2741}
2742
2744{
2746 XML_SOFT_PAGE_BREAK, false,
2747 false );
2748}
2749
2751 const uno::Reference<beans::XPropertySet>& xPropSet)
2752{
2753 static const XMLTokenEnum aLineBreakClears[] = {
2754 XML_NONE,
2755 XML_LEFT,
2756 XML_RIGHT,
2757 XML_ALL,
2758 };
2759
2760 uno::Reference<text::XTextContent> xLineBreak;
2761 xPropSet->getPropertyValue("LineBreak") >>= xLineBreak;
2762 if (!xLineBreak.is())
2763 {
2764 return;
2765 }
2766
2767 uno::Reference<beans::XPropertySet> xLineBreakProps(xLineBreak, uno::UNO_QUERY);
2768 if (!xLineBreakProps.is())
2769 {
2770 return;
2771 }
2772
2773 sal_Int16 eClear{};
2774 xLineBreakProps->getPropertyValue("Clear") >>= eClear;
2775 if (eClear >= 0 && o3tl::make_unsigned(eClear) < SAL_N_ELEMENTS(aLineBreakClears))
2776 {
2778 GetXMLToken(aLineBreakClears[eClear]));
2779 }
2781 /*bIgnWSOutside=*/false, /*bIgnWSInside=*/false);
2782}
2783
2785 const Reference<XPropertySet> & rPropSet,
2786 const OUString& rProperty,
2788 bool bAutoStyles)
2789{
2790 // mib said: "Hau wech!"
2791
2792 // (Originally, I'd export a span element in case the (book|reference)mark
2793 // was formatted. This actually makes a difference in case some pervert
2794 // sets a point reference mark in the document and, say, formats it bold.
2795 // This basically meaningless formatting will now been thrown away
2796 // (aka cleaned up), since mib said: ... dvo
2797
2798 if (bAutoStyles)
2799 return;
2800
2801 // name element
2802 Reference<XNamed> xName(rPropSet->getPropertyValue(rProperty), UNO_QUERY);
2804 xName->getName());
2805
2806 // start, end, or point-reference?
2807 sal_Int8 nElement;
2808 if( *o3tl::doAccess<bool>(rPropSet->getPropertyValue(gsIsCollapsed)) )
2809 {
2810 nElement = 0;
2811 }
2812 else
2813 {
2814 nElement = *o3tl::doAccess<bool>(rPropSet->getPropertyValue(gsIsStart)) ? 1 : 2;
2815 }
2816
2817 // bookmark, bookmark-start: xml:id and RDFa for RDF metadata
2818 if( nElement < 2 ) {
2820 const uno::Reference<text::XTextContent> xTextContent(
2821 xName, uno::UNO_QUERY_THROW);
2822 GetExport().AddAttributesRDFa(xTextContent);
2823 }
2824
2825 // bookmark-start: add attributes hidden and condition
2826 if (nElement == 1)
2827 {
2828 Reference<XPropertySet> bkmkProps(rPropSet->getPropertyValue(rProperty), UNO_QUERY);
2829 Reference<XPropertySetInfo> bkmkPropInfo = bkmkProps->getPropertySetInfo();
2830 OUString sHidden("BookmarkHidden");
2831 if (bkmkPropInfo->hasPropertyByName(sHidden))
2832 {
2833 bool bHidden = false;
2834 bkmkProps->getPropertyValue(sHidden) >>= bHidden;
2835 if (bHidden)
2836 {
2837 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, "hidden", "true");
2838 OUString sCondition("BookmarkCondition");
2839 if (bkmkPropInfo->hasPropertyByName(sCondition))
2840 {
2841 OUString sBookmarkCondition;
2842 bkmkProps->getPropertyValue(sCondition) >>= sBookmarkCondition;
2843 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, "condition", sBookmarkCondition);
2844 }
2845 }
2846 }
2847 }
2848
2849 // export element
2850 assert(pElements != nullptr);
2851 assert(0 <= nElement && nElement <= 2);
2853 XML_NAMESPACE_TEXT, pElements[nElement],
2854 false, false);
2855 // else: no styles. (see above)
2856}
2857
2859 const Reference < XPropertySet > & rPropSet,
2860 const Reference < XPropertySetInfo > & rPropSetInfo )
2861{
2862 bool bIsBoundAsChar = false;
2863 OUString sAnchorType( "AnchorType" );
2864 if( rPropSetInfo->hasPropertyByName( sAnchorType ) )
2865 {
2866 TextContentAnchorType eAnchor;
2867 rPropSet->getPropertyValue( sAnchorType ) >>= eAnchor;
2868 bIsBoundAsChar = TextContentAnchorType_AS_CHARACTER == eAnchor;
2869 }
2870
2871 return bIsBoundAsChar;
2872}
2873
2875 const Reference < XPropertySet >& rPropSet,
2876 bool bShape,
2877 basegfx::B2DPoint* pCenter,
2878 OUString* pMinHeightValue,
2879 OUString* pMinWidthValue)
2880{
2881 XMLShapeExportFlags nShapeFeatures = SEF_DEFAULT;
2882
2883 // draw:name (#97662#: not for shapes, since those names will be
2884 // treated in the shape export)
2885 if( !bShape )
2886 {
2887 Reference < XNamed > xNamed( rPropSet, UNO_QUERY );
2888 if( xNamed.is() )
2889 {
2890 OUString sName( xNamed->getName() );
2891 if( !sName.isEmpty() )
2893 xNamed->getName() );
2894 }
2895 }
2896
2897 OUStringBuffer sValue;
2898
2899 // text:anchor-type
2900 TextContentAnchorType eAnchor = TextContentAnchorType_AT_PARAGRAPH;
2901 rPropSet->getPropertyValue( gsAnchorType ) >>= eAnchor;
2902 {
2903 XMLAnchorTypePropHdl aAnchorTypeHdl;
2904 OUString sTmp;
2905 aAnchorTypeHdl.exportXML( sTmp, uno::Any(eAnchor),
2906 GetExport().GetMM100UnitConverter() );
2908 }
2909
2910 // text:anchor-page-number
2911 if( TextContentAnchorType_AT_PAGE == eAnchor )
2912 {
2913 sal_Int16 nPage = 0;
2914 rPropSet->getPropertyValue( gsAnchorPageNo ) >>= nPage;
2915 SAL_WARN_IF(nPage <= 0, "xmloff",
2916 "ERROR: writing invalid anchor-page-number 0");
2918 OUString::number( nPage ) );
2919 }
2920 else
2921 {
2922 nShapeFeatures |= XMLShapeExportFlags::NO_WS;
2923 }
2924
2925 // OD 2004-06-01 #i27691# - correction: no export of svg:x, if object
2926 // is anchored as-character.
2927 if ( !bShape &&
2928 eAnchor != TextContentAnchorType_AS_CHARACTER )
2929 {
2930 // svg:x
2931 sal_Int16 nHoriOrient = HoriOrientation::NONE;
2932 rPropSet->getPropertyValue( gsHoriOrient ) >>= nHoriOrient;
2933 if( HoriOrientation::NONE == nHoriOrient )
2934 {
2935 sal_Int32 nPos = 0;
2936 rPropSet->getPropertyValue( gsHoriOrientPosition ) >>= nPos;
2938 sValue, nPos );
2940 sValue.makeStringAndClear() );
2941 if(nullptr != pCenter)
2942 {
2943 // add left edge to Center
2944 pCenter->setX(pCenter->getX() + nPos);
2945 }
2946 }
2947 }
2948 else if( TextContentAnchorType_AS_CHARACTER == eAnchor )
2949 nShapeFeatures = (nShapeFeatures & ~XMLShapeExportFlags::X);
2950
2951 if( !bShape || TextContentAnchorType_AS_CHARACTER == eAnchor )
2952 {
2953 // svg:y
2954 sal_Int16 nVertOrient = VertOrientation::NONE;
2955 rPropSet->getPropertyValue( gsVertOrient ) >>= nVertOrient;
2956 if( VertOrientation::NONE == nVertOrient )
2957 {
2958 sal_Int32 nPos = 0;
2959 rPropSet->getPropertyValue( gsVertOrientPosition ) >>= nPos;
2961 sValue, nPos );
2963 sValue.makeStringAndClear() );
2964 if(nullptr != pCenter)
2965 {
2966 // add top edge to Center
2967 pCenter->setY(pCenter->getY() + nPos);
2968 }
2969 }
2970 if( bShape )
2971 nShapeFeatures = (nShapeFeatures & ~XMLShapeExportFlags::Y);
2972 }
2973
2974 Reference< XPropertySetInfo > xPropSetInfo(rPropSet->getPropertySetInfo());
2975
2976 bool bSyncWidth = false;
2977 if (xPropSetInfo->hasPropertyByName(gsIsSyncWidthToHeight))
2978 {
2979 bSyncWidth = *o3tl::doAccess<bool>(rPropSet->getPropertyValue(gsIsSyncWidthToHeight));
2980 }
2981 sal_Int16 nRelWidth = 0;
2982 if (!bSyncWidth && xPropSetInfo->hasPropertyByName(gsRelativeWidth))
2983 {
2984 rPropSet->getPropertyValue(gsRelativeWidth) >>= nRelWidth;
2985 }
2986 bool bSyncHeight = false;
2987 if (xPropSetInfo->hasPropertyByName(gsIsSyncHeightToWidth))
2988 {
2989 bSyncHeight = *o3tl::doAccess<bool>(rPropSet->getPropertyValue(gsIsSyncHeightToWidth));
2990 }
2991 sal_Int16 nRelHeight = 0;
2992 if (!bSyncHeight && xPropSetInfo->hasPropertyByName(gsRelativeHeight))
2993 {
2994 rPropSet->getPropertyValue(gsRelativeHeight) >>= nRelHeight;
2995 }
2996 awt::Size aLayoutSize;
2997 if ((nRelWidth > 0 || nRelHeight > 0) && xPropSetInfo->hasPropertyByName("LayoutSize"))
2998 {
2999 rPropSet->getPropertyValue("LayoutSize") >>= aLayoutSize;
3000 }
3001
3002 bool bUseLayoutSize = true;
3003 if (bSyncWidth && bSyncHeight)
3004 {
3005 // This is broken, width depends on height and height depends on width. Don't use the
3006 // invalid layout size we got.
3007 bUseLayoutSize = false;
3008 }
3009 if (aLayoutSize.Width <= 0 || aLayoutSize.Height <= 0)
3010 {
3011 // This is broken, Writer frames have a minimal size, see MINFLY.
3012 bUseLayoutSize = false;
3013 }
3014
3015 // svg:width
3016 sal_Int16 nWidthType = SizeType::FIX;
3017 if( xPropSetInfo->hasPropertyByName( gsWidthType ) )
3018 {
3019 rPropSet->getPropertyValue( gsWidthType ) >>= nWidthType;
3020 }
3021 if( xPropSetInfo->hasPropertyByName( gsWidth ) )
3022 {
3023 sal_Int32 nWidth = 0;
3024 // VAR size will be written as zero min-size
3025 if( SizeType::VARIABLE != nWidthType )
3026 {
3027 rPropSet->getPropertyValue( gsWidth ) >>= nWidth;
3028 }
3030 if( SizeType::FIX != nWidthType )
3031 {
3032 assert(pMinWidthValue);
3033 if (pMinWidthValue)
3034 {
3035 *pMinWidthValue = sValue.makeStringAndClear();
3036 }
3037 }
3038 else
3039 {
3040 if ((nRelWidth > 0 || bSyncWidth) && bUseLayoutSize)
3041 {
3042 // Relative width: write the layout size for the fallback width.
3043 sValue.setLength(0);
3044 GetExport().GetMM100UnitConverter().convertMeasureToXML(sValue, aLayoutSize.Width);
3045 }
3046
3048 sValue.makeStringAndClear() );
3049 if(nullptr != pCenter)
3050 {
3051 // add half width to Center
3052 pCenter->setX(pCenter->getX() + (0.5 * nWidth));
3053 }
3054 }
3055 }
3056 if( xPropSetInfo->hasPropertyByName( gsIsSyncWidthToHeight ) )
3057 {
3058 if( bSyncWidth )
3060 XML_SCALE );
3061 }
3062 if( !bSyncWidth && xPropSetInfo->hasPropertyByName( gsRelativeWidth ) )
3063 {
3064 SAL_WARN_IF( nRelWidth < 0 || nRelWidth > 254, "xmloff",
3065 "Got illegal relative width from API" );
3066 if( nRelWidth > 0 )
3067 {
3068 ::sax::Converter::convertPercent( sValue, nRelWidth );
3070 sValue.makeStringAndClear() );
3071 }
3072 }
3073
3074 // svg:height, fo:min-height or style:rel-height
3075 sal_Int16 nSizeType = SizeType::FIX;
3076 if( xPropSetInfo->hasPropertyByName( gsSizeType ) )
3077 {
3078 rPropSet->getPropertyValue( gsSizeType ) >>= nSizeType;
3079 }
3080 if( xPropSetInfo->hasPropertyByName( gsHeight ) )
3081 {
3082 sal_Int32 nHeight = 0;
3083 if( SizeType::VARIABLE != nSizeType )
3084 {
3085 rPropSet->getPropertyValue( gsHeight ) >>= nHeight;
3086 }
3088 nHeight );
3089 if( SizeType::FIX != nSizeType && 0==nRelHeight && !bSyncHeight &&
3090 pMinHeightValue )
3091 {
3092 *pMinHeightValue = sValue.makeStringAndClear();
3093 }
3094 else
3095 {
3096 if ((nRelHeight > 0 || bSyncHeight) && bUseLayoutSize)
3097 {
3098 // Relative height: write the layout size for the fallback height.
3099 sValue.setLength(0);
3100 GetExport().GetMM100UnitConverter().convertMeasureToXML(sValue, aLayoutSize.Height);
3101 }
3102
3104 sValue.makeStringAndClear() );
3105 if(nullptr != pCenter)
3106 {
3107 // add half height to Center
3108 pCenter->setY(pCenter->getY() + (0.5 * nHeight));
3109 }
3110 }
3111 }
3112 if( bSyncHeight )
3113 {
3115 SizeType::MIN == nSizeType ? XML_SCALE_MIN : XML_SCALE );
3116
3117 }
3118 else if( nRelHeight > 0 )
3119 {
3120 ::sax::Converter::convertPercent( sValue, nRelHeight );
3121 if( SizeType::MIN == nSizeType )
3122 {
3123 assert(pMinHeightValue);
3124 if (pMinHeightValue)
3125 {
3126 *pMinHeightValue = sValue.makeStringAndClear();
3127 }
3128 }
3129 else
3131 sValue.makeStringAndClear() );
3132 }
3133
3134 OUString sZOrder( "ZOrder" );
3135 if( xPropSetInfo->hasPropertyByName( sZOrder ) )
3136 {
3137 sal_Int32 nZIndex = 0;
3138 rPropSet->getPropertyValue( sZOrder ) >>= nZIndex;
3139 if( -1 != nZIndex )
3140 {
3142 OUString::number( nZIndex ) );
3143 }
3144 }
3145
3146 if (xPropSetInfo->hasPropertyByName("IsSplitAllowed")
3147 && rPropSet->getPropertyValue("IsSplitAllowed").get<bool>())
3148 {
3150 }
3151
3152 return nShapeFeatures;
3153}
3154
3156 const Reference < XTextContent > & rTxtCntnt,
3157 FrameType eType,
3158 bool bAutoStyles,
3159 bool bIsProgress,
3160 bool bExportContent,
3161 const Reference < XPropertySet > *pRangePropSet)
3162{
3163 Reference < XPropertySet > xPropSet( rTxtCntnt, UNO_QUERY );
3164
3165 if( bAutoStyles )
3166 {
3167 if( FrameType::Embedded == eType )
3169 // No text frame style for shapes (#i28745#)
3170 else if ( FrameType::Shape != eType )
3171 Add( XmlStyleFamily::TEXT_FRAME, xPropSet );
3172
3173 if( pRangePropSet && lcl_txtpara_isBoundAsChar( xPropSet,
3174 xPropSet->getPropertySetInfo() ) )
3175 Add( XmlStyleFamily::TEXT_TEXT, *pRangePropSet );
3176
3177 switch( eType )
3178 {
3179 case FrameType::Text:
3180 {
3181 // frame bound frames
3182 if ( bExportContent )
3183 {
3184 Reference < XTextFrame > xTxtFrame( rTxtCntnt, UNO_QUERY );
3185 bool bAlreadySeen = !maFrameRecurseGuard.insert(xTxtFrame).second;
3186 if (bAlreadySeen)
3187 {
3188 SAL_WARN("xmloff", "loop in frame export, ditching");
3189 }
3190 else
3191 {
3192 comphelper::ScopeGuard const g([this, xTxtFrame]() {
3193 maFrameRecurseGuard.erase(xTxtFrame);
3194 });
3195 Reference < XText > xTxt(xTxtFrame->getText());
3196 exportFrameFrames( true, bIsProgress, xTxtFrame );
3197 exportText( xTxt, bAutoStyles, bIsProgress, true );
3198 }
3199 }
3200 }
3201 break;
3202 case FrameType::Shape:
3203 {
3204 Reference < XShape > xShape( rTxtCntnt, UNO_QUERY );
3205 bool bAlreadySeen = !maShapeRecurseGuard.insert(xShape).second;
3206 if (bAlreadySeen)
3207 {
3208 SAL_WARN("xmloff", "loop in shape export, ditching");
3209 }
3210 else
3211 {
3212 comphelper::ScopeGuard const g([this, xShape]() {
3213 maShapeRecurseGuard.erase(xShape);
3214 });
3215 GetExport().GetShapeExport()->collectShapeAutoStyles( xShape );
3216 }
3217 }
3218 break;
3219 default:
3220 break;
3221 }
3222 }
3223 else
3224 {
3225 Reference< XPropertySetInfo > xPropSetInfo(xPropSet->getPropertySetInfo());
3226 {
3227 bool bAddCharStyles = pRangePropSet &&
3228 lcl_txtpara_isBoundAsChar( xPropSet, xPropSetInfo );
3229
3230 bool bIsUICharStyle;
3231 bool bHasAutoStyle = false;
3232
3233 OUString sStyle;
3234
3235 if( bAddCharStyles )
3236 sStyle = FindTextStyle( *pRangePropSet, bIsUICharStyle, bHasAutoStyle );
3237 else
3238 bIsUICharStyle = false;
3239
3240 bool bDoSomething = bIsUICharStyle
3241 && m_aCharStyleNamesPropInfoCache.hasProperty( *pRangePropSet );
3242 XMLTextCharStyleNamesElementExport aCharStylesExport(
3243 GetExport(), bDoSomething, bHasAutoStyle,
3244 bDoSomething ? *pRangePropSet : Reference<XPropertySet>(),
3246
3247 if( !sStyle.isEmpty() )
3249 GetExport().EncodeStyleName( sStyle ) );
3250 {
3251 SvXMLElementExport aElem( GetExport(), !sStyle.isEmpty(),
3252 XML_NAMESPACE_TEXT, XML_SPAN, false, false );
3253 {
3254 SvXMLElementExport aElement( GetExport(),
3256 HyperlinkData(xPropSet).addHyperlinkAttributes(GetExport()),
3257 XML_NAMESPACE_DRAW, XML_A, false, false );
3258 switch( eType )
3259 {
3260 case FrameType::Text:
3261 _exportTextFrame( xPropSet, xPropSetInfo, bIsProgress );
3262 break;
3263 case FrameType::Graphic:
3264 _exportTextGraphic( xPropSet, xPropSetInfo );
3265 break;
3267 _exportTextEmbedded( xPropSet, xPropSetInfo );
3268 break;
3269 case FrameType::Shape:
3270 {
3271 Reference < XShape > xShape( rTxtCntnt, UNO_QUERY );
3272 XMLShapeExportFlags nFeatures =
3273 addTextFrameAttributes( xPropSet, true );
3275 ->exportShape( xShape, nFeatures );
3276 }
3277 break;
3278 }
3279 }
3280 }
3281 }
3282 }
3283}
3284
3286 const Reference < XPropertySet > & rPropSet,
3287 const Reference < XPropertySetInfo > & rPropSetInfo,
3288 bool bIsProgress )
3289{
3290 Reference < XTextFrame > xTxtFrame( rPropSet, UNO_QUERY );
3291 Reference < XText > xTxt(xTxtFrame->getText());
3292
3293 OUString sStyle;
3294 if( rPropSetInfo->hasPropertyByName( gsFrameStyleName ) )
3295 {
3296 rPropSet->getPropertyValue( gsFrameStyleName ) >>= sStyle;
3297 }
3298
3299 OUString aMinHeightValue;
3300 OUString sMinWidthValue;
3301 OUString sAutoStyle = Find( XmlStyleFamily::TEXT_FRAME, rPropSet, sStyle );
3302 if ( sAutoStyle.isEmpty() )
3303 sAutoStyle = sStyle;
3304 if( !sAutoStyle.isEmpty() )
3306 GetExport().EncodeStyleName( sAutoStyle ) );
3307 addTextFrameAttributes(rPropSet, false, nullptr, &aMinHeightValue, &sMinWidthValue);
3308
3310 XML_FRAME, false, true );
3311
3312 if( !aMinHeightValue.isEmpty() )
3314 aMinHeightValue );
3315
3316 if (!sMinWidthValue.isEmpty())
3317 {
3319 sMinWidthValue );
3320 }
3321
3322 // draw:chain-next-name
3323 if( rPropSetInfo->hasPropertyByName( gsChainNextName ) )
3324 {
3325 OUString sNext;
3326 if( (rPropSet->getPropertyValue( gsChainNextName ) >>= sNext) && !sNext.isEmpty() )
3329 sNext );
3330 }
3331
3332 {
3334 XML_TEXT_BOX, true, true );
3335
3336 // frames bound to frame
3337 exportFrameFrames( false, bIsProgress, xTxtFrame );
3338
3339 exportText( xTxt, false, bIsProgress, true );
3340 }
3341
3342 // script:events
3343 Reference<XEventsSupplier> xEventsSupp( xTxtFrame, UNO_QUERY );
3344 GetExport().GetEventExport().Export(xEventsSupp);
3345
3346 // image map
3347 GetExport().GetImageMapExport().Export( rPropSet );
3348
3349 // svg:title and svg:desc (#i73249#)
3350 exportTitleAndDescription( rPropSet, rPropSetInfo );
3351}
3352
3354 const Reference < XPropertySet > & rPropSet,
3355 const Reference < XPropertySetInfo > & rPropSetInfo )
3356{
3357 if( !rPropSetInfo->hasPropertyByName( gsContourPolyPolygon ) )
3358 {
3359 return;
3360 }
3361
3362 PointSequenceSequence aSourcePolyPolygon;
3363 rPropSet->getPropertyValue( gsContourPolyPolygon ) >>= aSourcePolyPolygon;
3364 const basegfx::B2DPolyPolygon aPolyPolygon(
3366 aSourcePolyPolygon));
3367 const sal_uInt32 nPolygonCount(aPolyPolygon.count());
3368
3369 if(!nPolygonCount)
3370 {
3371 return;
3372 }
3373
3374 const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());
3375 bool bPixel(false);
3376
3377 if( rPropSetInfo->hasPropertyByName( gsIsPixelContour ) )
3378 {
3379 bPixel = *o3tl::doAccess<bool>(rPropSet->getPropertyValue( gsIsPixelContour ));
3380 }
3381
3382 // svg: width
3383 OUStringBuffer aStringBuffer( 10 );
3384
3385 if(bPixel)
3386 {
3387 ::sax::Converter::convertMeasurePx(aStringBuffer, basegfx::fround(aPolyPolygonRange.getWidth()));
3388 }
3389 else
3390 {
3391 GetExport().GetMM100UnitConverter().convertMeasureToXML(aStringBuffer, basegfx::fround(aPolyPolygonRange.getWidth()));
3392 }
3393
3394 GetExport().AddAttribute(XML_NAMESPACE_SVG, XML_WIDTH, aStringBuffer.makeStringAndClear());
3395
3396 // svg: height
3397 if(bPixel)
3398 {
3399 ::sax::Converter::convertMeasurePx(aStringBuffer, basegfx::fround(aPolyPolygonRange.getHeight()));
3400 }
3401 else
3402 {
3403 GetExport().GetMM100UnitConverter().convertMeasureToXML(aStringBuffer, basegfx::fround(aPolyPolygonRange.getHeight()));
3404 }
3405
3406 GetExport().AddAttribute(XML_NAMESPACE_SVG, XML_HEIGHT, aStringBuffer.makeStringAndClear());
3407
3408 // svg:viewbox
3409 SdXMLImExViewBox aViewBox(0.0, 0.0, aPolyPolygonRange.getWidth(), aPolyPolygonRange.getHeight());
3411 enum XMLTokenEnum eElem = XML_TOKEN_INVALID;
3412
3413 if(1 == nPolygonCount )
3414 {
3415 // simple polygon shape, can be written as svg:points sequence
3416 const OUString aPointString(
3418 aPolyPolygon.getB2DPolygon(0)));
3419
3420 // write point array
3422 eElem = XML_CONTOUR_POLYGON;
3423 }
3424 else
3425 {
3426 // polypolygon, needs to be written as a svg:path sequence
3427 const OUString aPolygonString(
3429 aPolyPolygon,
3430 true, // bUseRelativeCoordinates
3431 false, // bDetectQuadraticBeziers: not used in old, but maybe activated now
3432 true)); // bHandleRelativeNextPointCompatible
3433
3434 // write point array
3435 GetExport().AddAttribute( XML_NAMESPACE_SVG, XML_D, aPolygonString);
3436 eElem = XML_CONTOUR_PATH;
3437 }
3438
3439 if( rPropSetInfo->hasPropertyByName( gsIsAutomaticContour ) )
3440 {
3441 bool bTmp = *o3tl::doAccess<bool>(rPropSet->getPropertyValue(
3445 }
3446
3447 // write object now
3449 true, true );
3450}
3451
3453 const Reference < XPropertySet > & rPropSet,
3454 const Reference < XPropertySetInfo > & rPropSetInfo )
3455{
3456 OUString sStyle;
3457 if( rPropSetInfo->hasPropertyByName( gsFrameStyleName ) )
3458 {
3459 rPropSet->getPropertyValue( gsFrameStyleName ) >>= sStyle;
3460 }
3461
3462 OUString sAutoStyle = Find( XmlStyleFamily::TEXT_FRAME, rPropSet, sStyle );
3463 if ( sAutoStyle.isEmpty() )
3464 sAutoStyle = sStyle;
3465 if( !sAutoStyle.isEmpty() )
3467 GetExport().EncodeStyleName( sAutoStyle ) );
3468
3469 // check if we need to use svg:transform
3470 sal_Int16 nRotation(0);
3471 rPropSet->getPropertyValue( gsGraphicRotation ) >>= nRotation;
3472 const bool bUseRotation(0 != nRotation);
3473 basegfx::B2DPoint aCenter(0.0, 0.0);
3474
3475 // add TextFrame attributes like svg:x/y/width/height, also get back
3476 // object's center point if rotation is used and has to be exported
3477 addTextFrameAttributes(rPropSet, false, bUseRotation ? &aCenter : nullptr);
3478
3479 // svg:transform
3480 if(bUseRotation)
3481 {
3482 // RotateFlyFrameFix: im/export full 'draw:transform' using existing tooling.
3483 // Currently only rotation is used, but combinations with 'draw:transform'
3484 // may be necessary in the future, so that svg:x/svg:y/svg:width/svg:height
3485 // may be extended/replaced with 'draw:transform' (see draw objects)
3486 SdXMLImExTransform2D aSdXMLImExTransform2D;
3487
3488 // Convert from 10th degree integer to deg.
3489 // CAUTION: internal rotation is classically mathematically 'wrong' defined by ignoring that
3490 // we have a right-handed coordinate system, so need to correct this by mirroring
3491 // the rotation to get the correct transformation. See also case XML_TOK_TEXT_FRAME_TRANSFORM
3492 // in XMLTextFrameContext_Impl::XMLTextFrameContext_Impl and #i78696#
3493 // CAUTION-II: due to tdf#115782 it is better for current ODF to indeed write it with the wrong
3494 // orientation as in all other cases - ARGH! We will need to correct this in future ODF ASAP!
3495 const double fRotate(basegfx::deg2rad<10>(nRotation));
3496
3497 // transform to rotation center which is the object's center
3498 aSdXMLImExTransform2D.AddTranslate(-aCenter);
3499
3500 // add rotation itself
3501 // tdf#115529 but correct value modulo 2PI to have it positive and in the range of [0.0 .. 2PI[
3502 aSdXMLImExTransform2D.AddRotate(basegfx::normalizeToRange(fRotate, 2 * M_PI));
3503
3504 // back-transform after rotation
3505 aSdXMLImExTransform2D.AddTranslate(aCenter);
3506
3507 // Note: using GetTwipUnitConverter instead of GetMM100UnitConverter may be needed,
3508 // but is not generally available (as it should be, a 'current' UnitConverter should
3509 // be available at GetExport() - and maybe was once). May have to be addressed as soon
3510 // as translate transformations are used here.
3514 aSdXMLImExTransform2D.GetExportString(GetExport().GetMM100UnitConverter()));
3515 }
3516
3517 // original content
3519
3520 {
3521 // xlink:href
3522 uno::Reference<graphic::XGraphic> xGraphic;
3523 rPropSet->getPropertyValue("Graphic") >>= xGraphic;
3524
3525 OUString sInternalURL;
3526 OUString sOutMimeType;
3527
3528 if (xGraphic.is())
3529 {
3530 sInternalURL = GetExport().AddEmbeddedXGraphic(xGraphic, sOutMimeType);
3531 }
3532
3533 // If there still is no url, then graphic is empty
3534 if (!sInternalURL.isEmpty())
3535 {
3540 }
3541
3542 // draw:filter-name
3543 OUString sGrfFilter;
3544 rPropSet->getPropertyValue( gsGraphicFilter ) >>= sGrfFilter;
3545 if( !sGrfFilter.isEmpty() )
3547 sGrfFilter );
3548
3549 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012)
3550 {
3551 if (sOutMimeType.isEmpty())
3552 {
3553 GetExport().GetGraphicMimeTypeFromStream(xGraphic, sOutMimeType);
3554 }
3555 if (!sOutMimeType.isEmpty())
3556 { // ODF 1.3 OFFICE-3943
3558 SvtSaveOptions::ODFSVER_013 <= GetExport().getSaneDefaultVersion()
3561 "mime-type", sOutMimeType);
3562 }
3563 }
3564
3565
3566 // optional office:binary-data
3567 if (xGraphic.is())
3568 {
3569 SvXMLElementExport aElement(GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, false, true );
3571 }
3572 }
3573
3574 const bool bAddReplacementImages = officecfg::Office::Common::Save::Graphic::AddReplacementImages::get();
3575 if (bAddReplacementImages)
3576 {
3577 // replacement graphic for backwards compatibility, but
3578 // only for SVG and metafiles currently
3579 uno::Reference<graphic::XGraphic> xReplacementGraphic;
3580 rPropSet->getPropertyValue("ReplacementGraphic") >>= xReplacementGraphic;
3581
3582 OUString sInternalURL;
3583 OUString sOutMimeType;
3584
3585 //Resolves: fdo#62461 put preferred image first above, followed by
3586 //fallback here
3587 if (xReplacementGraphic.is())
3588 {
3589 sInternalURL = GetExport().AddEmbeddedXGraphic(xReplacementGraphic, sOutMimeType);
3590 }
3591
3592 // If there is no url, then graphic is empty
3593 if (!sInternalURL.isEmpty())
3594 {
3599 }
3600
3601 if (GetExport().getSaneDefaultVersion() > SvtSaveOptions::ODFSVER_012)
3602 {
3603 if (sOutMimeType.isEmpty())
3604 {
3605 GetExport().GetGraphicMimeTypeFromStream(xReplacementGraphic, sOutMimeType);
3606 }
3607 if (!sOutMimeType.isEmpty())
3608 { // ODF 1.3 OFFICE-3943
3610 SvtSaveOptions::ODFSVER_013 <= GetExport().getSaneDefaultVersion()
3613 "mime-type", sOutMimeType);
3614 }
3615 }
3616
3617
3618 // optional office:binary-data
3619 if (xReplacementGraphic.is())
3620 {
3621 SvXMLElementExport aElement(GetExport(), XML_NAMESPACE_DRAW, XML_IMAGE, true, true);
3622 GetExport().AddEmbeddedXGraphicAsBase64(xReplacementGraphic);
3623 }
3624 }
3625
3626 // script:events
3627 Reference<XEventsSupplier> xEventsSupp( rPropSet, UNO_QUERY );
3628 GetExport().GetEventExport().Export(xEventsSupp);
3629
3630 // image map
3631 GetExport().GetImageMapExport().Export( rPropSet );
3632
3633 // svg:title and svg:desc (#i73249#)
3634 exportTitleAndDescription( rPropSet, rPropSetInfo );
3635
3636 // draw:contour
3637 exportContour( rPropSet, rPropSetInfo );
3638}
3639
3640void XMLTextParagraphExport::_collectTextEmbeddedAutoStyles(const Reference < XPropertySet > & )
3641{
3642 SAL_WARN( "xmloff", "no API implementation available" );
3643}
3644
3646 const Reference < XPropertySet > &,
3647 const Reference < XPropertySetInfo > & )
3648{
3649 SAL_WARN( "xmloff", "no API implementation available" );
3650}
3651
3652void XMLTextParagraphExport::exportEvents( const Reference < XPropertySet > & rPropSet )
3653{
3654 // script:events
3655 Reference<XEventsSupplier> xEventsSupp( rPropSet, UNO_QUERY );
3656 GetExport().GetEventExport().Export(xEventsSupp);
3657
3658 // image map
3659 if (rPropSet->getPropertySetInfo()->hasPropertyByName("ImageMap"))
3660 GetExport().GetImageMapExport().Export( rPropSet );
3661}
3662
3663// Implement Title/Description Elements UI (#i73249#)
3665 const Reference < XPropertySet > & rPropSet,
3666 const Reference < XPropertySetInfo > & rPropSetInfo )
3667{
3668 // svg:title
3669 if( rPropSetInfo->hasPropertyByName( gsTitle ) )
3670 {
3671 OUString sObjTitle;
3672 rPropSet->getPropertyValue( gsTitle ) >>= sObjTitle;
3673 if( !sObjTitle.isEmpty() )
3674 {
3676 XML_TITLE, true, false );
3677 GetExport().Characters( sObjTitle );
3678 }
3679 }
3680
3681 // svg:description
3682 if( rPropSetInfo->hasPropertyByName( gsDescription ) )
3683 {
3684 OUString sObjDesc;
3685 rPropSet->getPropertyValue( gsDescription ) >>= sObjDesc;
3686 if( !sObjDesc.isEmpty() )
3687 {
3689 XML_DESC, true, false );
3690 GetExport().Characters( sObjDesc );
3691 }
3692 }
3693}
3694
3696 const css::uno::Reference< css::text::XTextRange > & rTextRange,
3697 Reference< XPropertySet > const & xPropSet,
3698 Reference < XPropertySetInfo > & xPropSetInfo,
3699 const bool bIsUICharStyle,
3700 const bool bHasAutoStyle,
3701 const OUString& sStyle,
3702 bool& rPrevCharIsSpace,
3703 FieldmarkType& openFieldMark )
3704{
3705 XMLTextCharStyleNamesElementExport aCharStylesExport(
3706 GetExport(),
3707 bIsUICharStyle && m_aCharStyleNamesPropInfoCache.hasProperty( xPropSet, xPropSetInfo ),
3708 bHasAutoStyle,
3709 xPropSet,
3711
3712 if ( !sStyle.isEmpty() )
3713 {
3714 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME, GetExport().EncodeStyleName( sStyle ) );
3715 }
3716 {
3717 SvXMLElementExport aElement( GetExport(), !sStyle.isEmpty(), XML_NAMESPACE_TEXT, XML_SPAN, false, false );
3718 const OUString aText( rTextRange->getString() );
3719 SvXMLElementExport aElem2( GetExport(), TEXT == openFieldMark,
3721 false, false );
3722 exportCharacterData(aText, rPrevCharIsSpace);
3723 openFieldMark = NONE;
3724 }
3725}
3726
3728 const Reference< XTextRange > & rTextRange,
3729 bool bAutoStyles,
3730 bool& rPrevCharIsSpace,
3731 FieldmarkType& openFieldMark )
3732{
3733 Reference< XPropertySet > xPropSet( rTextRange, UNO_QUERY );
3734 if ( bAutoStyles )
3735 {
3736 Add( XmlStyleFamily::TEXT_TEXT, xPropSet );
3737 }
3738 else
3739 {
3740 bool bIsUICharStyle = false;
3741 bool bHasAutoStyle = false;
3742 const OUString sStyle(
3743 FindTextStyle( xPropSet, bIsUICharStyle, bHasAutoStyle ) );
3744
3745 Reference < XPropertySetInfo > xPropSetInfo;
3746 exportTextRangeSpan( rTextRange, xPropSet, xPropSetInfo, bIsUICharStyle, bHasAutoStyle, sStyle, rPrevCharIsSpace, openFieldMark );
3747 }
3748}
3749
3751 bool& rPrevCharIsSpace )
3752{
3753 sal_Int32 nExpStartPos = 0;
3754 sal_Int32 nEndPos = rText.getLength();
3755 sal_Int32 nSpaceChars = 0;
3756 for( sal_Int32 nPos = 0; nPos < nEndPos; nPos++ )
3757 {
3758 sal_Unicode cChar = rText[nPos];
3759 bool bExpCharAsText = true;
3760 bool bExpCharAsElement = false;
3761 bool bCurrCharIsSpace = false;
3762 switch( cChar )
3763 {
3764 case 0x0009: // Tab
3765 case 0x000A: // LF
3766 // These characters are exported as text.
3767 bExpCharAsElement = true;
3768 bExpCharAsText = false;
3769 break;
3770 case 0x000D:
3771 break; // legal character
3772 case 0x0020: // Blank
3773 if( rPrevCharIsSpace )
3774 {
3775 // If the previous character is a space character,
3776 // too, export a special space element.
3777 bExpCharAsText = false;
3778 }
3779 bCurrCharIsSpace = true;
3780 break;
3781 default:
3782 if( cChar < 0x0020 )
3783 {
3784#ifdef DBG_UTIL
3786 cChar >= 0x0020,
3787 "illegal character in text content" );
3789#endif
3790 bExpCharAsText = false;
3791 }
3792 break;
3793 }
3794
3795 // If the current character is not exported as text
3796 // the text that has not been exported by now has to be exported now.
3797 if( nPos > nExpStartPos && !bExpCharAsText )
3798 {
3799 SAL_WARN_IF( 0 != nSpaceChars, "xmloff", "pending spaces" );
3800 OUString sExp( rText.copy( nExpStartPos, nPos - nExpStartPos ) );
3801 GetExport().Characters( sExp );
3802 nExpStartPos = nPos;
3803 }
3804
3805 // If there are spaces left that have not been exported and the
3806 // current character is not a space , the pending spaces have to be
3807 // exported now.
3808 if( nSpaceChars > 0 && !bCurrCharIsSpace )
3809 {
3810 SAL_WARN_IF( nExpStartPos != nPos, "xmloff", " pending characters" );
3811
3812 if( nSpaceChars > 1 )
3813 {
3815 OUString::number(nSpaceChars) );
3816 }
3817
3819 XML_S, false, false );
3820
3821 nSpaceChars = 0;
3822 }
3823
3824 // If the current character has to be exported as a special
3825 // element, the element will be exported now.
3826 if( bExpCharAsElement )
3827 {
3828 switch( cChar )
3829 {
3830 case 0x0009: // Tab
3831 {
3833 XML_TAB, false,
3834 false );
3835 }
3836 break;
3837 case 0x000A: // LF
3838 {
3840 XML_LINE_BREAK, false,
3841 false );
3842 }
3843 break;
3844 }
3845 }
3846
3847 // If the current character is a space, and the previous one
3848 // is a space, too, the number of pending spaces is incremented
3849 // only.
3850 if( bCurrCharIsSpace && rPrevCharIsSpace )
3851 nSpaceChars++;
3852 rPrevCharIsSpace = bCurrCharIsSpace;
3853
3854 // If the current character is not exported as text, the start
3855 // position for text is the position behind the current position.
3856 if( !bExpCharAsText )
3857 {
3858 SAL_WARN_IF( nExpStartPos != nPos, "xmloff", "wrong export start pos" );
3859 nExpStartPos = nPos+1;
3860 }
3861 }
3862
3863 if( nExpStartPos < nEndPos )
3864 {
3865 SAL_WARN_IF( 0 != nSpaceChars, "xmloff", " pending spaces " );
3866 OUString sExp( rText.copy( nExpStartPos, nEndPos - nExpStartPos ) );
3867 GetExport().Characters( sExp );
3868 }
3869
3870 // If there are some spaces left, they have to be exported now.
3871 if( nSpaceChars > 0 )
3872 {
3873 if( nSpaceChars > 1 )
3874 {
3876 OUString::number(nSpaceChars) );
3877 }
3878
3880 false, false );
3881 }
3882}
3883
3885{
3886 m_pFieldExport->ExportFieldDeclarations();
3887
3888 // get XPropertySet from the document and ask for AutoMarkFileURL.
3889 // If it exists, export the auto-mark-file element.
3890 Reference<XPropertySet> xPropertySet( GetExport().GetModel(), UNO_QUERY );
3891 if (!xPropertySet.is())
3892 return;
3893
3894 OUString sUrl;
3895 OUString sIndexAutoMarkFileURL(
3896 "IndexAutoMarkFileURL");
3897 if (!xPropertySet->getPropertySetInfo()->hasPropertyByName(
3898 sIndexAutoMarkFileURL))
3899 return;
3900
3901 xPropertySet->getPropertyValue(sIndexAutoMarkFileURL) >>= sUrl;
3902 if (!sUrl.isEmpty())
3903 {
3905 GetExport().GetRelativeReference(sUrl) );
3906 SvXMLElementExport aAutoMarkElement(
3909 true, true );
3910 }
3911}
3912
3914 const Reference<XText> & rText )
3915{
3916 m_pFieldExport->ExportFieldDeclarations(rText);
3917}
3918
3920{
3921 m_pFieldExport->SetExportOnlyUsedFieldDeclarations( false/*bOnlyUsed*/ );
3922}
3923
3925{
3926 if (nullptr != m_pRedlineExport)
3927 m_pRedlineExport->ExportChangesList( bAutoStyles );
3928}
3929
3931 const Reference<XText> & rText,
3932 bool bAutoStyle)
3933{
3934 if (nullptr != m_pRedlineExport)
3935 m_pRedlineExport->ExportChangesList(rText, bAutoStyle);
3936}
3937
3939 const Reference<XText> & rText )
3940{
3941 if (nullptr != m_pRedlineExport)
3942 m_pRedlineExport->SetCurrentXText(rText);
3943}
3944
3946{
3947 if (nullptr != m_pRedlineExport)
3948 m_pRedlineExport->SetCurrentXText();
3949}
3950
3952
3954{
3955 // tdf#135942: do not collect styles during their export: this may modify iterated containers
3956 mbCollected = true;
3958
3960
3962
3964
3966
3968
3970}
3971
3973 const Reference<XPropertySet> & rPropSet,
3974 bool bAutoStyles )
3975{
3976 // early out: a collapsed ruby makes no sense
3977 if (*o3tl::doAccess<bool>(rPropSet->getPropertyValue(gsIsCollapsed)))
3978 return;
3979
3980 // start value ?
3981 bool bStart = *o3tl::doAccess<bool>(rPropSet->getPropertyValue(gsIsStart));
3982
3983 if (bAutoStyles)
3984 {
3985 // ruby auto styles
3986 if (bStart)
3987 Add( XmlStyleFamily::TEXT_RUBY, rPropSet );
3988 }
3989 else
3990 {
3991 if (bStart)
3992 {
3993 // ruby start
3994
3995 // we can only start a ruby if none is open
3996 assert(!m_bOpenRuby && "Can't open a ruby inside of ruby!");
3997 if( m_bOpenRuby )
3998 return;
3999
4000 // save ruby text + ruby char style
4001 rPropSet->getPropertyValue(gsRubyText) >>= m_sOpenRubyText;
4002 rPropSet->getPropertyValue(gsRubyCharStyleName) >>= m_sOpenRubyCharStyle;
4003
4004 // ruby style
4006 OUString sStyleName(Find(XmlStyleFamily::TEXT_RUBY, rPropSet, ""));
4007 SAL_WARN_IF(sStyleName.isEmpty(), "xmloff", "Can't find ruby style!");
4009 XML_STYLE_NAME, sStyleName);
4010
4011 // export <text:ruby> and <text:ruby-base> start elements
4015 false );
4016 m_bOpenRuby = true;
4017 }
4018 else
4019 {
4020 // ruby end
4021
4022 // check for an open ruby
4023 assert(m_bOpenRuby && "Can't close a ruby if none is open!");
4024 if( !m_bOpenRuby )
4025 return;
4026
4027 // close <text:ruby-base>
4029 false);
4030
4031 // write the ruby text (with char style)
4032 {
4033 if (!m_sOpenRubyCharStyle.isEmpty())
4036 GetExport().EncodeStyleName( m_sOpenRubyCharStyle) );
4037
4038 SvXMLElementExport aRubyElement(
4040 false, false);
4041
4043 }
4044
4045 // and finally, close the ruby
4047 m_bOpenRuby = false;
4048 }
4049 }
4050}
4051
4053 const Reference<XPropertySet> & i_xPortion,
4054 bool i_bAutoStyles, bool i_isProgress, bool & rPrevCharIsSpace)
4055{
4056 bool doExport(!i_bAutoStyles); // do not export element if autostyles
4057 // check version >= 1.2
4058 switch (GetExport().getSaneDefaultVersion()) {
4059 case SvtSaveOptions::ODFSVER_011: // fall through
4060 case SvtSaveOptions::ODFSVER_010: doExport = false; break;
4061 default: break;
4062 }
4063
4064 const Reference< XTextContent > xTextContent(
4065 i_xPortion->getPropertyValue("InContentMetadata"), UNO_QUERY_THROW);
4066 const Reference< XEnumerationAccess > xEA( xTextContent, UNO_QUERY_THROW );
4067 const Reference< XEnumeration > xTextEnum( xEA->createEnumeration() );
4068
4069 if (doExport)
4070 {
4071 const Reference<rdf::XMetadatable> xMeta(xTextContent, UNO_QUERY_THROW);
4072
4073 // text:meta with neither xml:id nor RDFa is invalid
4074 xMeta->ensureMetadataReference();
4075
4076 // xml:id and RDFa for RDF metadata
4078 GetExport().AddAttributesRDFa(xTextContent);
4079 }
4080
4081 SvXMLElementExport aElem( GetExport(), doExport,
4082 XML_NAMESPACE_TEXT, XML_META, false, false );
4083
4084 // recurse to export content
4085 exportTextRangeEnumeration(xTextEnum, i_bAutoStyles, i_isProgress, rPrevCharIsSpace);
4086}
4087
4089 const uno::Reference<beans::XPropertySet>& xPortion, bool bAutoStyles, bool isProgress,
4090 bool& rPrevCharIsSpace)
4091{
4092 // Do not export the element in the autostyle case.
4093 bool bExport = !bAutoStyles;
4094 if (!(GetExport().getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED))
4095 {
4096 bExport = false;
4097 }
4098
4099 uno::Reference<text::XTextContent> xTextContent(xPortion->getPropertyValue("ContentControl"),
4100 uno::UNO_QUERY_THROW);
4101 uno::Reference<container::XEnumerationAccess> xEA(xTextContent, uno::UNO_QUERY_THROW);
4102 uno::Reference<container::XEnumeration> xTextEnum = xEA->createEnumeration();
4103
4104 uno::Reference<beans::XPropertySet> xPropertySet(xTextContent, uno::UNO_QUERY_THROW);
4105 if (bExport)
4106 {
4107 bool bShowingPlaceHolder = false;
4108 xPropertySet->getPropertyValue("ShowingPlaceHolder") >>= bShowingPlaceHolder;
4109 if (bShowingPlaceHolder)
4110 {
4111 OUStringBuffer aBuffer;
4112 sax::Converter::convertBool(aBuffer, bShowingPlaceHolder);
4114 aBuffer.makeStringAndClear());
4115 }
4116
4117 bool bCheckbox = false;
4118 xPropertySet->getPropertyValue("Checkbox") >>= bCheckbox;
4119 if (bCheckbox)
4120 {
4121 OUStringBuffer aBuffer;
4124 }
4125
4126 bool bChecked = false;
4127 xPropertySet->getPropertyValue("Checked") >>= bChecked;
4128 if (bChecked)
4129 {
4130 OUStringBuffer aBuffer;
4133 }
4134
4135 OUString aCheckedState;
4136 xPropertySet->getPropertyValue("CheckedState") >>= aCheckedState;
4137 if (!aCheckedState.isEmpty())
4138 {
4140 }
4141
4142 OUString aUncheckedState;
4143 xPropertySet->getPropertyValue("UncheckedState") >>= aUncheckedState;
4144 if (!aUncheckedState.isEmpty())
4145 {
4147 }
4148
4149 bool bPicture = false;
4150 xPropertySet->getPropertyValue("Picture") >>= bPicture;
4151 if (bPicture)
4152 {
4153 OUStringBuffer aBuffer;
4156 aBuffer.makeStringAndClear());
4157 }
4158
4159 bool bDate = false;
4160 xPropertySet->getPropertyValue("Date") >>= bDate;
4161 if (bDate)
4162 {
4163 OUStringBuffer aBuffer;
4166 }
4167
4168 OUString aDateFormat;
4169 xPropertySet->getPropertyValue("DateFormat") >>= aDateFormat;
4170 if (!aDateFormat.isEmpty())
4171 {
4173 }
4174
4175 OUString aDateLanguage;
4176 xPropertySet->getPropertyValue("DateLanguage") >>= aDateLanguage;
4177 if (!aDateLanguage.isEmpty())
4178 {
4180 }
4181 OUString aCurrentDate;
4182 xPropertySet->getPropertyValue("CurrentDate") >>= aCurrentDate;
4183 if (!aCurrentDate.isEmpty())
4184 {
4186 }
4187
4188 bool bPlainText = false;
4189 xPropertySet->getPropertyValue("PlainText") >>= bPlainText;
4190 if (bPlainText)
4191 {
4192 OUStringBuffer aBuffer;
4195 }
4196
4197 bool bComboBox = false;
4198 xPropertySet->getPropertyValue("ComboBox") >>= bComboBox;
4199 if (bComboBox)
4200 {
4201 OUStringBuffer aBuffer;
4204 }
4205
4206 bool bDropDown = false;
4207 xPropertySet->getPropertyValue("DropDown") >>= bDropDown;
4208 if (bDropDown)
4209 {
4210 OUStringBuffer aBuffer;
4213 }
4214
4215 OUString aAlias;
4216 xPropertySet->getPropertyValue("Alias") >>= aAlias;
4217 if (!aAlias.isEmpty())
4218 {
4220 }
4221
4222 OUString aTag;
4223 xPropertySet->getPropertyValue("Tag") >>= aTag;
4224 if (!aTag.isEmpty())
4225 {
4227 }
4228
4229 sal_Int32 nId = 0;
4230 xPropertySet->getPropertyValue("Id") >>= nId;
4231 if (nId)
4232 {
4233 GetExport().AddAttribute(XML_NAMESPACE_LO_EXT, XML_ID, OUString::number(nId));
4234 }
4235
4236 sal_uInt32 nTabIndex = 0;
4237 if ((xPropertySet->getPropertyValue("TabIndex") >>= nTabIndex) && nTabIndex)
4238 {
4240 OUString::number(nTabIndex));
4241 }
4242
4243 OUString aLock;
4244 xPropertySet->getPropertyValue("Lock") >>= aLock;
4245 if (!aLock.isEmpty())
4246 {
4248 }
4249 }
4250
4252 false);
4253
4254 if (bExport)
4255 {
4256 // Export list items of dropdowns.
4257 uno::Sequence<beans::PropertyValues> aListItems;
4258 xPropertySet->getPropertyValue("ListItems") >>= aListItems;
4259 for (const auto& rListItem : aListItems)
4260 {
4262 auto it = aMap.find("DisplayText");
4263 OUString aValue;
4264 if (it != aMap.end() && (it->second >>= aValue) && !aValue.isEmpty())
4265 {
4267 }
4268
4269 it = aMap.find("Value");
4270 if (it != aMap.end() && (it->second >>= aValue))
4271 {
4273 }
4274
4276 false);
4277 }
4278 }
4279
4280 // Recurse to export content.
4281 exportTextRangeEnumeration(xTextEnum, bAutoStyles, isProgress, rPrevCharIsSpace);
4282}
4283
4285 const Reference<XIndexAccess> & rShapes,
4287{
4288 // check parameters ad pre-conditions
4289 if( ( ! rShapes.is() ) || ( ! xFormExport.is() ) )
4290 {
4291 // if we don't have shapes or a form export, there's nothing to do
4292 return;
4293 }
4294 SAL_WARN_IF( m_pSectionExport == nullptr, "xmloff", "We need the section export." );
4295
4296 Reference<XEnumeration> xShapesEnum = m_pBoundFrameSets->GetShapes()->createEnumeration();
4297 if(!xShapesEnum.is())
4298 return;
4299 while( xShapesEnum->hasMoreElements() )
4300 {
4301 // now we need to check
4302 // 1) if this is a control shape, and
4303 // 2) if it's in a mute section
4304 // if both answers are 'yes', notify the form layer export
4305
4306 // we join accessing the shape and testing for control
4307 Reference<XControlShape> xControlShape(xShapesEnum->nextElement(), UNO_QUERY);
4308 if( xControlShape.is() )
4309 {
4310 // Reference<XPropertySet> xPropSet( xControlShape, UNO_QUERY );
4311 // Reference<XTextContent> xTextContent;
4312 // xPropSet->getPropertyValue("TextRange") >>= xTextContent;
4313
4314 Reference<XTextContent> xTextContent( xControlShape, UNO_QUERY );
4315 if( xTextContent.is() )
4316 {
4317 if( m_pSectionExport->IsMuteSection( xTextContent, false ) )
4318 {
4319 // Ah, we've found a shape that
4320 // 1) is a control shape
4321 // 2) is anchored in a mute section
4322 // so: don't export it!
4323 xFormExport->excludeFromExport(
4324 xControlShape->getControl() );
4325 }
4326 // else: not in mute section -> should be exported -> nothing
4327 // to do
4328 }
4329 // else: no anchor -> ignore
4330 }
4331 // else: no control shape -> nothing to do
4332 }
4333}
4334
4336{
4337 maTextListsHelperStack.emplace_back( new XMLTextListsHelper() );
4339}
4340
4342{
4343 mpTextListsHelper = nullptr;
4344 maTextListsHelperStack.pop_back();
4345 if ( !maTextListsHelperStack.empty() )
4346 {
4348 }
4349}
4350
4351/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OptionalString sType
constexpr OUStringLiteral sHidden
The MultiPropertySetHelper performs the following functions:
void hasProperties(const css::uno::Reference< css::beans::XPropertySetInfo > &)
Call hasPropertiesByName for the provided XPropertySetInfo and build list of allowed properties.
const css::uno::Any & getValue(sal_Int16 nIndex)
Get a value from the values array.
bool hasProperty(sal_Int16 nIndex)
Find out if this property is supported.
bool checkedProperties()
Return whether hasProperties was called (i.e.
void SetValue(sal_Int32 nValue)
sal_Int32 GetValue() const
void AddTranslate(const ::basegfx::B2DTuple &rNew)
Definition: xexptran.cxx:232
void AddRotate(double fNew)
Definition: xexptran.cxx:226
const OUString & GetExportString(const SvXMLUnitConverter &rConv)
Definition: xexptran.cxx:245
const OUString & GetExportString()
Definition: xexptran.cxx:1034
bool hasProperty(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo)
void AddFamily(XmlStyleFamily nFamily, const OUString &rStrName, SvXMLExportPropertyMapper *pMapper, const OUString &aStrPrefix)
register a new family with its appropriate instance of a derivation of XMLPropertySetMapper for famil...
Definition: xmlaustp.cxx:271
void exportXML(XmlStyleFamily nFamily) const
Export all item sets ofs a certain class in the order in that they have been added.
Definition: xmlaustp.cxx:367
ProgressBarHelper * GetProgressBarHelper()
Definition: xmlexp.cxx:1941
::comphelper::UnoInterfaceToUniqueIdentifierMapper & getInterfaceToIdentifierMapper()
Definition: xmlexp.cxx:2248
OUString GetRelativeReference(const OUString &rValue)
Definition: xmlexp.cxx:2057
void AddAttributeXmlId(css::uno::Reference< css::uno::XInterface > const &i_xIfc)
add xml:id attribute (for RDF metadata)
Definition: xmlexp.cxx:2290
XMLEventExport & GetEventExport()
get Event export, with handlers for script types "None" and "StarBasic" already registered; other han...
Definition: xmlexp.cxx:1989
void StartElement(sal_uInt16 nPrefix, enum ::xmloff::token::XMLTokenEnum eName, bool bIgnWSOutside)
Definition: xmlexp.cxx:2091
rtl::Reference< XMLTextParagraphExport > const & GetTextParagraphExport()
Definition: xmlexp.hxx:557
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
Definition: xmlexp.cxx:907
void Characters(const OUString &rChars)
Definition: xmlexp.cxx:2126
bool GetGraphicMimeTypeFromStream(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic, OUString &rOutMimeType)
Definition: xmlexp.cxx:1860
void ClearAttrList()
Definition: xmlexp.cxx:1006
void SAL_DLLPRIVATE AddAttributeIdLegacy(sal_uInt16 const nLegacyPrefix, OUString const &rValue)
add xml:id and legacy namespace id
Definition: xmlexp.cxx:2274
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
returns the deterministic version for odf export
Definition: xmlexp.cxx:2264
rtl::Reference< XMLShapeExport > const & GetShapeExport()
Definition: xmlexp.hxx:565
OUString EncodeStyleName(const OUString &rName, bool *pEncoded=nullptr) const
Definition: xmlexp.cxx:1934
bool AddEmbeddedXGraphicAsBase64(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic)
Definition: xmlexp.cxx:1875
void CheckAttrList()
Definition: xmlexp.cxx:1012
XMLImageMapExport & GetImageMapExport()
get the export for image maps
Definition: xmlexp.cxx:2005
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlexp.hxx:391
void AddAttributesRDFa(css::uno::Reference< css::text::XTextContent > const &i_xTextContent)
add RDFa attributes for a metadatable text content
Definition: xmlexp.cxx:2340
void EndElement(sal_uInt16 nPrefix, enum ::xmloff::token::XMLTokenEnum eName, bool bIgnWSInside)
Definition: xmlexp.cxx:2148
OUString AddEmbeddedXGraphic(css::uno::Reference< css::graphic::XGraphic > const &rxGraphic, OUString &rOutMimeType, OUString const &rRequestedName=OUString())
Definition: xmlexp.cxx:1838
void convertMeasureToXML(OUStringBuffer &rBuffer, sal_Int32 nMeasure) const
convert measure to string: from meCoreMeasureUnit to meXMLMeasureUnit
Definition: xmluconv.cxx:208
virtual bool exportXML(OUString &rStrExpValue, const css::uno::Any &rValue, const SvXMLUnitConverter &rUnitConverter) const override
Exports the given value according to the XML-data-type corresponding to the derived class.
Definition: txtprhdl.cxx:614
void Export(css::uno::Reference< css::document::XEventsSupplier > const &xAccess, bool bUseWhitespace=true)
export the events (calls EventExport::Export(Reference<XNameAccess>) )
void Export(const css::uno::Reference< css::beans::XPropertySet > &rPropertySet)
Get the ImageMap object from the "ImageMap" property and subsequently export the map (if present).
This class handles the export of index marks for table of content, alphabetical and user index.
This class handles the export of redline portions.
This class handles the export of sections and indices (which are, internally, just sections).
static bool IsInSection(const css::uno::Reference< css::text::XTextSection > &rEnclosingSection, const css::uno::Reference< css::text::XTextContent > &rContent, bool bDefault)
Determine whether rContent is contained in rEnclosingSection.
SvXMLExport & GetExport()
Definition: styleexp.hxx:59
OUString Add(const css::uno::Reference< css::container::XIndexReplace > &rNumRules)
information about list and list style for a certain paragraph
const OUString & GetNumRulesName() const
const OUString & ListLabelString() const
const OUString & GetListId() const
sal_Int16 GetListLevelStartValue() const
sal_Int16 GetLevel() const
bool IsListIdDefault() const
void Set(const css::uno::Reference< css::text::XTextContent > &rTextContent, bool bOutlineStyleAsNormalListStyle, const XMLTextListAutoStylePool &rListAutoPool, bool bExportTextNumberElement, bool bListIdIsDefault)
bool BelongsToSameList(const XMLTextNumRuleInfo &rCmp) const
sal_uInt32 GetStartValue() const
bool IsContinueingPreviousSubTree() const
void recordTrackedChangesForXText(const css::uno::Reference< css::text::XText > &rText)
Record tracked changes for this particular XText (empty reference stop recording) This should be used...
Definition: txtparae.cxx:3938
std::unique_ptr< XMLRedlineExport > m_pRedlineExport
may be NULL (if no redlines should be exported; e.g. in block mode)
Definition: txtparae.hxx:101
SvXMLAutoStylePoolP & GetAutoStylePool()
Definition: txtparae.hxx:166
void exportTextFrame(const css::uno::Reference< css::text::XTextContent > &rTextContent, bool bAutoStyles, bool bProgress, bool bExportContent, const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet=nullptr)
Definition: txtparae.hxx:556
virtual void _exportTextEmbedded(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo)
Definition: txtparae.cxx:3645
void exportShape(const css::uno::Reference< css::text::XTextContent > &rTextContent, bool bAutoStyles, const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet=nullptr)
Definition: txtparae.hxx:583
virtual void _collectTextEmbeddedAutoStyles(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
Definition: txtparae.cxx:3640
void exportTextField(const css::uno::Reference< css::text::XTextRange > &rTextRange, bool bAutoStyles, bool bProgress, bool *pPrevCharIsSpace)
std::unique_ptr< XMLSectionExport > m_pSectionExport
Definition: txtparae.hxx:97
std::unique_ptr< XMLIndexMarkExport > m_pIndexMarkExport
Definition: txtparae.hxx:98
rtl::Reference< SvXMLExportPropertyMapper > m_xRubyPropMapper
Definition: txtparae.hxx:91
virtual void exportTableAutoStyles()
Definition: txtparae.cxx:3951
void PreventExportOfControlsInMuteSections(const css::uno::Reference< css::container::XIndexAccess > &rShapes, const rtl::Reference< xmloff::OFormLayerXMLExport > &xFormExport)
exclude form controls which are in mute sections.
Definition: txtparae.cxx:4284
void exportTextDeclarations()
This method exports (text field) declarations etc.
Definition: txtparae.cxx:3884
bool ShouldSkipListId(const css::uno::Reference< css::text::XTextContent > &xTextContent)
Definition: txtparae.cxx:1899
void exportTitleAndDescription(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo)
Definition: txtparae.cxx:3664
static constexpr OUStringLiteral gsCharStyleNames
Definition: txtparae.hxx:146
const ::std::unique_ptr< ::xmloff::BoundFrameSets > m_pBoundFrameSets
Definition: txtparae.hxx:93
virtual ~XMLTextParagraphExport() override
Definition: txtparae.cxx:1512
rtl::Reference< SvXMLExportPropertyMapper > m_xFramePropMapper
Definition: txtparae.hxx:88
rtl::Reference< SvXMLExportPropertyMapper > m_xParaPropMapper
Definition: txtparae.hxx:86
XMLTextListsHelper * mpTextListsHelper
Definition: txtparae.hxx:112
void exportFrameFrames(bool bAutoStyles, bool bProgress, const css::uno::Reference< css::text::XTextFrame > &rParentTxtFrame)
Definition: txtparae.cxx:1582
::std::vector< std::unique_ptr< XMLTextListsHelper > > maTextListsHelperStack
Definition: txtparae.hxx:113
void exportTextGraphic(const css::uno::Reference< css::text::XTextContent > &rTextContent, bool bAutoStyles, const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet=nullptr)
Definition: txtparae.hxx:565
void exportContour(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo)
Definition: txtparae.cxx:3353
std::unique_ptr< DocumentListNodes > mpDocumentListNodes
Definition: txtparae.hxx:115
virtual void exportTable(const css::uno::Reference< css::text::XTextContent > &rTextContent, bool bAutoStyles, bool bProgress)
Definition: txtparae.cxx:2698
OUString m_sOpenRubyCharStyle
Definition: txtparae.hxx:109
void collectTextAutoStylesOptimized(bool bIsProgress)
Definition: txtparae.cxx:1623
void exportTextRangeEnumeration(const css::uno::Reference< css::container::XEnumeration > &rRangeEnum, bool bAutoStyles, bool bProgress, bool &rPrevCharIsSpace)
Definition: txtparae.cxx:2389
static constexpr OUStringLiteral gsFootnote
Definition: txtparae.hxx:148
void _exportTextFrame(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo, bool bProgress)
Definition: txtparae.cxx:3285
void exportMeta(const css::uno::Reference< css::beans::XPropertySet > &i_xPortion, bool i_bAutoStyles, bool i_isProgress, bool &rPrevCharIsSpace)
export a text:meta
Definition: txtparae.cxx:4052
void exportListAndSectionChange(css::uno::Reference< css::text::XTextSection > &rOldSection, const css::uno::Reference< css::text::XTextSection > &rNewSection, const XMLTextNumRuleInfo &rOldList, const XMLTextNumRuleInfo &rNewList, bool bAutoStyles)
check if current section or current list has changed; calls exportListChange as appropriate
void exportTextRange(const css::uno::Reference< css::text::XTextRange > &rTextRange, bool bAutoStyles, bool &rPrevCharWasSpace, FieldmarkType &openFieldmarkType)
Definition: txtparae.cxx:3727
void exportTextContentEnumeration(const css::uno::Reference< css::container::XEnumeration > &rContentEnum, bool bAutoStyles, const css::uno::Reference< css::text::XTextSection > &rBaseSection, bool bProgress, bool bExportParagraph=true, const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet=nullptr, TextPNS eExtensionNS=TextPNS::ODF)
Definition: txtparae.cxx:1912
void exportTextLineBreak(const css::uno::Reference< css::beans::XPropertySet > &xPropSet)
Definition: txtparae.cxx:2750
void exportTextEmbedded(const css::uno::Reference< css::text::XTextContent > &rTextContent, bool bAutoStyles, const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet=nullptr)
Definition: txtparae.hxx:574
OUString FindTextStyle(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, bool &rbHasCharStyle, bool &rbHasAutoStyle, const XMLPropertyState **pAddState=nullptr) const
Definition: txtparae.cxx:915
bool IsBlockMode() const
Definition: txtparae.hxx:512
std::unique_ptr< XMLTextFieldExport > m_pFieldExport
Definition: txtparae.hxx:94
static SvXMLExportPropertyMapper * CreateShapeExtPropMapper(SvXMLExport &rExport)
Definition: txtparae.cxx:1526
rtl::Reference< SvXMLExportPropertyMapper > m_xSectionPropMapper
Definition: txtparae.hxx:90
void exportRuby(const css::uno::Reference< css::beans::XPropertySet > &rPortionPropSet, bool bAutoStyles)
export a ruby
Definition: txtparae.cxx:3972
void exportTextFootnote(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const OUString &sString, bool bAutoStyles, bool bProgress)
export a footnote and styles
Definition: txtftne.cxx:64
XMLTextListAutoStylePool maListAutoPool
Definition: txtparae.hxx:96
static SvXMLExportPropertyMapper * CreateParaDefaultExtPropMapper(SvXMLExport &rExport)
Definition: txtparae.cxx:1550
void exportPageFrames(bool bProgress)
Definition: txtparae.cxx:1558
const XMLTextListAutoStylePool & GetListAutoStylePool() const
Definition: txtparae.hxx:551
static constexpr OUStringLiteral gsFrameStyleName
Definition: txtparae.hxx:163
static constexpr OUStringLiteral gsTextSection
Definition: txtparae.hxx:160
o3tl::sorted_vector< css::uno::Reference< css::text::XTextFrame > > maFrameRecurseGuard
Definition: txtparae.hxx:118
void ExportContentControl(const css::uno::Reference< css::beans::XPropertySet > &xPortion, bool bAutoStyles, bool isProgress, bool &rPrevCharIsSpace)
Exports a <loext:content-control> element.
Definition: txtparae.cxx:4088
rtl::Reference< SvXMLExportPropertyMapper > m_xAutoFramePropMapper
Definition: txtparae.hxx:89
void exportCharacterData(const OUString &rText, bool &rPrevCharWasSpace)
Definition: txtparae.cxx:3750
void recordTrackedChangesNoXText()
Stop recording tracked changes.
Definition: txtparae.cxx:3945
o3tl::sorted_vector< css::uno::Reference< css::drawing::XShape > > maShapeRecurseGuard
Definition: txtparae.hxx:119
std::unique_ptr< Impl > m_xImpl
Definition: txtparae.hxx:81
SinglePropertySetInfoCache m_aCharStyleNamesPropInfoCache
Definition: txtparae.hxx:164
void Add(XmlStyleFamily nFamily, MultiPropertySetHelper &rPropSetHelper, const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
add autostyle for specified family
bool ExportListId() const
Definition: txtparae.cxx:1893
XMLShapeExportFlags addTextFrameAttributes(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, bool bShape, basegfx::B2DPoint *pCenter=nullptr, OUString *pMinHeightValue=nullptr, OUString *pMinWidthValue=nullptr)
Definition: txtparae.cxx:2874
void exportTextMark(const css::uno::Reference< css::beans::XPropertySet > &xPropSet, const OUString &rProperty, const enum ::xmloff::token::XMLTokenEnum pElements[], bool bAutoStyles)
Definition: txtparae.cxx:2784
static SvXMLExportPropertyMapper * CreateCharExtPropMapper(SvXMLExport &rExport)
Definition: txtparae.cxx:1534
void exportListChange(const XMLTextNumRuleInfo &rPrvInfo, const XMLTextNumRuleInfo &rNextInfo)
Definition: txtparae.cxx:993
OUString Find(XmlStyleFamily nFamily, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const OUString &rParent, const o3tl::span< const XMLPropertyState > aAddStates={}) const
find style name for specified family and parent
Definition: txtparae.cxx:880
void exportUsedDeclarations()
export all declarations
Definition: txtparae.cxx:3919
void exportTextRangeSpan(const css::uno::Reference< css::text::XTextRange > &rTextRange, css::uno::Reference< css::beans::XPropertySet > const &xPropSet, css::uno::Reference< css::beans::XPropertySetInfo > &xPropSetInfo, const bool bIsUICharStyle, const bool bHasAutoStyle, const OUString &sStyle, bool &rPrevCharIsSpace, FieldmarkType &openFieldMark)
Definition: txtparae.cxx:3695
void exportEvents(const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
Definition: txtparae.cxx:3652
void _exportTextGraphic(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo)
Definition: txtparae.cxx:3452
void exportTrackedChanges(bool bAutoStyle)
Export the list of change information (enclosed by <tracked-changes>) (or the necessary automatic sty...
Definition: txtparae.cxx:3924
XMLTextParagraphExport(SvXMLExport &rExp, SvXMLAutoStylePoolP &rASP)
Definition: txtparae.cxx:1433
SvXMLAutoStylePoolP & m_rAutoStylePool
Definition: txtparae.hxx:85
void exportAnyTextFrame(const css::uno::Reference< css::text::XTextContent > &rTextContent, FrameType eTxpe, bool bAutoStyles, bool bProgress, bool bExportContent, const css::uno::Reference< css::beans::XPropertySet > *pRangePropSet)
Definition: txtparae.cxx:3155
void exportParagraph(const css::uno::Reference< css::text::XTextContent > &rTextContent, bool bAutoStyles, bool bProgress, bool bExportParagraph, MultiPropertySetHelper &rPropSetHelper, TextPNS eExtensionNS)
Definition: txtparae.cxx:2074
rtl::Reference< SvXMLExportPropertyMapper > m_xTextPropMapper
Definition: txtparae.hxx:87
void exportText(const css::uno::Reference< css::text::XText > &rText, bool bAutoStyles, bool bProgress, bool bExportParagraph, TextPNS eExtensionNS=TextPNS::ODF)
static SvXMLExportPropertyMapper * CreateParaExtPropMapper(SvXMLExport &rExport)
Definition: txtparae.cxx:1542
B2DPolygon const & getB2DPolygon(sal_uInt32 nIndex) const
B2DRange getB2DRange() const
sal_uInt32 count() const
TYPE getWidth() const
TYPE getHeight() const
TYPE getX() const
void setY(TYPE fY)
TYPE getY() const
void setX(TYPE fX)
const OUString & getIdentifier(const css::uno::Reference< css::uno::XInterface > &rInterface) const
css::uno::Type const & get()
size_type erase(const Value &x)
std::pair< const_iterator, bool > insert(Value &&x)
constexpr iterator begin() const noexcept
constexpr iterator end() const noexcept
static bool convertMeasurePx(sal_Int32 &rValue, std::u16string_view rString)
static bool convertPercent(sal_Int32 &rValue, std::u16string_view rString)
static bool convertBool(bool &rBool, std::u16string_view rString)
std::unique_ptr< BoundFrames > m_pEmbeddeds
Definition: txtparae.cxx:445
const BoundFrames * GetShapes() const
Definition: txtparae.cxx:440
const BoundFrames * GetGraphics() const
Definition: txtparae.cxx:436
std::unique_ptr< BoundFrames > m_pShapes
Definition: txtparae.cxx:446
const BoundFrames * GetEmbeddeds() const
Definition: txtparae.cxx:438
BoundFrameSets(const Reference< XInterface > &rModel)
Definition: txtparae.cxx:555
std::unique_ptr< BoundFrames > m_pGraphics
Definition: txtparae.cxx:444
const BoundFrames * GetTexts() const
Definition: txtparae.cxx:434
std::unique_ptr< BoundFrames > m_pTexts
Definition: txtparae.cxx:441
int nCount
float u
XmlStyleFamily
Definition: families.hxx:50
constexpr OUStringLiteral XML_STYLE_FAMILY_SD_GRAPHICS_NAME
Definition: families.hxx:38
DocumentType eType
sal_Int16 nValue
OUString sName
const char * name
sal_Int32 nIndex
uno_Any a
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_N_ELEMENTS(arr)
OUString exportToSvgD(const B2DPolyPolygon &rPolyPoly, bool bUseRelativeCoordinates, bool bDetectQuadraticBeziers, bool bHandleRelativeNextPointCompatible, bool bOOXMLMotionPath=false)
OUString exportToSvgPoints(const B2DPolygon &rPoly)
B2DPolyPolygon UnoPointSequenceSequenceToB2DPolyPolygon(const css::drawing::PointSequenceSequence &rPointSequenceSequenceSource)
double normalizeToRange(double v, const double fRange)
B2IRange fround(const B2DRange &rRange)
Fill
@ Exception
Type
int i
index
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:50
@ XML_CONTINUE_NUMBERING
Definition: xmltoken.hxx:513
@ XML_MAY_BREAK_BETWEEN_PAGES
Definition: xmltoken.hxx:3524
@ XML_SHOWING_PLACE_HOLDER
Definition: xmltoken.hxx:3511
@ XML_ALPHABETICAL_INDEX_AUTO_MARK_FILE
Definition: xmltoken.hxx:237
@ XML_OUTLINE_CONTENT_VISIBLE
Definition: xmltoken.hxx:1456
@ XML_FIELDMARK_SEPARATOR
Definition: xmltoken.hxx:3325
@ XML_REFERENCE_MARK_START
Definition: xmltoken.hxx:1604
@ XML_DATE_RFC_LANGUAGE_TAG
Definition: xmltoken.hxx:3517
@ XML_VISITED_STYLE_NAME
Definition: xmltoken.hxx:2139
@ XML_ANCHOR_PAGE_NUMBER
Definition: xmltoken.hxx:247
@ XML_REFERENCE_MARK_END
Definition: xmltoken.hxx:1603
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3541
bool operator==(const AttributeDescription &i_lhs, const AttributeDescription &i_rhs)
HashMap_OWString_Interface aMap
constexpr OUStringLiteral ODF_FORMTEXT
Definition: odffields.hxx:25
constexpr OUStringLiteral ODF_FORMCHECKBOX
Definition: odffields.hxx:28
constexpr OUStringLiteral ODF_OLE_PARAM
Definition: odffields.hxx:54
sal_Int16 nId
static void ExportParameter(OUStringBuffer &rStrBuffer, const css::drawing::EnhancedCustomShapeParameter &rParameter)
#define SEF_DEFAULT
Definition: shapeexport.hxx:68
XMLShapeExportFlags
Definition: shapeexport.hxx:49
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:140
sal_Int32 mnIndex
Definition: maptype.hxx:141
bool ShouldSkipListId(const Reference< XTextContent > &xTextContent) const
Definition: txtparae.cxx:1371
DocumentListNodes(const css::uno::Reference< css::frame::XModel > &xModel)
Definition: txtparae.cxx:1342
std::vector< NodeData > docListNodes
Definition: txtparae.cxx:1341
sal_Int32 GetFieldMarkIndex(Reference< XFormField > const &i_xFieldMark)
Definition: txtparae.cxx:1322
sal_Int32 AddFieldMarkStart(Reference< XFormField > const &i_xFieldMark)
Definition: txtparae.cxx:1315
::std::map< Reference< XFormField >, sal_Int32 > FieldMarkMap_t
Definition: txtparae.cxx:1311
FieldMarkMap_t m_FieldMarkMap
Definition: txtparae.cxx:1312
Reference< XModel > xModel
constexpr OUStringLiteral gsTextFieldStartEnd(u"TextFieldStartEnd")
constexpr OUStringLiteral gsParagraphService(u"com.sun.star.text.Paragraph")
constexpr OUStringLiteral gsChainNextName(u"ChainNextName")
constexpr OUStringLiteral gsRelativeWidth(u"RelativeWidth")
constexpr OUStringLiteral gsVisitedCharStyleName(u"VisitedCharStyleName")
constexpr OUStringLiteral gsAnchorType(u"AnchorType")
constexpr OUStringLiteral gsVertOrientPosition(u"VertOrientPosition")
constexpr OUStringLiteral gsSizeType(u"SizeType")
static const char * aParagraphPropertyNamesAuto[]
Definition: txtparae.cxx:475
constexpr OUStringLiteral gsReferenceMark(u"ReferenceMark")
constexpr OUStringLiteral gsContourPolyPolygon(u"ContourPolyPolygon")
constexpr OUStringLiteral gsTextContentService(u"com.sun.star.text.TextContent")
enum XMLTokenEnum lcl_XmlBookmarkElements[]
Definition: txtparae.cxx:1618
constexpr OUStringLiteral gsTableService(u"com.sun.star.text.TextTable")
constexpr OUStringLiteral gsBookmark(u"Bookmark")
constexpr OUStringLiteral gsTextFieldSep(u"TextFieldSeparator")
constexpr OUStringLiteral gsHoriOrientPosition(u"HoriOrientPosition")
constexpr OUStringLiteral gsFrame(u"Frame")
constexpr OUStringLiteral gsHyperLinkURL(u"HyperLinkURL")
constexpr OUStringLiteral gsDescription(u"Description")
constexpr OUStringLiteral gsHoriOrient(u"HoriOrient")
constexpr OUStringLiteral gsNumberingRules(u"NumberingRules")
constexpr OUStringLiteral gsServerMap(u"ServerMap")
static bool lcl_txtpara_isBoundAsChar(const Reference< XPropertySet > &rPropSet, const Reference< XPropertySetInfo > &rPropSetInfo)
Definition: txtparae.cxx:2858
constexpr OUStringLiteral gsParaConditionalStyleName(u"ParaConditionalStyleName")
static const char * aParagraphPropertyNames[]
Definition: txtparae.cxx:494
constexpr OUStringLiteral gsDocumentIndexMark(u"DocumentIndexMark")
constexpr OUStringLiteral gsText(u"Text")
constexpr OUStringLiteral gsHyperLinkName(u"HyperLinkName")
constexpr OUStringLiteral gsRubyCharStyleName(u"RubyCharStyleName")
constexpr OUStringLiteral gsIsPixelContour(u"IsPixelContour")
constexpr OUStringLiteral gsWidthType(u"WidthType")
constexpr OUStringLiteral gsHeight(u"Height")
constexpr OUStringLiteral gsTextFieldStart(u"TextFieldStart")
constexpr OUStringLiteral gsTextField(u"TextField")
constexpr OUStringLiteral gsRuby(u"Ruby")
constexpr OUStringLiteral gsIsStart(u"IsStart")
constexpr OUStringLiteral gsGraphicRotation(u"GraphicRotation")
constexpr OUStringLiteral gsTextFieldEnd(u"TextFieldEnd")
constexpr OUStringLiteral gsIsSyncHeightToWidth(u"IsSyncHeightToWidth")
constexpr OUStringLiteral gsUnvisitedCharStyleName(u"UnvisitedCharStyleName")
static bool lcl_validPropState(const XMLPropertyState &rState)
Definition: txtparae.cxx:791
constexpr OUStringLiteral gsTextFrameService(u"com.sun.star.text.TextFrame")
constexpr OUStringLiteral gsTitle(u"Title")
constexpr OUStringLiteral gsTextGraphicService(u"com.sun.star.text.TextGraphicObject")
constexpr OUStringLiteral gsTextEmbeddedService(u"com.sun.star.text.TextEmbeddedObject")
constexpr OUStringLiteral gsIsAutomaticContour(u"IsAutomaticContour")
constexpr OUStringLiteral gsWidth(u"Width")
constexpr OUStringLiteral gsShapeService(u"com.sun.star.drawing.Shape")
constexpr OUStringLiteral gsTextFieldService(u"com.sun.star.text.TextField")
constexpr OUStringLiteral gsVertOrient(u"VertOrient")
static bool txtparae_bContainsIllegalCharacters
Definition: txtparae.cxx:451
constexpr OUStringLiteral gsHyperLinkTarget(u"HyperLinkTarget")
constexpr OUStringLiteral gsIsSyncWidthToHeight(u"IsSyncWidthToHeight")
constexpr OUStringLiteral gsRedline(u"Redline")
constexpr OUStringLiteral gsIsCollapsed(u"IsCollapsed")
constexpr OUStringLiteral gsGraphicFilter(u"GraphicFilter")
constexpr OUStringLiteral gsTextPortionType(u"TextPortionType")
constexpr OUStringLiteral gsRelativeHeight(u"RelativeHeight")
constexpr OUStringLiteral gsSoftPageBreak(u"SoftPageBreak")
constexpr OUStringLiteral gsAnchorPageNo(u"AnchorPageNo")
enum XMLTokenEnum lcl_XmlReferenceElements[]
Definition: txtparae.cxx:1616
constexpr OUStringLiteral gsRubyText(u"RubyText")
TextPNS
Definition: txtparae.hxx:74
#define CTF_HYPERLINK_URL
Definition: txtprmap.hxx:140
@ TEXT_ADDITIONAL_DEFAULTS
#define CTF_CHAR_STYLE_NAME
Definition: txtprmap.hxx:141
sal_uInt16 sal_Unicode
signed char sal_Int8
std::unique_ptr< char[]> aBuffer
bool operator!=(const XclExpString &rLeft, const XclExpString &rRight)
constexpr sal_uInt16 XML_NAMESPACE_DRAW
constexpr sal_uInt16 XML_NAMESPACE_FIELD
constexpr sal_uInt16 XML_NAMESPACE_XLINK
constexpr sal_uInt16 XML_NAMESPACE_SVG
constexpr sal_uInt16 XML_NAMESPACE_TEXT
constexpr sal_uInt16 XML_NAMESPACE_XML
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
constexpr sal_uInt16 XML_NAMESPACE_STYLE
constexpr sal_uInt16 XML_NAMESPACE_FO