1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sal/config.h>
22 #include <sal/log.hxx>
27 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
28 #include <osl/mutex.hxx>
29 #include <tools/urlobj.hxx>
30 #include <vcl/graph.hxx>
31 #include <comphelper/genericpropertyset.hxx>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/io/XInputStream.hpp>
34 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
35 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
36 #include <com/sun/star/text/XTextContent.hpp>
37 #include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp>
38 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
39 #include <com/sun/star/uri/UriReferenceFactory.hpp>
40 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
41 #include <com/sun/star/util/MeasureUnit.hpp>
42 #include <i18nlangtag/languagetag.hxx>
43 #include <comphelper/processfactory.hxx>
44 #include <comphelper/propertysetinfo.hxx>
45 #include <xmloff/attrlist.hxx>
46 #include <xmloff/namespacemap.hxx>
47 #include <xmloff/xmluconv.hxx>
48 #include <xmloff/xmlnamespace.hxx>
49 #include <xmloff/xmltoken.hxx>
50 #include <xmloff/xmlexp.hxx>
51 #include <xmloff/xmlnumfe.hxx>
52 #include <xmloff/xmlmetae.hxx>
53 #include <xmloff/XMLSettingsExportContext.hxx>
54 #include <xmloff/XMLEventExport.hxx>
55 #include <xmloff/ProgressBarHelper.hxx>
56 #include <XMLStarBasicExportHandler.hxx>
57 #include <XMLScriptExportHandler.hxx>
58 #include <xmloff/SettingsExportHelper.hxx>
59 #include <com/sun/star/document/XEventsSupplier.hpp>
60 #include <com/sun/star/document/XViewDataSupplier.hpp>
61 #include <com/sun/star/frame/XModel.hpp>
62 #include <com/sun/star/frame/XModule.hpp>
63 #include <xmloff/GradientStyle.hxx>
64 #include <xmloff/HatchStyle.hxx>
65 #include <xmloff/ImageStyle.hxx>
66 #include <TransGradientStyle.hxx>
67 #include <xmloff/MarkerStyle.hxx>
68 #include <xmloff/DashStyle.hxx>
69 #include <xmloff/XMLFontAutoStylePool.hxx>
70 #include <XMLImageMapExport.hxx>
71 #include <XMLBase64Export.hxx>
72 #include <xmloff/xmlerror.hxx>
73 #include <com/sun/star/style/XStyle.hpp>
74 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
75 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
76 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
77 #include <com/sun/star/beans/PropertyAttribute.hpp>
78 #include <xmloff/XMLFilterServiceNames.h>
79 #include <XMLEmbeddedObjectExportFilter.hxx>
80 #include <XMLBasicExportFilter.hxx>
81 #include <cppuhelper/exc_hlp.hxx>
82 #include <cppuhelper/implbase.hxx>
83 #include <cppuhelper/supportsservice.hxx>
84 #include <comphelper/extract.hxx>
85 #include <comphelper/SetFlagContextHelper.hxx>
86 #include <PropertySetMerger.hxx>
88 #include <unotools/docinfohelper.hxx>
89 #include <com/sun/star/document/XDocumentProperties.hpp>
90 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
91 #include <com/sun/star/document/XMLOasisBasicExporter.hpp>
92 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
93 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
94 #include <com/sun/star/rdf/XMetadatable.hpp>
95 #include <RDFaExportHelper.hxx>
97 #include <comphelper/xmltools.hxx>
98 #include <comphelper/graphicmimetype.hxx>
100 using namespace ::osl
;
101 using namespace ::com::sun::star
;
102 using namespace ::com::sun::star::uno
;
103 using namespace ::com::sun::star::frame
;
104 using namespace ::com::sun::star::container
;
105 using namespace ::com::sun::star::lang
;
106 using namespace ::com::sun::star::document
;
107 using namespace ::com::sun::star::beans
;
108 using namespace ::com::sun::star::xml::sax
;
109 using namespace ::com::sun::star::io
;
110 using namespace ::xmloff::token
;
112 #define XML_MODEL_SERVICE_WRITER "com.sun.star.text.TextDocument"
113 #define XML_MODEL_SERVICE_CALC "com.sun.star.sheet.SpreadsheetDocument"
114 #define XML_MODEL_SERVICE_DRAW "com.sun.star.drawing.DrawingDocument"
115 #define XML_MODEL_SERVICE_IMPRESS "com.sun.star.presentation.PresentationDocument"
116 #define XML_MODEL_SERVICE_MATH "com.sun.star.formula.FormulaProperties"
117 #define XML_MODEL_SERVICE_CHART "com.sun.star.chart.ChartDocument"
119 #define XML_USEPRETTYPRINTING "UsePrettyPrinting"
121 #define XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE "vnd.sun.star.GraphicObject:"
122 #define XML_EMBEDDEDOBJECT_URL_BASE "vnd.sun.star.EmbeddedObject:"
126 struct XMLServiceMapEntry_Impl
128 const char *sModelService
;
129 sal_Int32 nModelServiceLen
;
130 const char *sFilterService
;
131 sal_Int32 nFilterServiceLen
;
136 #define SERVICE_MAP_ENTRY( app ) \
137 { XML_MODEL_SERVICE_##app, sizeof(XML_MODEL_SERVICE_##app)-1, \
138 XML_EXPORT_FILTER_##app, sizeof(XML_EXPORT_FILTER_##app)-1 }
140 const XMLServiceMapEntry_Impl aServiceMap
[] =
142 SERVICE_MAP_ENTRY( WRITER
),
143 SERVICE_MAP_ENTRY( CALC
),
144 SERVICE_MAP_ENTRY( IMPRESS
),// Impress supports DrawingDocument, too, so
145 SERVICE_MAP_ENTRY( DRAW
), // it must appear before Draw
146 SERVICE_MAP_ENTRY( MATH
),
147 SERVICE_MAP_ENTRY( CHART
),
148 { nullptr, 0, nullptr, 0 }
153 class SettingsExportFacade
: public ::xmloff::XMLSettingsExportContext
156 explicit SettingsExportFacade( SvXMLExport
& i_rExport
)
157 :m_rExport( i_rExport
)
161 virtual ~SettingsExportFacade()
165 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName
,
166 const OUString
& i_rValue
) override
;
167 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName
,
168 enum ::xmloff::token::XMLTokenEnum i_eValue
) override
;
170 virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName
) override
;
171 virtual void EndElement( const bool i_bIgnoreWhitespace
) override
;
173 virtual void Characters( const OUString
& i_rCharacters
) override
;
175 virtual css::uno::Reference
< css::uno::XComponentContext
>
176 GetComponentContext() const override
;
178 SvXMLExport
& m_rExport
;
179 ::std::stack
< OUString
> m_aElements
;
184 void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName
, const OUString
& i_rValue
)
186 m_rExport
.AddAttribute( XML_NAMESPACE_CONFIG
, i_eName
, i_rValue
);
189 void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName
, enum ::xmloff::token::XMLTokenEnum i_eValue
)
191 m_rExport
.AddAttribute( XML_NAMESPACE_CONFIG
, i_eName
, i_eValue
);
194 void SettingsExportFacade::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName
)
196 const OUString
sElementName( m_rExport
.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_CONFIG
, GetXMLToken( i_eName
) ) );
197 m_rExport
.StartElement( sElementName
, true/*i_bIgnoreWhitespace*/ );
198 m_aElements
.push( sElementName
);
201 void SettingsExportFacade::EndElement( const bool i_bIgnoreWhitespace
)
203 const OUString
sElementName( m_aElements
.top() );
204 m_rExport
.EndElement( sElementName
, i_bIgnoreWhitespace
);
208 void SettingsExportFacade::Characters( const OUString
& i_rCharacters
)
210 m_rExport
.GetDocHandler()->characters( i_rCharacters
);
213 Reference
< XComponentContext
> SettingsExportFacade::GetComponentContext() const
215 return m_rExport
.getComponentContext();
220 class SvXMLExportEventListener
: public cppu::WeakImplHelper
<
221 css::lang::XEventListener
>
224 SvXMLExport
* pExport
;
227 explicit SvXMLExportEventListener(SvXMLExport
* pExport
);
230 virtual void SAL_CALL
disposing(const lang::EventObject
& rEventObject
) override
;
235 SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport
* pTempExport
)
236 : pExport(pTempExport
)
241 void SAL_CALL
SvXMLExportEventListener::disposing( const lang::EventObject
& )
245 pExport
->DisposingModel();
250 class SvXMLExport_Impl
255 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper
;
256 uno::Reference
< uri::XUriReferenceFactory
> mxUriReferenceFactory
;
257 OUString msPackageURI
;
258 OUString msPackageURIScheme
;
259 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
260 bool mbOutlineStyleAsNormalListStyle
;
262 uno::Reference
< embed::XStorage
> mxTargetStorage
;
264 SvtSaveOptions maSaveOptions
;
265 std::optional
<SvtSaveOptions::ODFSaneDefaultVersion
> m_oOverrideODFVersion
;
267 /// name of stream in package, e.g., "content.xml"
268 OUString mStreamName
;
270 OUString maSrcShellID
;
271 OUString maDestShellID
;
273 /// stack of backed up namespace maps
274 /// long: depth at which namespace map has been backed up into the stack
275 ::std::stack
< ::std::pair
< std::unique_ptr
<SvXMLNamespaceMap
>, tools::Long
> > mNamespaceMaps
;
276 /// counts depth (number of open elements/start tags)
279 ::std::unique_ptr
< ::xmloff::RDFaExportHelper
> mpRDFaHelper
;
281 bool mbExportTextNumberElement
;
282 bool mbNullDateInitialized
;
284 void SetSchemeOf( const OUString
& rOrigFileName
)
286 sal_Int32 nSep
= rOrigFileName
.indexOf(':');
288 msPackageURIScheme
= rOrigFileName
.copy( 0, nSep
);
292 SvXMLExport_Impl::SvXMLExport_Impl()
293 : mxUriReferenceFactory( uri::UriReferenceFactory::create(comphelper::getProcessComponentContext()) ),
294 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
295 mbOutlineStyleAsNormalListStyle( false ),
297 mbExportTextNumberElement( false ),
298 mbNullDateInitialized( false )
302 void SvXMLExport::SetDocHandler( const uno::Reference
< xml::sax::XDocumentHandler
> &rHandler
)
304 mxHandler
= rHandler
;
305 mxExtHandler
.set( mxHandler
, UNO_QUERY
);
308 void SvXMLExport::InitCtor_()
310 // note: it is not necessary to add XML_NP_XML (it is declared implicitly)
311 if( getExportFlags() & ~SvXMLExportFlags::OASIS
)
313 mpNamespaceMap
->Add( GetXMLToken(XML_NP_OFFICE
), GetXMLToken(XML_N_OFFICE
), XML_NAMESPACE_OFFICE
);
314 mpNamespaceMap
->Add( GetXMLToken(XML_NP_OOO
), GetXMLToken(XML_N_OOO
), XML_NAMESPACE_OOO
);
316 if( getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::FONTDECLS
) )
318 mpNamespaceMap
->Add( GetXMLToken(XML_NP_FO
), GetXMLToken(XML_N_FO_COMPAT
), XML_NAMESPACE_FO
);
320 if( getExportFlags() & (SvXMLExportFlags::META
|SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
|SvXMLExportFlags::SETTINGS
) )
322 mpNamespaceMap
->Add( GetXMLToken(XML_NP_XLINK
), GetXMLToken(XML_N_XLINK
), XML_NAMESPACE_XLINK
);
324 if( getExportFlags() & SvXMLExportFlags::SETTINGS
)
326 mpNamespaceMap
->Add( GetXMLToken(XML_NP_CONFIG
), GetXMLToken(XML_N_CONFIG
), XML_NAMESPACE_CONFIG
);
329 if( getExportFlags() & (SvXMLExportFlags::META
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
331 mpNamespaceMap
->Add( GetXMLToken(XML_NP_DC
), GetXMLToken(XML_N_DC
), XML_NAMESPACE_DC
);
332 mpNamespaceMap
->Add( GetXMLToken(XML_NP_META
), GetXMLToken(XML_N_META
), XML_NAMESPACE_META
);
334 if( getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::FONTDECLS
) )
336 mpNamespaceMap
->Add( GetXMLToken(XML_NP_STYLE
), GetXMLToken(XML_N_STYLE
), XML_NAMESPACE_STYLE
);
339 // namespaces for documents
340 if( getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
342 mpNamespaceMap
->Add( GetXMLToken(XML_NP_DC
), GetXMLToken(XML_N_DC
), XML_NAMESPACE_DC
);
343 mpNamespaceMap
->Add( GetXMLToken(XML_NP_TEXT
), GetXMLToken(XML_N_TEXT
), XML_NAMESPACE_TEXT
);
344 mpNamespaceMap
->Add( GetXMLToken(XML_NP_DRAW
), GetXMLToken(XML_N_DRAW
), XML_NAMESPACE_DRAW
);
345 mpNamespaceMap
->Add( GetXMLToken(XML_NP_DR3D
), GetXMLToken(XML_N_DR3D
), XML_NAMESPACE_DR3D
);
346 mpNamespaceMap
->Add( GetXMLToken(XML_NP_SVG
), GetXMLToken(XML_N_SVG_COMPAT
), XML_NAMESPACE_SVG
);
347 mpNamespaceMap
->Add( GetXMLToken(XML_NP_CHART
), GetXMLToken(XML_N_CHART
), XML_NAMESPACE_CHART
);
348 mpNamespaceMap
->Add( GetXMLToken(XML_NP_RPT
), GetXMLToken(XML_N_RPT
), XML_NAMESPACE_REPORT
);
349 mpNamespaceMap
->Add( GetXMLToken(XML_NP_TABLE
), GetXMLToken(XML_N_TABLE
), XML_NAMESPACE_TABLE
);
350 mpNamespaceMap
->Add( GetXMLToken(XML_NP_NUMBER
),GetXMLToken(XML_N_NUMBER
), XML_NAMESPACE_NUMBER
);
351 mpNamespaceMap
->Add( GetXMLToken(XML_NP_OOOW
), GetXMLToken(XML_N_OOOW
), XML_NAMESPACE_OOOW
);
352 mpNamespaceMap
->Add( GetXMLToken(XML_NP_OOOC
), GetXMLToken(XML_N_OOOC
), XML_NAMESPACE_OOOC
);
353 mpNamespaceMap
->Add( GetXMLToken(XML_NP_OF
), GetXMLToken(XML_N_OF
), XML_NAMESPACE_OF
);
355 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED
)
358 GetXMLToken(XML_NP_TABLE_EXT
), GetXMLToken(XML_N_TABLE_EXT
), XML_NAMESPACE_TABLE_EXT
);
360 GetXMLToken(XML_NP_CALC_EXT
), GetXMLToken(XML_N_CALC_EXT
), XML_NAMESPACE_CALC_EXT
);
362 GetXMLToken(XML_NP_DRAW_EXT
), GetXMLToken(XML_N_DRAW_EXT
), XML_NAMESPACE_DRAW_EXT
);
364 GetXMLToken(XML_NP_LO_EXT
), GetXMLToken(XML_N_LO_EXT
),
365 XML_NAMESPACE_LO_EXT
);
366 mpNamespaceMap
->Add( GetXMLToken(XML_NP_FIELD
), GetXMLToken(XML_N_FIELD
), XML_NAMESPACE_FIELD
);
369 if( getExportFlags() & (SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
371 mpNamespaceMap
->Add( GetXMLToken(XML_NP_MATH
), GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
372 mpNamespaceMap
->Add( GetXMLToken(XML_NP_FORM
), GetXMLToken(XML_N_FORM
), XML_NAMESPACE_FORM
);
374 if( getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SCRIPTS
) )
376 mpNamespaceMap
->Add( GetXMLToken(XML_NP_SCRIPT
), GetXMLToken(XML_N_SCRIPT
), XML_NAMESPACE_SCRIPT
);
377 mpNamespaceMap
->Add( GetXMLToken(XML_NP_DOM
), GetXMLToken(XML_N_DOM
), XML_NAMESPACE_DOM
);
379 if( getExportFlags() & SvXMLExportFlags::CONTENT
)
381 mpNamespaceMap
->Add( GetXMLToken(XML_NP_XFORMS_1_0
), GetXMLToken(XML_N_XFORMS_1_0
), XML_NAMESPACE_XFORMS
);
382 mpNamespaceMap
->Add( GetXMLToken(XML_NP_XSD
), GetXMLToken(XML_N_XSD
), XML_NAMESPACE_XSD
);
383 mpNamespaceMap
->Add( GetXMLToken(XML_NP_XSI
), GetXMLToken(XML_N_XSI
), XML_NAMESPACE_XSI
);
384 mpNamespaceMap
->Add( GetXMLToken(XML_NP_FORMX
), GetXMLToken(XML_N_FORMX
), XML_NAMESPACE_FORMX
);
387 // RDFa: needed for content and header/footer styles
388 if( getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
390 mpNamespaceMap
->Add( GetXMLToken(XML_NP_XHTML
),
391 GetXMLToken(XML_N_XHTML
), XML_NAMESPACE_XHTML
);
393 // GRDDL: to convert RDFa and meta.xml to RDF
394 if( getExportFlags() & (SvXMLExportFlags::META
|SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
|SvXMLExportFlags::CONTENT
) )
396 mpNamespaceMap
->Add( GetXMLToken(XML_NP_GRDDL
),
397 GetXMLToken(XML_N_GRDDL
), XML_NAMESPACE_GRDDL
);
399 // CSS Text Level 3 for distributed text justification.
400 if ( getExportFlags() & (SvXMLExportFlags::STYLES
|SvXMLExportFlags::AUTOSTYLES
|SvXMLExportFlags::MASTERSTYLES
) )
403 GetXMLToken(XML_NP_CSS3TEXT
), GetXMLToken(XML_N_CSS3TEXT
), XML_NAMESPACE_CSS3TEXT
);
406 if (mxModel
.is() && !mxEventListener
.is())
408 mxEventListener
.set( new SvXMLExportEventListener(this));
409 mxModel
->addEventListener(mxEventListener
);
412 // Determine model type (#i51726#)
413 DetermineModelType_();
416 // Shapes in Writer cannot be named via context menu (#i51726#)
417 void SvXMLExport::DetermineModelType_()
419 meModelType
= SvtModuleOptions::EFactory::UNKNOWN_FACTORY
;
423 meModelType
= SvtModuleOptions::ClassifyFactoryByModel( mxModel
);
425 // note: MATH documents will throw NotInitializedException; maybe unit test problem
426 if (meModelType
== SvtModuleOptions::EFactory::WRITER
)
428 uno::Reference
<frame::XModule
> const xModule(mxModel
, uno::UNO_QUERY
);
429 bool const isBaseForm(xModule
.is() &&
430 xModule
->getIdentifier() == "com.sun.star.sdb.FormDesign");
433 switch (mpImpl
->maSaveOptions
.GetODFSaneDefaultVersion())
435 case SvtSaveOptions::ODFSVER_013_EXTENDED
:
436 SAL_INFO("xmloff.core", "tdf#138209 force form export to ODF 1.2");
437 mpImpl
->m_oOverrideODFVersion
= SvtSaveOptions::ODFSVER_012_EXTENDED
;
438 maUnitConv
.overrideSaneDefaultVersion(SvtSaveOptions::ODFSVER_012_EXTENDED
);
440 case SvtSaveOptions::ODFSVER_013
:
441 SAL_INFO("xmloff.core", "tdf#138209 force form export to ODF 1.2");
442 mpImpl
->m_oOverrideODFVersion
= SvtSaveOptions::ODFSVER_012
;
443 maUnitConv
.overrideSaneDefaultVersion(SvtSaveOptions::ODFSVER_012
);
453 SvXMLExport::SvXMLExport(
454 const uno::Reference
< uno::XComponentContext
>& xContext
,
455 OUString
const & implementationName
,
456 sal_Int16
const eDefaultMeasureUnit
/*css::util::MeasureUnit*/,
457 const enum XMLTokenEnum eClass
, SvXMLExportFlags nExportFlags
)
458 : mpImpl( new SvXMLExport_Impl
),
459 m_xContext(xContext
), m_implementationName(implementationName
),
460 mxAttrList( new SvXMLAttributeList
),
461 mpNamespaceMap( new SvXMLNamespaceMap
),
462 maUnitConv(xContext
, util::MeasureUnit::MM_100TH
, eDefaultMeasureUnit
, getSaneDefaultVersion()),
464 mnExportFlags( nExportFlags
),
465 mnErrorFlags( SvXMLErrorFlags::NO
),
466 msWS( GetXMLToken(XML_WS
) ),
467 mbSaveLinkedSections(true),
468 mbAutoStylesCollected(false)
470 SAL_WARN_IF( !xContext
.is(), "xmloff.core", "got no service manager" );
474 SvXMLExport::SvXMLExport(
475 const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
476 OUString
const & implementationName
,
477 const OUString
&rFileName
,
478 sal_Int16
const eDefaultMeasureUnit
/*css::util::MeasureUnit*/,
479 const uno::Reference
< xml::sax::XDocumentHandler
> & rHandler
)
480 : mpImpl( new SvXMLExport_Impl
),
481 m_xContext(xContext
), m_implementationName(implementationName
),
482 mxHandler( rHandler
),
483 mxExtHandler( rHandler
, uno::UNO_QUERY
),
484 mxAttrList( new SvXMLAttributeList
),
485 msOrigFileName( rFileName
),
486 mpNamespaceMap( new SvXMLNamespaceMap
),
487 maUnitConv(xContext
, util::MeasureUnit::MM_100TH
, eDefaultMeasureUnit
, getSaneDefaultVersion()),
488 meClass( XML_TOKEN_INVALID
),
489 mnExportFlags( SvXMLExportFlags::NONE
),
490 mnErrorFlags( SvXMLErrorFlags::NO
),
491 msWS( GetXMLToken(XML_WS
) ),
492 mbSaveLinkedSections(true),
493 mbAutoStylesCollected(false)
495 SAL_WARN_IF( !xContext
.is(), "xmloff.core", "got no service manager" );
496 mpImpl
->SetSchemeOf( msOrigFileName
);
499 if (mxNumberFormatsSupplier
.is())
500 mpNumExport
.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier
) );
503 SvXMLExport::SvXMLExport(
504 const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
505 OUString
const & implementationName
,
506 const OUString
&rFileName
,
507 const uno::Reference
< xml::sax::XDocumentHandler
> & rHandler
,
508 const Reference
< XModel
>& rModel
,
509 FieldUnit
const eDefaultFieldUnit
,
510 SvXMLExportFlags nExportFlag
)
511 : mpImpl( new SvXMLExport_Impl
),
512 m_xContext(xContext
), m_implementationName(implementationName
),
514 mxHandler( rHandler
),
515 mxExtHandler( rHandler
, uno::UNO_QUERY
),
516 mxNumberFormatsSupplier (rModel
, uno::UNO_QUERY
),
517 mxAttrList( new SvXMLAttributeList
),
518 msOrigFileName( rFileName
),
519 mpNamespaceMap( new SvXMLNamespaceMap
),
520 maUnitConv( xContext
,
521 util::MeasureUnit::MM_100TH
,
522 SvXMLUnitConverter::GetMeasureUnit(eDefaultFieldUnit
),
523 getSaneDefaultVersion()),
524 meClass( XML_TOKEN_INVALID
),
525 mnExportFlags( nExportFlag
),
526 mnErrorFlags( SvXMLErrorFlags::NO
),
527 msWS( GetXMLToken(XML_WS
) ),
528 mbSaveLinkedSections(true),
529 mbAutoStylesCollected(false)
531 SAL_WARN_IF(!xContext
.is(), "xmloff.core", "got no service manager" );
532 mpImpl
->SetSchemeOf( msOrigFileName
);
535 if (mxNumberFormatsSupplier
.is())
536 mpNumExport
.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier
) );
539 SvXMLExport::~SvXMLExport()
542 mpImageMapExport
.reset();
543 mpEventExport
.reset();
544 mpNamespaceMap
.reset();
545 if (mpProgressBarHelper
|| mpNumExport
)
547 if (mxExportInfo
.is())
549 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxExportInfo
->getPropertySetInfo();
550 if (xPropertySetInfo
.is())
552 if (mpProgressBarHelper
)
554 OUString
sProgressMax(XML_PROGRESSMAX
);
555 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
556 OUString
sRepeat(XML_PROGRESSREPEAT
);
557 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
558 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
))
560 sal_Int32
nProgressMax(mpProgressBarHelper
->GetReference());
561 sal_Int32
nProgressCurrent(mpProgressBarHelper
->GetValue());
562 mxExportInfo
->setPropertyValue(sProgressMax
, uno::Any(nProgressMax
));
563 mxExportInfo
->setPropertyValue(sProgressCurrent
, uno::Any(nProgressCurrent
));
565 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
566 mxExportInfo
->setPropertyValue(sRepeat
, css::uno::makeAny(mpProgressBarHelper
->GetRepeat()));
568 if (mpNumExport
&& (mnExportFlags
& (SvXMLExportFlags::AUTOSTYLES
| SvXMLExportFlags::STYLES
)))
570 OUString
sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES
);
571 if (xPropertySetInfo
->hasPropertyByName(sWrittenNumberFormats
))
573 mxExportInfo
->setPropertyValue(sWrittenNumberFormats
, Any(mpNumExport
->GetWasUsed()));
578 mpProgressBarHelper
.reset();
582 if (mxEventListener
.is() && mxModel
.is())
583 mxModel
->removeEventListener(mxEventListener
);
587 void SAL_CALL
SvXMLExport::setSourceDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
589 mxModel
.set( xDoc
, UNO_QUERY
);
591 throw lang::IllegalArgumentException();
592 if (mxModel
.is() && ! mxEventListener
.is())
594 mxEventListener
.set( new SvXMLExportEventListener(this));
595 mxModel
->addEventListener(mxEventListener
);
598 if(!mxNumberFormatsSupplier
.is() )
600 mxNumberFormatsSupplier
.set(mxModel
, css::uno::UNO_QUERY
);
601 if(mxNumberFormatsSupplier
.is() && mxHandler
.is())
602 mpNumExport
.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier
) );
604 if (mxExportInfo
.is())
606 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxExportInfo
->getPropertySetInfo();
607 if (xPropertySetInfo
.is())
609 OUString
sUsePrettyPrinting(XML_USEPRETTYPRINTING
);
610 if (xPropertySetInfo
->hasPropertyByName(sUsePrettyPrinting
))
612 uno::Any aAny
= mxExportInfo
->getPropertyValue(sUsePrettyPrinting
);
613 if (::cppu::any2bool(aAny
))
614 mnExportFlags
|= SvXMLExportFlags::PRETTY
;
616 mnExportFlags
&= ~SvXMLExportFlags::PRETTY
;
619 if (mpNumExport
&& (mnExportFlags
& (SvXMLExportFlags::AUTOSTYLES
| SvXMLExportFlags::STYLES
)))
621 OUString
sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES
);
622 if (xPropertySetInfo
->hasPropertyByName(sWrittenNumberFormats
))
624 uno::Any aAny
= mxExportInfo
->getPropertyValue(sWrittenNumberFormats
);
625 uno::Sequence
<sal_Int32
> aWasUsed
;
626 if(aAny
>>= aWasUsed
)
627 mpNumExport
->SetWasUsed(aWasUsed
);
633 // namespaces for user defined attributes
634 Reference
< XMultiServiceFactory
> xFactory( mxModel
, UNO_QUERY
);
639 Reference
< XInterface
> xIfc
=
640 xFactory
->createInstance("com.sun.star.xml.NamespaceMap");
643 Reference
< XNameAccess
> xNamespaceMap( xIfc
, UNO_QUERY
);
644 if( xNamespaceMap
.is() )
646 const Sequence
< OUString
> aPrefixes( xNamespaceMap
->getElementNames() );
647 for( OUString
const & prefix
: aPrefixes
)
650 if( xNamespaceMap
->getByName( prefix
) >>= aURL
)
651 GetNamespaceMap_().Add( prefix
, aURL
);
656 catch(const css::uno::Exception
&)
661 // Determine model type (#i51726#)
662 DetermineModelType_();
666 void SAL_CALL
SvXMLExport::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
668 // #93186# we need to queryInterface every single Any with any expected outcome. This variable hold the queryInterface results.
670 for( const auto& rAny
: aArguments
)
672 Reference
<XInterface
> xValue
;
676 uno::Reference
<task::XStatusIndicator
> xTmpStatus( xValue
, UNO_QUERY
);
677 if ( xTmpStatus
.is() )
678 mxStatusIndicator
= xTmpStatus
;
680 // graphic storage handler
681 uno::Reference
<document::XGraphicStorageHandler
> xGraphicStorageHandler(xValue
, UNO_QUERY
);
682 if (xGraphicStorageHandler
.is())
683 mxGraphicStorageHandler
= xGraphicStorageHandler
;
686 uno::Reference
<document::XEmbeddedObjectResolver
> xTmpObjectResolver(
688 if ( xTmpObjectResolver
.is() )
689 mxEmbeddedResolver
= xTmpObjectResolver
;
692 uno::Reference
<xml::sax::XDocumentHandler
> xTmpDocHandler(
694 if( xTmpDocHandler
.is() )
696 mxHandler
= xTmpDocHandler
;
697 rAny
>>= mxExtHandler
;
699 if (mxNumberFormatsSupplier
.is() && mpNumExport
== nullptr)
700 mpNumExport
.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier
) );
703 // property set to transport data across
704 uno::Reference
<beans::XPropertySet
> xTmpPropertySet(
706 if( xTmpPropertySet
.is() )
707 mxExportInfo
= xTmpPropertySet
;
710 if( !mxExportInfo
.is() )
713 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
=
714 mxExportInfo
->getPropertySetInfo();
717 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
719 uno::Any aAny
= mxExportInfo
->getPropertyValue(sPropName
);
720 aAny
>>= msOrigFileName
;
721 mpImpl
->msPackageURI
= msOrigFileName
;
722 mpImpl
->SetSchemeOf( msOrigFileName
);
725 sPropName
= "StreamRelPath";
726 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
728 uno::Any aAny
= mxExportInfo
->getPropertyValue(sPropName
);
732 sPropName
= "StreamName";
733 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
735 uno::Any aAny
= mxExportInfo
->getPropertyValue(sPropName
);
738 if( !msOrigFileName
.isEmpty() && !sName
.isEmpty() )
740 INetURLObject
aBaseURL( msOrigFileName
);
741 if( !sRelPath
.isEmpty() )
742 aBaseURL
.insertName( sRelPath
);
743 aBaseURL
.insertName( sName
);
744 msOrigFileName
= aBaseURL
.GetMainURL(INetURLObject::DecodeMechanism::ToIUri
);
746 mpImpl
->mStreamName
= sName
; // Note: may be empty (XSLT)
748 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
749 const OUString
sOutlineStyleAsNormalListStyle(
750 "OutlineStyleAsNormalListStyle" );
751 if( xPropertySetInfo
->hasPropertyByName( sOutlineStyleAsNormalListStyle
) )
753 uno::Any aAny
= mxExportInfo
->getPropertyValue( sOutlineStyleAsNormalListStyle
);
754 aAny
>>= mpImpl
->mbOutlineStyleAsNormalListStyle
;
757 OUString
sTargetStorage( "TargetStorage" );
758 if( xPropertySetInfo
->hasPropertyByName( sTargetStorage
) )
759 mxExportInfo
->getPropertyValue( sTargetStorage
) >>= mpImpl
->mxTargetStorage
;
761 const OUString
sExportTextNumberElement(
762 "ExportTextNumberElement" );
763 if( xPropertySetInfo
->hasPropertyByName( sExportTextNumberElement
) )
765 uno::Any aAny
= mxExportInfo
->getPropertyValue( sExportTextNumberElement
);
766 aAny
>>= mpImpl
->mbExportTextNumberElement
;
771 sal_Bool SAL_CALL
SvXMLExport::filter( const uno::Sequence
< beans::PropertyValue
>& aDescriptor
)
773 // check for xHandler first... should have been supplied in initialize
774 if( !mxHandler
.is() )
779 const SvXMLExportFlags nTest
=
780 SvXMLExportFlags::META
|SvXMLExportFlags::STYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SETTINGS
;
781 if( (mnExportFlags
& nTest
) == nTest
&& msOrigFileName
.isEmpty() )
783 // evaluate descriptor only for flat files and if a base URI
784 // has not been provided already
786 for( const auto& rProp
: aDescriptor
)
788 const OUString
& rPropName
= rProp
.Name
;
789 const Any
& rValue
= rProp
.Value
;
791 if ( rPropName
== "FileName" )
793 if( !(rValue
>>= msOrigFileName
) )
796 else if ( rPropName
== "FilterName" )
798 if( !(rValue
>>= msFilterName
) )
804 for( const auto& rProp
: aDescriptor
)
806 const OUString
& rPropName
= rProp
.Name
;
807 const Any
& rValue
= rProp
.Value
;
809 if (rPropName
== "SourceShellID")
811 if (!(rValue
>>= mpImpl
->maSrcShellID
))
814 else if (rPropName
== "DestinationShellID")
816 if (!(rValue
>>= mpImpl
->maDestShellID
))
819 else if( rPropName
== "ImageFilter")
821 if (!(rValue
>>= msImgFilterName
))
827 exportDoc( meClass
);
829 catch(const uno::Exception
& e
)
831 // We must catch exceptions, because according to the
832 // API definition export must not throw one!
833 css::uno::Any
ex(cppu::getCaughtException());
834 OUString
sMessage( ex
.getValueTypeName() + ": \"" + e
.Message
+ "\"");
837 const char* pContext
= typeid(*e
.Context
).name();
838 sMessage
+= " (context: " + OUString::createFromAscii(pContext
) + " )";
840 SetError( XMLERROR_FLAG_ERROR
| XMLERROR_FLAG_SEVERE
| XMLERROR_API
,
841 Sequence
<OUString
>(), sMessage
, nullptr );
844 // return true only if no error occurred
845 return (mnErrorFlags
& (SvXMLErrorFlags::DO_NOTHING
|SvXMLErrorFlags::ERROR_OCCURRED
)) == SvXMLErrorFlags::NO
;
848 void SAL_CALL
SvXMLExport::cancel()
851 Sequence
<OUString
> aEmptySeq
;
852 SetError(XMLERROR_CANCEL
|XMLERROR_FLAG_SEVERE
, aEmptySeq
);
855 OUString SAL_CALL
SvXMLExport::getName( )
860 void SAL_CALL
SvXMLExport::setName( const OUString
& )
862 // do nothing, because it is not possible to set the FilterName
866 OUString SAL_CALL
SvXMLExport::getImplementationName( )
868 return m_implementationName
;
871 sal_Bool SAL_CALL
SvXMLExport::supportsService( const OUString
& rServiceName
)
873 return cppu::supportsService(this, rServiceName
);
876 uno::Sequence
< OUString
> SAL_CALL
SvXMLExport::getSupportedServiceNames( )
878 return { "com.sun.star.document.ExportFilter", "com.sun.star.xml.XMLExportFilter" };
882 SvXMLExport::EnsureNamespace(OUString
const & i_rNamespace
)
884 OUString
const aPreferredPrefix("gen");
886 sal_uInt16
nKey( GetNamespaceMap_().GetKeyByName( i_rNamespace
) );
887 if( XML_NAMESPACE_UNKNOWN
== nKey
)
889 // There is no prefix for the namespace, so
890 // we have to generate one and have to add it.
891 sPrefix
= aPreferredPrefix
;
892 nKey
= GetNamespaceMap_().GetKeyByPrefix( sPrefix
);
895 while( nKey
!= USHRT_MAX
)
897 buf
.append( aPreferredPrefix
);
899 sPrefix
= buf
.makeStringAndClear();
900 nKey
= GetNamespaceMap_().GetKeyByPrefix( sPrefix
);
903 if (mpImpl
->mNamespaceMaps
.empty()
904 || (mpImpl
->mNamespaceMaps
.top().second
!= mpImpl
->mDepth
))
906 // top was created for lower depth... need a new namespace map!
907 auto pNew
= new SvXMLNamespaceMap( *mpNamespaceMap
);
908 mpImpl
->mNamespaceMaps
.push(
909 ::std::make_pair(std::move(mpNamespaceMap
), mpImpl
->mDepth
) );
910 mpNamespaceMap
.reset( pNew
);
913 // add the namespace to the map and as attribute
914 mpNamespaceMap
->Add( sPrefix
, i_rNamespace
);
915 buf
.append( GetXMLToken(XML_XMLNS
) );
917 buf
.append( sPrefix
);
918 AddAttribute( buf
.makeStringAndClear(), i_rNamespace
);
922 // If there is a prefix for the namespace, reuse that.
923 sPrefix
= GetNamespaceMap_().GetPrefixByKey( nKey
);
928 void SvXMLExport::AddAttributeASCII( sal_uInt16 nPrefixKey
,
932 OUString
sName( OUString::createFromAscii( pName
) );
933 OUString
sValue( OUString::createFromAscii( pValue
) );
935 mxAttrList
->AddAttribute(
936 GetNamespaceMap_().GetQNameByKey( nPrefixKey
, sName
), sValue
);
939 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey
, const char *pName
,
940 const OUString
& rValue
)
942 OUString
sName( OUString::createFromAscii( pName
) );
944 mxAttrList
->AddAttribute(
945 GetNamespaceMap_().GetQNameByKey( nPrefixKey
, sName
), rValue
);
948 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey
, const OUString
& rName
,
949 const OUString
& rValue
)
951 mxAttrList
->AddAttribute(
952 GetNamespaceMap_().GetQNameByKey( nPrefixKey
, rName
), rValue
);
955 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey
,
956 enum XMLTokenEnum eName
,
957 const OUString
& rValue
)
959 mxAttrList
->AddAttribute(
960 GetNamespaceMap_().GetQNameByKey( nPrefixKey
, GetXMLToken(eName
) ),
964 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey
,
965 enum XMLTokenEnum eName
,
966 enum XMLTokenEnum eValue
)
968 mxAttrList
->AddAttribute(
969 GetNamespaceMap_().GetQNameByKey( nPrefixKey
, GetXMLToken(eName
) ),
970 GetXMLToken(eValue
) );
973 void SvXMLExport::AddAttribute( const OUString
& rQName
,
974 const OUString
& rValue
)
976 mxAttrList
->AddAttribute(
981 void SvXMLExport::AddAttribute( const OUString
& rQName
,
982 enum ::xmloff::token::XMLTokenEnum eValue
)
984 mxAttrList
->AddAttribute(
986 GetXMLToken(eValue
) );
989 void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix
, sal_uInt16 nPrefixRfc
,
990 const css::lang::Locale
& rLocale
, bool bWriteEmpty
)
992 if (rLocale
.Variant
.isEmpty())
994 // Per convention The BCP 47 string is always stored in Variant, if
995 // that is empty we have a plain language-country combination, no need
996 // to convert to LanguageTag first. Also catches the case of empty
997 // locale denoting system locale.
998 xmloff::token::XMLTokenEnum eLanguage
, eCountry
;
999 eLanguage
= XML_LANGUAGE
;
1000 eCountry
= XML_COUNTRY
;
1001 if (bWriteEmpty
|| !rLocale
.Language
.isEmpty())
1002 AddAttribute( nPrefix
, eLanguage
, rLocale
.Language
);
1003 if (bWriteEmpty
|| !rLocale
.Country
.isEmpty())
1004 AddAttribute( nPrefix
, eCountry
, rLocale
.Country
);
1008 LanguageTag
aLanguageTag( rLocale
);
1009 AddLanguageTagAttributes( nPrefix
, nPrefixRfc
, aLanguageTag
, bWriteEmpty
);
1013 void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix
, sal_uInt16 nPrefixRfc
,
1014 const LanguageTag
& rLanguageTag
, bool bWriteEmpty
)
1016 if (rLanguageTag
.isIsoODF())
1018 if (bWriteEmpty
|| !rLanguageTag
.isSystemLocale())
1020 AddAttribute( nPrefix
, XML_LANGUAGE
, rLanguageTag
.getLanguage());
1021 if (rLanguageTag
.hasScript() && getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
1022 AddAttribute( nPrefix
, XML_SCRIPT
, rLanguageTag
.getScript());
1023 if (bWriteEmpty
|| !rLanguageTag
.getCountry().isEmpty())
1024 AddAttribute( nPrefix
, XML_COUNTRY
, rLanguageTag
.getCountry());
1029 if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
1030 AddAttribute( nPrefixRfc
, XML_RFC_LANGUAGE_TAG
, rLanguageTag
.getBcp47());
1031 // Also in case of non-pure-ISO tag store best matching fo: attributes
1032 // for consumers not handling *:rfc-language-tag, ensuring that only
1033 // valid ISO codes are stored. Here the bWriteEmpty parameter has no
1035 OUString aLanguage
, aScript
, aCountry
;
1036 rLanguageTag
.getIsoLanguageScriptCountry( aLanguage
, aScript
, aCountry
);
1037 if (!aLanguage
.isEmpty())
1039 AddAttribute( nPrefix
, XML_LANGUAGE
, aLanguage
);
1040 if (!aScript
.isEmpty() && getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012
)
1041 AddAttribute( nPrefix
, XML_SCRIPT
, aScript
);
1042 if (!aCountry
.isEmpty())
1043 AddAttribute( nPrefix
, XML_COUNTRY
, aCountry
);
1048 void SvXMLExport::AddAttributeList( const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
1051 mxAttrList
->AppendAttributeList( xAttrList
);
1054 void SvXMLExport::ClearAttrList()
1056 mxAttrList
->Clear();
1060 void SvXMLExport::CheckAttrList()
1062 SAL_WARN_IF( mxAttrList
->getLength(), "xmloff.core", "XMLExport::CheckAttrList: list is not empty" );
1066 void SvXMLExport::ImplExportMeta()
1073 void SvXMLExport::ImplExportSettings()
1077 ::std::vector
< SettingsGroup
> aSettings
;
1078 sal_Int32 nSettingsCount
= 0;
1081 uno::Sequence
< beans::PropertyValue
> aViewSettings
;
1082 GetViewSettingsAndViews( aViewSettings
);
1083 aSettings
.emplace_back( XML_VIEW_SETTINGS
, aViewSettings
);
1084 nSettingsCount
+= aViewSettings
.getLength();
1086 // configuration settings
1087 uno::Sequence
<beans::PropertyValue
> aConfigSettings
;
1088 GetConfigurationSettings( aConfigSettings
);
1089 aSettings
.emplace_back( XML_CONFIGURATION_SETTINGS
, aConfigSettings
);
1090 nSettingsCount
+= aConfigSettings
.getLength();
1092 // any document specific settings
1093 nSettingsCount
+= GetDocumentSpecificSettings( aSettings
);
1096 SvXMLElementExport
aElem( *this,
1097 nSettingsCount
!= 0,
1098 XML_NAMESPACE_OFFICE
, XML_SETTINGS
,
1101 SettingsExportFacade
aSettingsExportContext( *this );
1102 XMLSettingsExportHelper
aSettingsExportHelper( aSettingsExportContext
);
1104 for (auto const& settings
: aSettings
)
1106 if ( !settings
.aSettings
.hasElements() )
1109 const OUString
& sSettingsName( GetXMLToken( settings
.eGroupName
) );
1110 OUString sQName
= GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OOO
, sSettingsName
);
1111 aSettingsExportHelper
.exportAllSettings( settings
.aSettings
, sQName
);
1116 void SvXMLExport::ImplExportStyles()
1122 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
, XML_STYLES
,
1125 ExportStyles_( false );
1128 // transfer style names (+ families) TO other components (if appropriate)
1129 if( ( mnExportFlags
& SvXMLExportFlags::CONTENT
) || !mxExportInfo
.is() )
1132 static OUString
sStyleNames( "StyleNames" );
1133 static OUString
sStyleFamilies( "StyleFamilies" );
1134 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxExportInfo
->getPropertySetInfo();
1135 if ( xPropertySetInfo
->hasPropertyByName( sStyleNames
) && xPropertySetInfo
->hasPropertyByName( sStyleFamilies
) )
1137 Sequence
<sal_Int32
> aStyleFamilies
;
1138 Sequence
<OUString
> aStyleNames
;
1139 mxAutoStylePool
->GetRegisteredNames( aStyleFamilies
, aStyleNames
);
1140 mxExportInfo
->setPropertyValue( sStyleNames
, makeAny( aStyleNames
) );
1141 mxExportInfo
->setPropertyValue( sStyleFamilies
,
1142 makeAny( aStyleFamilies
) );
1146 void SvXMLExport::ImplExportAutoStyles()
1148 // transfer style names (+ families) FROM other components (if appropriate)
1149 OUString
sStyleNames( "StyleNames" );
1150 OUString
sStyleFamilies( "StyleFamilies" );
1151 if( ( !( mnExportFlags
& SvXMLExportFlags::STYLES
) )
1152 && mxExportInfo
.is()
1153 && mxExportInfo
->getPropertySetInfo()->hasPropertyByName( sStyleNames
)
1154 && mxExportInfo
->getPropertySetInfo()->hasPropertyByName( sStyleFamilies
) )
1156 Sequence
<sal_Int32
> aStyleFamilies
;
1157 mxExportInfo
->getPropertyValue( sStyleFamilies
) >>= aStyleFamilies
;
1158 Sequence
<OUString
> aStyleNames
;
1159 mxExportInfo
->getPropertyValue( sStyleNames
) >>= aStyleNames
;
1160 mxAutoStylePool
->RegisterNames( aStyleFamilies
, aStyleNames
);
1164 // <style:automatic-styles>
1165 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
,
1166 XML_AUTOMATIC_STYLES
, true, true );
1168 ExportAutoStyles_();
1172 void SvXMLExport::ImplExportMasterStyles()
1174 // <style:master-styles>
1175 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
, XML_MASTER_STYLES
,
1178 ExportMasterStyles_();
1181 void SvXMLExport::ImplExportContent()
1188 SvXMLElementExport
aElement( *this, XML_NAMESPACE_OFFICE
, XML_BODY
,
1191 XMLTokenEnum eClass
= meClass
;
1192 if( XML_TEXT_GLOBAL
== eClass
)
1194 AddAttribute( XML_NAMESPACE_TEXT
, XML_GLOBAL
,
1195 GetXMLToken( XML_TRUE
) );
1198 if ( XML_GRAPHICS
== eClass
)
1199 eClass
= XML_DRAWING
;
1200 // <office:body ...>
1201 SetBodyAttributes();
1202 SvXMLElementExport
aElem( *this, meClass
!= XML_TOKEN_INVALID
,
1203 XML_NAMESPACE_OFFICE
, eClass
,
1211 void SvXMLExport::SetBodyAttributes()
1216 lcl_AddGrddl(SvXMLExport
const & rExport
, const SvXMLExportFlags
/*nExportMode*/)
1218 // check version >= 1.2
1219 switch (rExport
.getSaneDefaultVersion()) {
1220 case SvtSaveOptions::ODFSVER_011
: // fall through
1221 case SvtSaveOptions::ODFSVER_010
: return;
1225 // #i115030#: disabled, the XSLT is not finished, and not available via HTTP
1227 if (SvXMLExportFlags::SETTINGS
!= nExportMode
) // meta, content, styles
1229 rExport
.AddAttribute( XML_NAMESPACE_GRDDL
, XML_TRANSFORMATION
,
1230 OUString("http://FIXME") );
1235 void SvXMLExport::addChaffWhenEncryptedStorage()
1237 uno::Reference
< embed::XEncryptionProtectedSource2
> xEncr(mpImpl
->mxTargetStorage
, uno::UNO_QUERY
);
1239 if (xEncr
.is() && xEncr
->hasEncryptionData() && mxExtHandler
.is())
1241 mxExtHandler
->comment(OStringToOUString(comphelper::xml::makeXMLChaff(), RTL_TEXTENCODING_ASCII_US
));
1245 auto SvXMLExport::GetODFVersionAttributeValue() const -> char const*
1247 char const* pVersion(nullptr);
1248 switch (getSaneDefaultVersion())
1250 case SvtSaveOptions::ODFSVER_013_EXTENDED
: [[fallthrough
]];
1251 case SvtSaveOptions::ODFSVER_013
: pVersion
= "1.3"; break;
1252 case SvtSaveOptions::ODFSVER_012_EXTENDED
: [[fallthrough
]];
1253 case SvtSaveOptions::ODFSVER_012_EXT_COMPAT
: [[fallthrough
]];
1254 case SvtSaveOptions::ODFSVER_012
: pVersion
= "1.2"; break;
1255 case SvtSaveOptions::ODFSVER_011
: pVersion
= "1.1"; break;
1256 case SvtSaveOptions::ODFSVER_010
: break;
1259 assert(!"xmloff::SvXMLExport::exportDoc(), unexpected odf default version!");
1264 ErrCode
SvXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass
)
1266 bool bOwnGraphicResolver
= false;
1267 bool bOwnEmbeddedResolver
= false;
1269 if (!mxGraphicStorageHandler
.is() || !mxEmbeddedResolver
.is())
1271 Reference
< XMultiServiceFactory
> xFactory( mxModel
, UNO_QUERY
);
1276 if (!mxGraphicStorageHandler
.is())
1278 mxGraphicStorageHandler
.set(xFactory
->createInstance( "com.sun.star.document.ExportGraphicStorageHandler"), UNO_QUERY
);
1279 bOwnGraphicResolver
= mxGraphicStorageHandler
.is();
1282 if( !mxEmbeddedResolver
.is() )
1284 mxEmbeddedResolver
.set(
1285 xFactory
->createInstance( "com.sun.star.document.ExportEmbeddedObjectResolver" ), UNO_QUERY
);
1286 bOwnEmbeddedResolver
= mxEmbeddedResolver
.is();
1289 catch(const css::uno::Exception
&)
1294 if( (getExportFlags() & SvXMLExportFlags::OASIS
) == SvXMLExportFlags::NONE
)
1298 static ::comphelper::PropertyMapEntry
const aInfoMap
[] =
1300 { OUString("Class"), 0,
1301 ::cppu::UnoType
<OUString
>::get(),
1302 PropertyAttribute::MAYBEVOID
, 0},
1303 { OUString(), 0, css::uno::Type(), 0, 0 }
1305 Reference
< XPropertySet
> xConvPropSet(
1306 ::comphelper::GenericPropertySet_CreateInstance(
1307 new ::comphelper::PropertySetInfo( aInfoMap
) ) );
1309 xConvPropSet
->setPropertyValue( "Class", Any(GetXMLToken( eClass
)) );
1311 Reference
< XPropertySet
> xPropSet
=
1313 ? PropertySetMerger_CreateInstance( mxExportInfo
,
1317 Sequence
<Any
> aArgs( 3 );
1318 aArgs
[0] <<= mxHandler
;
1319 aArgs
[1] <<= xPropSet
;
1320 aArgs
[2] <<= mxModel
;
1322 // get filter component
1323 Reference
< xml::sax::XDocumentHandler
> xTmpDocHandler(
1324 m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.comp.Oasis2OOoTransformer", aArgs
, m_xContext
),
1326 SAL_WARN_IF(!xTmpDocHandler
.is(), "xmloff.core", "can't instantiate OASIS transformer component" );
1327 if( xTmpDocHandler
.is() )
1329 mxHandler
= xTmpDocHandler
;
1330 mxExtHandler
.set( mxHandler
, UNO_QUERY
);
1333 catch(const css::uno::Exception
&)
1338 mxHandler
->startDocument();
1340 addChaffWhenEncryptedStorage();
1342 // <office:document ...>
1345 // namespace attributes
1346 // ( The namespace decls should be first attributes in the element;
1347 // some faulty XML parsers (JAXP1.1) have a problem with this,
1348 // also it's more elegant )
1349 sal_uInt16 nPos
= mpNamespaceMap
->GetFirstKey();
1350 while( USHRT_MAX
!= nPos
)
1352 mxAttrList
->AddAttribute( mpNamespaceMap
->GetAttrNameByKey( nPos
),
1353 mpNamespaceMap
->GetNameByKey( nPos
) );
1354 nPos
= mpNamespaceMap
->GetNextKey( nPos
);
1357 // office:version = ...
1358 const char*const pVersion
= GetODFVersionAttributeValue();
1362 AddAttribute( XML_NAMESPACE_OFFICE
, XML_VERSION
,
1363 OUString::createFromAscii(pVersion
) );
1367 enum XMLTokenEnum eRootService
= XML_TOKEN_INVALID
;
1368 const SvXMLExportFlags nExportMode
= mnExportFlags
& (SvXMLExportFlags::META
|SvXMLExportFlags::STYLES
|SvXMLExportFlags::CONTENT
|SvXMLExportFlags::SETTINGS
);
1370 lcl_AddGrddl(*this, nExportMode
);
1372 if( SvXMLExportFlags::META
== nExportMode
)
1375 eRootService
= XML_DOCUMENT_META
;
1377 else if ( SvXMLExportFlags::SETTINGS
== nExportMode
)
1379 // export only settings
1380 eRootService
= XML_DOCUMENT_SETTINGS
;
1382 else if( SvXMLExportFlags::STYLES
== nExportMode
)
1384 // export only styles
1385 eRootService
= XML_DOCUMENT_STYLES
;
1387 else if( SvXMLExportFlags::CONTENT
== nExportMode
)
1389 // export only content
1390 eRootService
= XML_DOCUMENT_CONTENT
;
1394 // the god'ol one4all element
1395 eRootService
= XML_DOCUMENT
;
1396 // office:mimetype = ... (only for stream containing the content)
1397 if( eClass
!= XML_TOKEN_INVALID
)
1399 OUString aTmp
= "application/vnd.oasis.opendocument." + GetXMLToken( eClass
);
1400 AddAttribute( XML_NAMESPACE_OFFICE
, XML_MIMETYPE
, aTmp
);
1404 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
, eRootService
, true, true );
1407 if( mnExportFlags
& SvXMLExportFlags::META
)
1411 if( mnExportFlags
& SvXMLExportFlags::SETTINGS
)
1412 ImplExportSettings();
1415 if( mnExportFlags
& SvXMLExportFlags::SCRIPTS
)
1418 // font declarations
1419 if( mnExportFlags
& SvXMLExportFlags::FONTDECLS
)
1423 if( mnExportFlags
& SvXMLExportFlags::STYLES
)
1427 if( mnExportFlags
& SvXMLExportFlags::AUTOSTYLES
)
1428 ImplExportAutoStyles();
1431 if( mnExportFlags
& SvXMLExportFlags::MASTERSTYLES
)
1432 ImplExportMasterStyles();
1435 if( mnExportFlags
& SvXMLExportFlags::CONTENT
)
1436 ImplExportContent();
1439 mxHandler
->endDocument();
1441 if( bOwnGraphicResolver
)
1443 uno::Reference
<XComponent
> xComp(mxGraphicStorageHandler
, UNO_QUERY
);
1447 if( bOwnEmbeddedResolver
)
1449 Reference
< XComponent
> xComp( mxEmbeddedResolver
, UNO_QUERY
);
1453 return ERRCODE_NONE
;
1456 void SvXMLExport::ResetNamespaceMap()
1458 mpNamespaceMap
.reset( new SvXMLNamespaceMap
);
1461 OUString
const & SvXMLExport::GetSourceShellID() const
1463 return mpImpl
->maSrcShellID
;
1466 OUString
const & SvXMLExport::GetDestinationShellID() const
1468 return mpImpl
->maDestShellID
;
1471 void SvXMLExport::ExportMeta_()
1473 OUString
generator( ::utl::DocInfoHelper::GetGeneratorString() );
1474 Reference
< XDocumentPropertiesSupplier
> xDocPropsSupplier(mxModel
,
1476 if (xDocPropsSupplier
.is()) {
1477 Reference
<XDocumentProperties
> xDocProps(
1478 xDocPropsSupplier
->getDocumentProperties());
1479 if (!xDocProps
.is()) throw;
1480 // update generator here
1481 xDocProps
->setGenerator(generator
);
1482 rtl::Reference
<SvXMLMetaExport
> pMeta
= new SvXMLMetaExport(*this, xDocProps
);
1486 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
, XML_META
,
1489 // BM: #i60323# export generator even if xInfoProp is empty (which is the
1490 // case for charts). The generator does not depend on xInfoProp
1491 SvXMLElementExport
anElem( *this, XML_NAMESPACE_META
, XML_GENERATOR
,
1493 Characters(generator
);
1498 void SvXMLExport::ExportScripts_()
1500 SvXMLElementExport
aElement( *this, XML_NAMESPACE_OFFICE
, XML_SCRIPTS
, true, true );
1502 // export Basic macros (only for FlatXML)
1503 if ( mnExportFlags
& SvXMLExportFlags::EMBEDDED
)
1505 OUString
aValue( GetNamespaceMap().GetPrefixByKey( XML_NAMESPACE_OOO
) + ":Basic" );
1506 AddAttribute( XML_NAMESPACE_SCRIPT
, XML_LANGUAGE
, aValue
);
1508 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
, XML_SCRIPT
, true, true );
1513 Reference
< beans::XPropertySet
> xPSet( mxModel
, UNO_QUERY
);
1515 xPSet
->getPropertyValue("BasicLibraries");
1518 Reference
< XDocumentHandler
> xHdl( new XMLBasicExportFilter( mxHandler
) );
1519 Reference
< document::XXMLBasicExporter
> xExporter
= document::XMLOasisBasicExporter::createWithHandler( m_xContext
, xHdl
);
1521 xExporter
->setSourceDocument( mxModel
);
1522 Sequence
< PropertyValue
> aMediaDesc( 0 );
1523 xExporter
->filter( aMediaDesc
);
1526 // export document events
1527 Reference
< document::XEventsSupplier
> xEvents( GetModel(), UNO_QUERY
);
1528 GetEventExport().Export( xEvents
);
1531 void SvXMLExport::ExportFontDecls_()
1533 if( mxFontAutoStylePool
.is() )
1534 mxFontAutoStylePool
->exportXML();
1537 void SvXMLExport::ExportStyles_( bool )
1539 uno::Reference
< lang::XMultiServiceFactory
> xFact( GetModel(), uno::UNO_QUERY
);
1543 // export (fill-)gradient-styles
1546 uno::Reference
< container::XNameAccess
> xGradient( xFact
->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY
);
1547 if( xGradient
.is() )
1549 XMLGradientStyleExport
aGradientStyle( *this );
1551 if( xGradient
->hasElements() )
1553 const uno::Sequence
< OUString
> aNamesSeq ( xGradient
->getElementNames() );
1554 for( const OUString
& rStrName
: aNamesSeq
)
1558 uno::Any aValue
= xGradient
->getByName( rStrName
);
1560 aGradientStyle
.exportXML( rStrName
, aValue
);
1562 catch(const container::NoSuchElementException
&)
1569 catch(const lang::ServiceNotRegisteredException
&)
1573 // export (fill-)hatch-styles
1576 uno::Reference
< container::XNameAccess
> xHatch( xFact
->createInstance("com.sun.star.drawing.HatchTable"), uno::UNO_QUERY
);
1579 XMLHatchStyleExport
aHatchStyle( *this );
1581 if( xHatch
->hasElements() )
1583 const uno::Sequence
< OUString
> aNamesSeq ( xHatch
->getElementNames() );
1584 for( const OUString
& rStrName
: aNamesSeq
)
1588 uno::Any aValue
= xHatch
->getByName( rStrName
);
1590 aHatchStyle
.exportXML( rStrName
, aValue
);
1592 catch(const container::NoSuchElementException
&)
1598 catch(const lang::ServiceNotRegisteredException
&)
1602 // export (fill-)bitmap-styles
1605 uno::Reference
< container::XNameAccess
> xBitmap( xFact
->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY
);
1608 if( xBitmap
->hasElements() )
1610 const uno::Sequence
< OUString
> aNamesSeq ( xBitmap
->getElementNames() );
1611 for( const OUString
& rStrName
: aNamesSeq
)
1615 uno::Any aValue
= xBitmap
->getByName( rStrName
);
1617 XMLImageStyle::exportXML( rStrName
, aValue
, *this );
1619 catch(const container::NoSuchElementException
&)
1626 catch(const lang::ServiceNotRegisteredException
&)
1630 // export transparency-gradient -styles
1633 uno::Reference
< container::XNameAccess
> xTransGradient( xFact
->createInstance("com.sun.star.drawing.TransparencyGradientTable"), uno::UNO_QUERY
);
1634 if( xTransGradient
.is() )
1636 XMLTransGradientStyleExport
aTransGradientstyle( *this );
1638 if( xTransGradient
->hasElements() )
1640 const uno::Sequence
< OUString
> aNamesSeq ( xTransGradient
->getElementNames() );
1641 for( const OUString
& rStrName
: aNamesSeq
)
1645 uno::Any aValue
= xTransGradient
->getByName( rStrName
);
1647 aTransGradientstyle
.exportXML( rStrName
, aValue
);
1649 catch(const container::NoSuchElementException
&)
1656 catch(const lang::ServiceNotRegisteredException
&)
1660 // export marker-styles
1663 uno::Reference
< container::XNameAccess
> xMarker( xFact
->createInstance("com.sun.star.drawing.MarkerTable"), uno::UNO_QUERY
);
1666 XMLMarkerStyleExport
aMarkerStyle( *this );
1668 if( xMarker
->hasElements() )
1670 const uno::Sequence
< OUString
> aNamesSeq ( xMarker
->getElementNames() );
1671 for( const OUString
& rStrName
: aNamesSeq
)
1675 uno::Any aValue
= xMarker
->getByName( rStrName
);
1677 aMarkerStyle
.exportXML( rStrName
, aValue
);
1679 catch(const container::NoSuchElementException
&)
1686 catch(const lang::ServiceNotRegisteredException
&)
1690 // export dash-styles
1693 uno::Reference
< container::XNameAccess
> xDashes( xFact
->createInstance("com.sun.star.drawing.DashTable"), uno::UNO_QUERY
);
1696 XMLDashStyleExport
aDashStyle( *this );
1698 if( xDashes
->hasElements() )
1700 const uno::Sequence
< OUString
> aNamesSeq ( xDashes
->getElementNames() );
1701 for( const OUString
& rStrName
: aNamesSeq
)
1705 uno::Any aValue
= xDashes
->getByName( rStrName
);
1707 aDashStyle
.exportXML( rStrName
, aValue
);
1709 catch(const container::NoSuchElementException
&)
1716 catch(const lang::ServiceNotRegisteredException
&)
1721 XMLTextParagraphExport
* SvXMLExport::CreateTextParagraphExport()
1723 return new XMLTextParagraphExport( *this, *GetAutoStylePool() );
1726 XMLShapeExport
* SvXMLExport::CreateShapeExport()
1728 return new XMLShapeExport(*this);
1731 SvXMLAutoStylePoolP
* SvXMLExport::CreateAutoStylePool()
1733 return new SvXMLAutoStylePoolP(*this);
1736 void SvXMLExport::collectAutoStyles()
1740 XMLPageExport
* SvXMLExport::CreatePageExport()
1742 return new XMLPageExport( *this );
1745 SchXMLExportHelper
* SvXMLExport::CreateChartExport()
1747 return new SchXMLExportHelper(*this, *GetAutoStylePool());
1750 XMLFontAutoStylePool
* SvXMLExport::CreateFontAutoStylePool()
1752 return new XMLFontAutoStylePool( *this );
1755 xmloff::OFormLayerXMLExport
* SvXMLExport::CreateFormExport()
1757 return new xmloff::OFormLayerXMLExport(*this);
1760 void SvXMLExport::GetViewSettingsAndViews(uno::Sequence
<beans::PropertyValue
>& rProps
)
1762 GetViewSettings(rProps
);
1763 uno::Reference
<document::XViewDataSupplier
> xViewDataSupplier(GetModel(), uno::UNO_QUERY
);
1764 if(!xViewDataSupplier
.is())
1767 uno::Reference
<container::XIndexAccess
> xIndexAccess
;
1768 xViewDataSupplier
->setViewData( xIndexAccess
); // make sure we get a newly created sequence
1770 // tdf#130559: don't export preview view data if active
1771 css::uno::ContextLayer
layer(comphelper::NewFlagContext("NoPreviewData"));
1772 xIndexAccess
= xViewDataSupplier
->getViewData();
1776 if(xIndexAccess
.is() && xIndexAccess
->hasElements() )
1778 sal_Int32 nCount
= xIndexAccess
->getCount();
1779 for (sal_Int32 i
= 0; i
< nCount
; i
++)
1781 aAny
= xIndexAccess
->getByIndex(i
);
1782 uno::Sequence
<beans::PropertyValue
> aProps
;
1783 if( aAny
>>= aProps
)
1785 if( aProps
.hasElements() )
1796 sal_Int32
nOldLength(rProps
.getLength());
1797 rProps
.realloc(nOldLength
+ 1);
1798 beans::PropertyValue aProp
;
1799 aProp
.Name
= "Views";
1800 aProp
.Value
<<= xIndexAccess
;
1801 rProps
[nOldLength
] = aProp
;
1805 void SvXMLExport::GetViewSettings(uno::Sequence
<beans::PropertyValue
>&)
1809 void SvXMLExport::GetConfigurationSettings(uno::Sequence
<beans::PropertyValue
>&)
1813 sal_Int32
SvXMLExport::GetDocumentSpecificSettings( ::std::vector
< SettingsGroup
>& )
1818 void SvXMLExport::collectDataStyles(bool bFromUsedStyles
)
1820 Reference
<style::XStyleFamiliesSupplier
> xStyleFamiliesSupplier(GetModel(), uno::UNO_QUERY
);
1821 if (!xStyleFamiliesSupplier
.is())
1824 Reference
<container::XNameAccess
> xStylesFamilies(xStyleFamiliesSupplier
->getStyleFamilies());
1825 if (!xStylesFamilies
.is())
1828 Reference
<container::XIndexAccess
> xCellStyles(xStylesFamilies
->getByName("CellStyles"), uno::UNO_QUERY
);
1829 if (!xCellStyles
.is())
1832 sal_Int32
nCount(xCellStyles
->getCount());
1833 for (sal_Int32 i
= 0; i
< nCount
; ++i
)
1835 Reference
<style::XStyle
> xStyle(xCellStyles
->getByIndex(i
), uno::UNO_QUERY
);
1836 if (bFromUsedStyles
&& !xStyle
->isInUse())
1839 Reference
<beans::XPropertySet
> xCellProperties(xStyle
, uno::UNO_QUERY
);
1840 if (xCellProperties
.is())
1842 sal_Int32 nNumberFormat
= 0;
1843 if (xCellProperties
->getPropertyValue("NumberFormat") >>= nNumberFormat
)
1844 addDataStyle(nNumberFormat
);
1849 void SvXMLExport::addDataStyle(const sal_Int32 nNumberFormat
, bool /*bTimeFormat*/ )
1852 mpNumExport
->SetUsed(nNumberFormat
);
1855 void SvXMLExport::exportDataStyles()
1858 mpNumExport
->Export(false);
1861 void SvXMLExport::exportAutoDataStyles()
1864 mpNumExport
->Export(true);
1866 if (mxFormExport
.is())
1867 mxFormExport
->exportAutoControlNumberStyles();
1870 OUString
SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat
, bool /*bTimeFormat*/ ) const
1874 sTemp
= mpNumExport
->GetStyleName(nNumberFormat
);
1878 void SvXMLExport::exportAnnotationMeta(const uno::Reference
<drawing::XShape
>&)
1882 sal_Int32
SvXMLExport::dataStyleForceSystemLanguage(sal_Int32 nFormat
) const
1884 return ( mpNumExport
!= nullptr )
1885 ? mpNumExport
->ForceSystemLanguage( nFormat
) : nFormat
;
1888 OUString
SvXMLExport::AddEmbeddedXGraphic(uno::Reference
<graphic::XGraphic
> const & rxGraphic
, OUString
& rOutMimeType
, OUString
const & rRequestedName
)
1892 Graphic
aGraphic(rxGraphic
);
1893 OUString aOriginURL
= aGraphic
.getOriginURL();
1895 if (!aOriginURL
.isEmpty())
1897 sURL
= GetRelativeReference(aOriginURL
);
1901 if (mxGraphicStorageHandler
.is())
1903 if (!(getExportFlags() & SvXMLExportFlags::EMBEDDED
))
1904 sURL
= mxGraphicStorageHandler
->saveGraphicByName(rxGraphic
, rOutMimeType
, rRequestedName
);
1910 bool SvXMLExport::GetGraphicMimeTypeFromStream(uno::Reference
<graphic::XGraphic
> const & rxGraphic
, OUString
& rOutMimeType
)
1912 if (mxGraphicStorageHandler
.is())
1914 Reference
<XInputStream
> xInputStream(mxGraphicStorageHandler
->createInputStream(rxGraphic
));
1915 if (xInputStream
.is())
1917 rOutMimeType
= comphelper::GraphicMimeTypeHelper::GetMimeTypeForImageStream(xInputStream
);
1925 bool SvXMLExport::AddEmbeddedXGraphicAsBase64(uno::Reference
<graphic::XGraphic
> const & rxGraphic
)
1927 if ((getExportFlags() & SvXMLExportFlags::EMBEDDED
) &&
1928 mxGraphicStorageHandler
.is())
1930 Reference
<XInputStream
> xInputStream(mxGraphicStorageHandler
->createInputStream(rxGraphic
));
1931 if (xInputStream
.is())
1933 Graphic
aGraphic(rxGraphic
);
1934 if (aGraphic
.getOriginURL().isEmpty()) // don't add the base64 if the origin URL is set (image is from an external URL)
1936 XMLBase64Export
aBase64Exp(*this);
1937 return aBase64Exp
.exportOfficeBinaryDataElement(xInputStream
);
1945 OUString
SvXMLExport::AddEmbeddedObject( const OUString
& rEmbeddedObjectURL
)
1948 bool bSupportedURL
= rEmbeddedObjectURL
.startsWith(XML_EMBEDDEDOBJECT_URL_BASE
) ||
1949 rEmbeddedObjectURL
.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
);
1950 if (bSupportedURL
&& mxEmbeddedResolver
.is())
1952 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL(rEmbeddedObjectURL
);
1955 sRet
= GetRelativeReference( rEmbeddedObjectURL
);
1960 bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString
& rEmbeddedObjectURL
)
1963 bool bSupportedURL
= rEmbeddedObjectURL
.startsWith(XML_EMBEDDEDOBJECT_URL_BASE
) ||
1964 rEmbeddedObjectURL
.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE
);
1965 if (bSupportedURL
&& mxEmbeddedResolver
.is())
1967 Reference
< XNameAccess
> xNA( mxEmbeddedResolver
, UNO_QUERY
);
1970 Any aAny
= xNA
->getByName( rEmbeddedObjectURL
);
1971 Reference
< XInputStream
> xIn
;
1975 XMLBase64Export
aBase64Exp( *this );
1976 bRet
= aBase64Exp
.exportOfficeBinaryDataElement( xIn
);
1984 OUString
SvXMLExport::EncodeStyleName(
1985 const OUString
& rName
,
1986 bool *pEncoded
) const
1988 return GetMM100UnitConverter().encodeStyleName( rName
, pEncoded
);
1991 ProgressBarHelper
* SvXMLExport::GetProgressBarHelper()
1993 if (!mpProgressBarHelper
)
1995 mpProgressBarHelper
.reset( new ProgressBarHelper(mxStatusIndicator
, true) );
1997 if (mxExportInfo
.is())
1999 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxExportInfo
->getPropertySetInfo();
2000 if (xPropertySetInfo
.is())
2002 OUString
sProgressRange(XML_PROGRESSRANGE
);
2003 OUString
sProgressMax(XML_PROGRESSMAX
);
2004 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
2005 OUString
sRepeat(XML_PROGRESSREPEAT
);
2006 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
2007 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
) &&
2008 xPropertySetInfo
->hasPropertyByName(sProgressRange
))
2011 sal_Int32
nProgressMax(0);
2012 sal_Int32
nProgressCurrent(0);
2013 sal_Int32
nProgressRange(0);
2014 aAny
= mxExportInfo
->getPropertyValue(sProgressRange
);
2015 if (aAny
>>= nProgressRange
)
2016 mpProgressBarHelper
->SetRange(nProgressRange
);
2017 aAny
= mxExportInfo
->getPropertyValue(sProgressMax
);
2018 if (aAny
>>= nProgressMax
)
2019 mpProgressBarHelper
->SetReference(nProgressMax
);
2020 aAny
= mxExportInfo
->getPropertyValue(sProgressCurrent
);
2021 if (aAny
>>= nProgressCurrent
)
2022 mpProgressBarHelper
->SetValue(nProgressCurrent
);
2024 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
2026 uno::Any aAny
= mxExportInfo
->getPropertyValue(sRepeat
);
2027 if (aAny
.getValueType() == cppu::UnoType
<bool>::get())
2028 mpProgressBarHelper
->SetRepeat(::cppu::any2bool(aAny
));
2030 SAL_WARN("xmloff.core", "why is it no boolean?" );
2036 return mpProgressBarHelper
.get();
2039 XMLEventExport
& SvXMLExport::GetEventExport()
2041 if( nullptr == mpEventExport
)
2043 // create EventExport on demand
2044 mpEventExport
.reset( new XMLEventExport(*this) );
2046 // and register standard handlers + names
2047 mpEventExport
->AddHandler("StarBasic", std::make_unique
<XMLStarBasicExportHandler
>());
2048 mpEventExport
->AddHandler("Script", std::make_unique
<XMLScriptExportHandler
>());
2049 mpEventExport
->AddTranslationTable(aStandardEventTable
);
2052 return *mpEventExport
;
2055 XMLImageMapExport
& SvXMLExport::GetImageMapExport()
2057 // image map export, create on-demand
2058 if( nullptr == mpImageMapExport
)
2060 mpImageMapExport
.reset( new XMLImageMapExport(*this) );
2063 return *mpImageMapExport
;
2067 UNO3_GETIMPLEMENTATION_IMPL(SvXMLExport
);
2069 void SvXMLExport::ExportEmbeddedOwnObject( Reference
< XComponent
> const & rComp
)
2071 OUString sFilterService
;
2073 Reference
< lang::XServiceInfo
> xServiceInfo( rComp
, UNO_QUERY
);
2074 if( xServiceInfo
.is() )
2076 const XMLServiceMapEntry_Impl
*pEntry
= aServiceMap
;
2077 while( pEntry
->sModelService
)
2079 OUString
sModelService( pEntry
->sModelService
,
2080 pEntry
->nModelServiceLen
,
2081 RTL_TEXTENCODING_ASCII_US
);
2082 if( xServiceInfo
->supportsService( sModelService
) )
2084 sFilterService
= OUString( pEntry
->sFilterService
,
2085 pEntry
->nFilterServiceLen
,
2086 RTL_TEXTENCODING_ASCII_US
);
2093 SAL_WARN_IF( !sFilterService
.getLength(), "xmloff.core", "no export filter for own object" );
2095 if( sFilterService
.isEmpty() )
2098 Reference
< XDocumentHandler
> xHdl
=
2099 new XMLEmbeddedObjectExportFilter( mxHandler
);
2101 Sequence
< Any
> aArgs( 1 );
2104 Reference
< document::XExporter
> xExporter(
2105 m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService
, aArgs
, m_xContext
),
2107 SAL_WARN_IF( !xExporter
.is(), "xmloff.core", "can't instantiate export filter component for own object" );
2108 if( !xExporter
.is() )
2111 xExporter
->setSourceDocument( rComp
);
2113 Reference
<XFilter
> xFilter( xExporter
, UNO_QUERY
);
2115 Sequence
< PropertyValue
> aMediaDesc( 0 );
2116 xFilter
->filter( aMediaDesc
);
2119 OUString
SvXMLExport::GetRelativeReference(const OUString
& rValue
)
2121 OUString
sValue( rValue
);
2122 // #i65474# handling of fragment URLs ("#...") is undefined
2123 // they are stored 'as is'
2124 uno::Reference
< uri::XUriReference
> xUriRef
;
2125 if(!sValue
.isEmpty() && sValue
[0] != '#')
2129 xUriRef
= mpImpl
->mxUriReferenceFactory
->parse( rValue
);
2130 if( xUriRef
.is() && !xUriRef
->isAbsolute() )
2132 //#i61943# relative URLs need special handling
2133 INetURLObject
aTemp( mpImpl
->msPackageURI
);
2134 bool bWasAbsolute
= false;
2135 sValue
= aTemp
.smartRel2Abs(sValue
, bWasAbsolute
).GetMainURL(INetURLObject::DecodeMechanism::ToIUri
);
2138 catch(const uno::Exception
&)
2142 if( xUriRef
.is() )//no conversion for empty values or for fragments
2144 //conversion for matching schemes only
2145 if( xUriRef
->getScheme() == mpImpl
->msPackageURIScheme
)
2147 sValue
= INetURLObject::GetRelURL( msOrigFileName
, sValue
);
2153 void SvXMLExport::StartElement(sal_uInt16 nPrefix
,
2154 enum ::xmloff::token::XMLTokenEnum eName
,
2155 bool bIgnWSOutside
)
2157 StartElement(GetNamespaceMap_().GetQNameByKey( nPrefix
,
2158 GetXMLToken(eName
) ), bIgnWSOutside
);
2161 void SvXMLExport::StartElement(const OUString
& rName
,
2162 bool bIgnWSOutside
)
2164 if ((mnErrorFlags
& SvXMLErrorFlags::DO_NOTHING
) != SvXMLErrorFlags::DO_NOTHING
)
2168 if( bIgnWSOutside
&& ((mnExportFlags
& SvXMLExportFlags::PRETTY
) == SvXMLExportFlags::PRETTY
))
2169 mxHandler
->ignorableWhitespace( msWS
);
2170 mxHandler
->startElement( rName
, GetXAttrList() );
2172 catch (const SAXInvalidCharacterException
& e
)
2174 Sequence
<OUString
> aPars
{ rName
};
2175 SetError( XMLERROR_SAX
|XMLERROR_FLAG_WARNING
, aPars
, e
.Message
, nullptr );
2177 catch (const SAXException
& e
)
2179 Sequence
<OUString
> aPars
{ rName
};
2180 SetError( XMLERROR_SAX
|XMLERROR_FLAG_ERROR
|XMLERROR_FLAG_SEVERE
,
2181 aPars
, e
.Message
, nullptr );
2185 ++mpImpl
->mDepth
; // increment nesting depth counter
2188 void SvXMLExport::Characters(const OUString
& rChars
)
2190 if ((mnErrorFlags
& SvXMLErrorFlags::DO_NOTHING
) == SvXMLErrorFlags::DO_NOTHING
)
2195 mxHandler
->characters(rChars
);
2197 catch (const SAXInvalidCharacterException
& e
)
2199 Sequence
<OUString
> aPars
{ rChars
};
2200 SetError( XMLERROR_SAX
|XMLERROR_FLAG_WARNING
, aPars
, e
.Message
, nullptr );
2202 catch (const SAXException
& e
)
2204 Sequence
<OUString
> aPars
{ rChars
};
2205 SetError( XMLERROR_SAX
|XMLERROR_FLAG_ERROR
|XMLERROR_FLAG_SEVERE
,
2206 aPars
, e
.Message
, nullptr );
2210 void SvXMLExport::EndElement(sal_uInt16 nPrefix
,
2211 enum ::xmloff::token::XMLTokenEnum eName
,
2214 EndElement(GetNamespaceMap_().GetQNameByKey( nPrefix
, GetXMLToken(eName
) ),
2218 void SvXMLExport::EndElement(const OUString
& rName
,
2221 // decrement nesting depth counter & (maybe) restore namespace map
2223 if (!mpImpl
->mNamespaceMaps
.empty() &&
2224 (mpImpl
->mNamespaceMaps
.top().second
== mpImpl
->mDepth
))
2226 mpNamespaceMap
= std::move(mpImpl
->mNamespaceMaps
.top().first
);
2227 mpImpl
->mNamespaceMaps
.pop();
2229 SAL_WARN_IF(!mpImpl
->mNamespaceMaps
.empty() &&
2230 (mpImpl
->mNamespaceMaps
.top().second
>= mpImpl
->mDepth
), "xmloff.core", "SvXMLExport: NamespaceMaps corrupted");
2232 if ((mnErrorFlags
& SvXMLErrorFlags::DO_NOTHING
) == SvXMLErrorFlags::DO_NOTHING
)
2237 if( bIgnWSInside
&& ((mnExportFlags
& SvXMLExportFlags::PRETTY
) == SvXMLExportFlags::PRETTY
))
2238 mxHandler
->ignorableWhitespace( msWS
);
2239 mxHandler
->endElement( rName
);
2241 catch (const SAXException
& e
)
2243 Sequence
<OUString
> aPars
{ rName
};
2244 SetError( XMLERROR_SAX
|XMLERROR_FLAG_ERROR
|XMLERROR_FLAG_SEVERE
,
2245 aPars
, e
.Message
, nullptr );
2249 void SvXMLExport::IgnorableWhitespace()
2251 if ((mnExportFlags
& SvXMLExportFlags::PRETTY
) != SvXMLExportFlags::PRETTY
)
2254 if ((mnErrorFlags
& SvXMLErrorFlags::DO_NOTHING
) == SvXMLErrorFlags::DO_NOTHING
)
2259 mxHandler
->ignorableWhitespace( msWS
);
2261 catch (const SAXException
& e
)
2263 Sequence
<OUString
> aPars(0);
2264 SetError( XMLERROR_SAX
|XMLERROR_FLAG_ERROR
|XMLERROR_FLAG_SEVERE
,
2265 aPars
, e
.Message
, nullptr );
2269 void SvXMLExport::SetError(
2271 const Sequence
<OUString
>& rMsgParams
,
2272 const OUString
& rExceptionMessage
,
2273 const Reference
<XLocator
>& rLocator
)
2275 // allow multi-threaded access to the cancel() method
2276 static osl::Mutex aMutex
;
2277 osl::MutexGuard
aGuard(aMutex
);
2279 // maintain error flags
2280 if ( ( nId
& XMLERROR_FLAG_ERROR
) != 0 )
2281 mnErrorFlags
|= SvXMLErrorFlags::ERROR_OCCURRED
;
2282 if ( ( nId
& XMLERROR_FLAG_WARNING
) != 0 )
2283 mnErrorFlags
|= SvXMLErrorFlags::WARNING_OCCURRED
;
2284 if ( ( nId
& XMLERROR_FLAG_SEVERE
) != 0 )
2285 mnErrorFlags
|= SvXMLErrorFlags::DO_NOTHING
;
2287 // create error list on demand
2288 if ( mpXMLErrors
== nullptr )
2289 mpXMLErrors
.reset( new XMLErrors() );
2291 // save error information
2292 mpXMLErrors
->AddRecord( nId
, rMsgParams
, rExceptionMessage
, rLocator
);
2295 void SvXMLExport::SetError(
2297 const Sequence
<OUString
>& rMsgParams
)
2299 SetError( nId
, rMsgParams
, "", nullptr );
2302 void SvXMLExport::DisposingModel()
2305 // Shapes in Writer cannot be named via context menu (#i51726#)
2306 meModelType
= SvtModuleOptions::EFactory::UNKNOWN_FACTORY
;
2307 mxEventListener
.clear();
2311 ::comphelper::UnoInterfaceToUniqueIdentifierMapper
& SvXMLExport::getInterfaceToIdentifierMapper()
2313 return mpImpl
->maInterfaceToIdentifierMapper
;
2316 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
2317 bool SvXMLExport::writeOutlineStyleAsNormalListStyle() const
2319 return mpImpl
->mbOutlineStyleAsNormalListStyle
;
2322 uno::Reference
< embed::XStorage
> const & SvXMLExport::GetTargetStorage() const
2324 return mpImpl
->mxTargetStorage
;
2327 SvtSaveOptions::ODFSaneDefaultVersion
SvXMLExport::getSaneDefaultVersion() const
2329 if (mpImpl
->m_oOverrideODFVersion
)
2331 return *mpImpl
->m_oOverrideODFVersion
;
2333 return mpImpl
->maSaveOptions
.GetODFSaneDefaultVersion();
2337 SvXMLExport::AddAttributeIdLegacy(
2338 sal_uInt16
const nLegacyPrefix
, OUString
const& rValue
)
2340 switch (getSaneDefaultVersion()) {
2341 case SvtSaveOptions::ODFSVER_011
: // fall through
2342 case SvtSaveOptions::ODFSVER_010
: break;
2343 default: // ODF 1.2: xml:id
2344 AddAttribute(XML_NAMESPACE_XML
, XML_ID
, rValue
);
2346 // in ODF 1.1 this was form:id, anim:id, draw:id, or text:id
2347 // backward compatibility: in ODF 1.2 write _both_ id attrs
2348 AddAttribute(nLegacyPrefix
, XML_ID
, rValue
);
2349 // FIXME: this function simply assumes that rValue is unique
2353 SvXMLExport::AddAttributeXmlId(uno::Reference
<uno::XInterface
> const & i_xIfc
)
2355 // check version >= 1.2
2356 switch (getSaneDefaultVersion()) {
2357 case SvtSaveOptions::ODFSVER_011
: // fall through
2358 case SvtSaveOptions::ODFSVER_010
: return;
2361 const uno::Reference
<rdf::XMetadatable
> xMeta(i_xIfc
,
2367 const beans::StringPair
mdref( xMeta
->getMetadataReference() );
2368 if ( mdref
.Second
.isEmpty() )
2371 const OUString streamName
= mpImpl
->mStreamName
;
2372 if ( !streamName
.isEmpty() )
2374 if ( streamName
== mdref
.First
)
2376 AddAttribute( XML_NAMESPACE_XML
, XML_ID
, mdref
.Second
);
2380 SAL_WARN("xmloff.core","SvXMLExport::AddAttributeXmlId: invalid stream name");
2385 // FIXME: this is ugly
2386 // there is no stream name (e.g. XSLT, flat-xml format)!
2387 // but how do we ensure uniqueness in this case?
2388 // a) just omit styles.xml ids -- they are unlikely anyway...
2389 // b) somehow find out whether we are currently exporting styles
2390 // or content, and prefix "s" or "c" => unique
2391 if ( mdref
.First
== "content.xml" )
2393 AddAttribute( XML_NAMESPACE_XML
, XML_ID
, mdref
.Second
);
2397 SAL_INFO("xmloff.core", "SvXMLExport::AddAttributeXmlId: no stream name given: dropping styles.xml xml:id");
2403 SvXMLExport::AddAttributesRDFa(
2404 uno::Reference
<text::XTextContent
> const & i_xTextContent
)
2406 // check version >= 1.2
2407 switch (getSaneDefaultVersion()) {
2408 case SvtSaveOptions::ODFSVER_011
: // fall through
2409 case SvtSaveOptions::ODFSVER_010
: return;
2413 const uno::Reference
<rdf::XMetadatable
> xMeta(
2414 i_xTextContent
, uno::UNO_QUERY
);
2415 if (!xMeta
.is() || xMeta
->getMetadataReference().Second
.isEmpty())
2417 return; // no xml:id => no RDFa
2420 if (!mpImpl
->mpRDFaHelper
)
2422 mpImpl
->mpRDFaHelper
.reset( new ::xmloff::RDFaExportHelper(*this) );
2424 mpImpl
->mpRDFaHelper
->AddRDFa(xMeta
);
2427 bool SvXMLExport::exportTextNumberElement() const
2429 return mpImpl
->mbExportTextNumberElement
;
2432 bool SvXMLExport::SetNullDateOnUnitConverter()
2434 // if the null date has already been set, don't set it again (performance)
2435 if (!mpImpl
->mbNullDateInitialized
)
2436 mpImpl
->mbNullDateInitialized
= GetMM100UnitConverter().setNullDate(GetModel());
2438 return mpImpl
->mbNullDateInitialized
;
2441 OUString
const & SvXMLExport::GetImageFilterName() const
2443 return msImgFilterName
;
2446 void SvXMLElementExport::StartElement(
2447 const sal_uInt16 nPrefixKey
,
2448 const OUString
& rLName
,
2449 const bool bIgnoreWhitespaceOutside
)
2451 maElementName
= mrExport
.GetNamespaceMap().GetQNameByKey(nPrefixKey
, rLName
);
2452 mrExport
.StartElement(maElementName
, bIgnoreWhitespaceOutside
);
2455 SvXMLElementExport::SvXMLElementExport(
2457 sal_uInt16 nPrefixKey
,
2463 , mbIgnoreWhitespaceInside( bIWSInside
)
2464 , mbDoSomething( true )
2466 const OUString
sLName( OUString::createFromAscii( pLName
) );
2467 StartElement( nPrefixKey
, sLName
, bIWSOutside
);
2470 SvXMLElementExport::SvXMLElementExport(
2472 sal_uInt16 nPrefixKey
,
2473 const OUString
& rLName
,
2478 , mbIgnoreWhitespaceInside( bIWSInside
)
2479 , mbDoSomething( true )
2481 StartElement( nPrefixKey
, rLName
, bIWSOutside
);
2484 SvXMLElementExport::SvXMLElementExport(
2486 sal_uInt16 nPrefixKey
,
2487 enum XMLTokenEnum eLName
,
2492 , mbIgnoreWhitespaceInside( bIWSInside
)
2493 , mbDoSomething( true )
2495 StartElement( nPrefixKey
, GetXMLToken(eLName
), bIWSOutside
);
2498 SvXMLElementExport::SvXMLElementExport(
2501 sal_uInt16 nPrefixKey
,
2502 enum XMLTokenEnum eLName
,
2507 , mbIgnoreWhitespaceInside( bIWSInside
)
2508 , mbDoSomething( bDoSth
)
2510 if ( mbDoSomething
)
2511 StartElement( nPrefixKey
, GetXMLToken( eLName
), bIWSOutside
);
2514 SvXMLElementExport::SvXMLElementExport(
2516 const OUString
& rQName
,
2521 , mbIgnoreWhitespaceInside( bIWSInside
)
2522 , mbDoSomething( true )
2524 maElementName
= rQName
;
2525 rExp
.StartElement( rQName
, bIWSOutside
);
2528 SvXMLElementExport::~SvXMLElementExport()
2530 if ( mbDoSomething
)
2532 mrExport
.EndElement( maElementName
, mbIgnoreWhitespaceInside
);
2536 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */