Update git submodules
[LibreOffice.git] / xmloff / source / core / xmlexp.cxx
blob2cec3eb32f89c56442a076063fe1465b94333def
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_wasm_strip.h>
22 #include <memory>
23 #include <sal/config.h>
24 #include <sal/log.hxx>
26 #include <mutex>
27 #include <stack>
28 #include <optional>
29 #include <utility>
31 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
32 #include <tools/urlobj.hxx>
33 #include <vcl/graph.hxx>
34 #include <comphelper/genericpropertyset.hxx>
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include <com/sun/star/io/XInputStream.hpp>
37 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
38 #include <com/sun/star/text/XTextContent.hpp>
39 #include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp>
40 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
41 #include <com/sun/star/uri/UriReferenceFactory.hpp>
42 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
43 #include <com/sun/star/util/MeasureUnit.hpp>
44 #include <i18nlangtag/languagetag.hxx>
45 #include <comphelper/processfactory.hxx>
46 #include <comphelper/propertysetinfo.hxx>
47 #include <comphelper/propertyvalue.hxx>
48 #include <xmloff/namespacemap.hxx>
49 #include <xmloff/xmluconv.hxx>
50 #include <xmloff/xmlnamespace.hxx>
51 #include <xmloff/xmltoken.hxx>
52 #include <xmloff/xmlexp.hxx>
53 #include <xmloff/xmlnumfe.hxx>
54 #include <xmloff/xmlmetae.hxx>
55 #include <xmloff/XMLSettingsExportContext.hxx>
56 #include <xmloff/XMLEventExport.hxx>
57 #include <xmloff/ProgressBarHelper.hxx>
58 #include <XMLStarBasicExportHandler.hxx>
59 #include <XMLScriptExportHandler.hxx>
60 #include <xmloff/SettingsExportHelper.hxx>
61 #include <com/sun/star/document/XEventsSupplier.hpp>
62 #include <com/sun/star/document/XViewDataSupplier.hpp>
63 #include <com/sun/star/frame/XModel.hpp>
64 #include <com/sun/star/frame/XModule.hpp>
65 #include <xmloff/GradientStyle.hxx>
66 #include <xmloff/HatchStyle.hxx>
67 #include <xmloff/ImageStyle.hxx>
68 #include <TransGradientStyle.hxx>
69 #include <xmloff/MarkerStyle.hxx>
70 #include <xmloff/DashStyle.hxx>
71 #include <xmloff/XMLFontAutoStylePool.hxx>
72 #include <XMLImageMapExport.hxx>
73 #include <XMLBase64Export.hxx>
74 #include <xmloff/xmlerror.hxx>
75 #include <com/sun/star/style/XStyle.hpp>
76 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
77 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
78 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
79 #include <com/sun/star/beans/PropertyAttribute.hpp>
80 #include <xmloff/XMLFilterServiceNames.h>
81 #include <XMLEmbeddedObjectExportFilter.hxx>
82 #include <XMLBasicExportFilter.hxx>
83 #include <cppuhelper/exc_hlp.hxx>
84 #include <cppuhelper/implbase.hxx>
85 #include <cppuhelper/supportsservice.hxx>
86 #include <comphelper/extract.hxx>
87 #include <comphelper/SetFlagContextHelper.hxx>
88 #include <PropertySetMerger.hxx>
89 #include <docmodel/theme/Theme.hxx>
90 #include <o3tl/enumrange.hxx>
91 #include <sax/tools/converter.hxx>
93 #include <unotools/docinfohelper.hxx>
94 #include <com/sun/star/document/XDocumentProperties.hpp>
95 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
96 #include <com/sun/star/document/XMLOasisBasicExporter.hpp>
97 #include <com/sun/star/embed/XEncryptionProtectedStorage.hpp>
98 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
99 #include <com/sun/star/rdf/XMetadatable.hpp>
100 #include <RDFaExportHelper.hxx>
102 #include <comphelper/xmltools.hxx>
103 #include <comphelper/graphicmimetype.hxx>
105 using namespace ::com::sun::star;
106 using namespace ::com::sun::star::uno;
107 using namespace ::com::sun::star::frame;
108 using namespace ::com::sun::star::container;
109 using namespace ::com::sun::star::lang;
110 using namespace ::com::sun::star::document;
111 using namespace ::com::sun::star::beans;
112 using namespace ::com::sun::star::xml::sax;
113 using namespace ::com::sun::star::io;
114 using namespace ::xmloff::token;
116 constexpr OUString XML_MODEL_SERVICE_WRITER = u"com.sun.star.text.TextDocument"_ustr;
117 constexpr OUString XML_MODEL_SERVICE_CALC = u"com.sun.star.sheet.SpreadsheetDocument"_ustr;
118 constexpr OUString XML_MODEL_SERVICE_DRAW = u"com.sun.star.drawing.DrawingDocument"_ustr;
119 constexpr OUString XML_MODEL_SERVICE_IMPRESS = u"com.sun.star.presentation.PresentationDocument"_ustr;
120 constexpr OUString XML_MODEL_SERVICE_MATH = u"com.sun.star.formula.FormulaProperties"_ustr;
121 constexpr OUString XML_MODEL_SERVICE_CHART = u"com.sun.star.chart.ChartDocument"_ustr;
123 constexpr OUStringLiteral XML_USEPRETTYPRINTING = u"UsePrettyPrinting";
125 constexpr OUString XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE = u"vnd.sun.star.GraphicObject:"_ustr;
126 constexpr OUString XML_EMBEDDEDOBJECT_URL_BASE = u"vnd.sun.star.EmbeddedObject:"_ustr;
128 const std::pair<OUString, OUString> aServiceMap[] = {
129 { XML_MODEL_SERVICE_WRITER, XML_EXPORT_FILTER_WRITER },
130 { XML_MODEL_SERVICE_CALC, XML_EXPORT_FILTER_CALC },
131 { XML_MODEL_SERVICE_IMPRESS, XML_EXPORT_FILTER_IMPRESS }, // Impress supports DrawingDocument,
132 { XML_MODEL_SERVICE_DRAW, XML_EXPORT_FILTER_DRAW }, // too, so it must appear before Draw
133 { XML_MODEL_SERVICE_MATH, XML_EXPORT_FILTER_MATH },
134 { XML_MODEL_SERVICE_CHART, XML_EXPORT_FILTER_CHART },
137 namespace {
139 class SettingsExportFacade : public ::xmloff::XMLSettingsExportContext
141 public:
142 explicit SettingsExportFacade( SvXMLExport& i_rExport )
143 :m_rExport( i_rExport )
147 virtual ~SettingsExportFacade()
151 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
152 const OUString& i_rValue ) override;
153 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
154 enum ::xmloff::token::XMLTokenEnum i_eValue ) override;
156 virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName ) override;
157 virtual void EndElement( const bool i_bIgnoreWhitespace ) override;
159 virtual void Characters( const OUString& i_rCharacters ) override;
161 virtual css::uno::Reference< css::uno::XComponentContext >
162 GetComponentContext() const override;
163 private:
164 SvXMLExport& m_rExport;
165 ::std::stack< OUString > m_aElements;
170 void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const OUString& i_rValue )
172 m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_rValue );
175 void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue )
177 m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_eValue );
180 void SettingsExportFacade::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName )
182 const OUString sElementName( m_rExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_CONFIG, GetXMLToken( i_eName ) ) );
183 m_rExport.StartElement( sElementName, true/*i_bIgnoreWhitespace*/ );
184 m_aElements.push( sElementName );
187 void SettingsExportFacade::EndElement( const bool i_bIgnoreWhitespace )
189 const OUString sElementName( m_aElements.top() );
190 m_rExport.EndElement( sElementName, i_bIgnoreWhitespace );
191 m_aElements.pop();
194 void SettingsExportFacade::Characters( const OUString& i_rCharacters )
196 m_rExport.GetDocHandler()->characters( i_rCharacters );
199 Reference< XComponentContext > SettingsExportFacade::GetComponentContext() const
201 return m_rExport.getComponentContext();
204 namespace {
206 class SvXMLExportEventListener : public cppu::WeakImplHelper<
207 css::lang::XEventListener >
209 private:
210 SvXMLExport* pExport;
212 public:
213 explicit SvXMLExportEventListener(SvXMLExport* pExport);
215 // XEventListener
216 virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
221 SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport* pTempExport)
222 : pExport(pTempExport)
226 // XEventListener
227 void SAL_CALL SvXMLExportEventListener::disposing( const lang::EventObject& )
229 if (pExport)
231 pExport->DisposingModel();
232 pExport = nullptr;
236 class SvXMLExport_Impl
238 public:
239 SvXMLExport_Impl();
241 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper;
242 uno::Reference< uri::XUriReferenceFactory > mxUriReferenceFactory;
243 OUString msPackageURI;
244 OUString msPackageURIScheme;
245 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
246 bool mbOutlineStyleAsNormalListStyle;
248 uno::Reference< embed::XStorage > mxTargetStorage;
250 std::optional<SvtSaveOptions::ODFSaneDefaultVersion> m_oODFVersion;
252 /// name of stream in package, e.g., "content.xml"
253 OUString mStreamName;
255 OUString maSrcShellID;
256 OUString maDestShellID;
258 /// stack of backed up namespace maps
259 /// long: depth at which namespace map has been backed up into the stack
260 ::std::stack< ::std::pair< std::unique_ptr<SvXMLNamespaceMap>, tools::Long > > mNamespaceMaps;
261 /// counts depth (number of open elements/start tags)
262 tools::Long mDepth;
264 ::std::unique_ptr< ::xmloff::RDFaExportHelper> mpRDFaHelper;
266 bool mbExportTextNumberElement;
267 bool mbNullDateInitialized;
269 void SetSchemeOf( std::u16string_view rOrigFileName )
271 size_t nSep = rOrigFileName.find(':');
272 if( nSep != std::u16string_view::npos )
273 msPackageURIScheme = rOrigFileName.substr( 0, nSep );
277 SvXMLExport_Impl::SvXMLExport_Impl()
278 : mxUriReferenceFactory( uri::UriReferenceFactory::create(comphelper::getProcessComponentContext()) ),
279 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
280 mbOutlineStyleAsNormalListStyle( false ),
281 mDepth( 0 ),
282 mbExportTextNumberElement( false ),
283 mbNullDateInitialized( false )
287 void SvXMLExport::SetDocHandler( const uno::Reference< xml::sax::XDocumentHandler > &rHandler )
289 mxHandler = rHandler;
290 mxExtHandler.set( mxHandler, UNO_QUERY );
293 void SvXMLExport::InitCtor_()
295 // note: it is not necessary to add XML_NP_XML (it is declared implicitly)
296 if( getExportFlags() & ~SvXMLExportFlags::OASIS )
298 mpNamespaceMap->Add( GetXMLToken(XML_NP_OFFICE), GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
299 mpNamespaceMap->Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
301 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS) )
303 mpNamespaceMap->Add( GetXMLToken(XML_NP_FO), GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
305 if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::SETTINGS) )
307 mpNamespaceMap->Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
309 if( getExportFlags() & SvXMLExportFlags::SETTINGS )
311 mpNamespaceMap->Add( GetXMLToken(XML_NP_CONFIG), GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
314 if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
316 mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
317 mpNamespaceMap->Add( GetXMLToken(XML_NP_META), GetXMLToken(XML_N_META), XML_NAMESPACE_META );
319 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::FONTDECLS) )
321 mpNamespaceMap->Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
324 // namespaces for documents
325 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
327 mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
328 mpNamespaceMap->Add( GetXMLToken(XML_NP_TEXT), GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT );
329 mpNamespaceMap->Add( GetXMLToken(XML_NP_DRAW), GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW );
330 mpNamespaceMap->Add( GetXMLToken(XML_NP_DR3D), GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D );
331 mpNamespaceMap->Add( GetXMLToken(XML_NP_SVG), GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG );
332 mpNamespaceMap->Add( GetXMLToken(XML_NP_CHART), GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART );
333 mpNamespaceMap->Add( GetXMLToken(XML_NP_RPT), GetXMLToken(XML_N_RPT), XML_NAMESPACE_REPORT );
334 mpNamespaceMap->Add( GetXMLToken(XML_NP_TABLE), GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE );
335 mpNamespaceMap->Add( GetXMLToken(XML_NP_NUMBER),GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER );
336 mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOW), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
337 mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOC), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
338 mpNamespaceMap->Add( GetXMLToken(XML_NP_OF), GetXMLToken(XML_N_OF), XML_NAMESPACE_OF );
340 if (getSaneDefaultVersion() & SvtSaveOptions::ODFSVER_EXTENDED)
342 mpNamespaceMap->Add(
343 GetXMLToken(XML_NP_TABLE_EXT), GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT);
344 mpNamespaceMap->Add(
345 GetXMLToken(XML_NP_CALC_EXT), GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT);
346 mpNamespaceMap->Add(
347 GetXMLToken(XML_NP_DRAW_EXT), GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT);
348 mpNamespaceMap->Add(
349 GetXMLToken(XML_NP_LO_EXT), GetXMLToken(XML_N_LO_EXT),
350 XML_NAMESPACE_LO_EXT);
351 mpNamespaceMap->Add( GetXMLToken(XML_NP_FIELD), GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD );
354 if( getExportFlags() & (SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
356 mpNamespaceMap->Add( GetXMLToken(XML_NP_MATH), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
357 mpNamespaceMap->Add( GetXMLToken(XML_NP_FORM), GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM );
359 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS) )
361 mpNamespaceMap->Add( GetXMLToken(XML_NP_SCRIPT), GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT );
362 mpNamespaceMap->Add( GetXMLToken(XML_NP_DOM), GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
364 if( getExportFlags() & SvXMLExportFlags::CONTENT )
366 mpNamespaceMap->Add( GetXMLToken(XML_NP_XFORMS_1_0), GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS );
367 mpNamespaceMap->Add( GetXMLToken(XML_NP_XSD), GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD );
368 mpNamespaceMap->Add( GetXMLToken(XML_NP_XSI), GetXMLToken(XML_N_XSI), XML_NAMESPACE_XSI );
369 mpNamespaceMap->Add( GetXMLToken(XML_NP_FORMX), GetXMLToken(XML_N_FORMX), XML_NAMESPACE_FORMX );
372 // RDFa: needed for content and header/footer styles
373 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
375 mpNamespaceMap->Add( GetXMLToken(XML_NP_XHTML),
376 GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML );
378 // GRDDL: to convert RDFa and meta.xml to RDF
379 if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
381 mpNamespaceMap->Add( GetXMLToken(XML_NP_GRDDL),
382 GetXMLToken(XML_N_GRDDL), XML_NAMESPACE_GRDDL );
384 // CSS Text Level 3 for distributed text justification.
385 if ( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES) )
387 mpNamespaceMap->Add(
388 GetXMLToken(XML_NP_CSS3TEXT), GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT );
391 if (mxModel.is() && !mxEventListener.is())
393 mxEventListener.set( new SvXMLExportEventListener(this));
394 mxModel->addEventListener(mxEventListener);
397 // Determine model type (#i51726#)
398 DetermineModelType_();
401 // Shapes in Writer cannot be named via context menu (#i51726#)
402 void SvXMLExport::DetermineModelType_()
404 meModelType = SvtModuleOptions::EFactory::UNKNOWN_FACTORY;
406 if ( !mxModel.is() )
407 return;
409 meModelType = SvtModuleOptions::ClassifyFactoryByModel( mxModel );
411 // note: MATH documents will throw NotInitializedException; maybe unit test problem
412 if (meModelType == SvtModuleOptions::EFactory::WRITER)
414 uno::Reference<frame::XModule> const xModule(mxModel, uno::UNO_QUERY);
415 bool const isBaseForm(xModule.is() &&
416 xModule->getIdentifier() == "com.sun.star.sdb.FormDesign");
417 if (isBaseForm)
419 switch (GetODFSaneDefaultVersion())
421 case SvtSaveOptions::ODFSVER_013_EXTENDED:
422 SAL_INFO("xmloff.core", "tdf#138209 force form export to ODF 1.2");
423 mpImpl->m_oODFVersion = SvtSaveOptions::ODFSVER_012_EXTENDED;
424 maUnitConv.overrideSaneDefaultVersion(SvtSaveOptions::ODFSVER_012_EXTENDED);
425 break;
426 case SvtSaveOptions::ODFSVER_013:
427 SAL_INFO("xmloff.core", "tdf#138209 force form export to ODF 1.2");
428 mpImpl->m_oODFVersion = SvtSaveOptions::ODFSVER_012;
429 maUnitConv.overrideSaneDefaultVersion(SvtSaveOptions::ODFSVER_012);
430 break;
431 default:
432 break;
438 SvXMLExport::SvXMLExport(
439 const uno::Reference< uno::XComponentContext >& xContext,
440 OUString implementationName,
441 sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/,
442 const enum XMLTokenEnum eClass, SvXMLExportFlags nExportFlags )
443 : mpImpl( new SvXMLExport_Impl ),
444 m_xContext(xContext), m_implementationName(std::move(implementationName)),
445 mxAttrList( new comphelper::AttributeList ),
446 mpNamespaceMap( new SvXMLNamespaceMap ),
447 mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
448 maUnitConv(xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit, getSaneDefaultVersion()),
449 meClass( eClass ),
450 mnExportFlags( nExportFlags ),
451 mnErrorFlags( SvXMLErrorFlags::NO ),
452 msWS( GetXMLToken(XML_WS) ),
453 mbSaveLinkedSections(true),
454 mbAutoStylesCollected(false)
456 SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" );
457 InitCtor_();
460 SvXMLExport::SvXMLExport(
461 const css::uno::Reference< css::uno::XComponentContext >& xContext,
462 OUString implementationName,
463 OUString fileName,
464 sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/,
465 const uno::Reference< xml::sax::XDocumentHandler > & rHandler)
466 : mpImpl( new SvXMLExport_Impl ),
467 m_xContext(xContext), m_implementationName(std::move(implementationName)),
468 mxHandler( rHandler ),
469 mxExtHandler( rHandler, uno::UNO_QUERY ),
470 mxAttrList( new comphelper::AttributeList ),
471 msOrigFileName(std::move( fileName )),
472 mpNamespaceMap( new SvXMLNamespaceMap ),
473 mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
474 maUnitConv(xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit, getSaneDefaultVersion()),
475 meClass( XML_TOKEN_INVALID ),
476 mnExportFlags( SvXMLExportFlags::NONE ),
477 mnErrorFlags( SvXMLErrorFlags::NO ),
478 msWS( GetXMLToken(XML_WS) ),
479 mbSaveLinkedSections(true),
480 mbAutoStylesCollected(false)
482 SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" );
483 mpImpl->SetSchemeOf( msOrigFileName );
484 InitCtor_();
486 if (mxNumberFormatsSupplier.is())
487 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
490 SvXMLExport::SvXMLExport(
491 const css::uno::Reference< css::uno::XComponentContext >& xContext,
492 OUString implementationName,
493 OUString fileName,
494 const uno::Reference< xml::sax::XDocumentHandler > & rHandler,
495 const Reference< XModel >& rModel,
496 FieldUnit const eDefaultFieldUnit,
497 SvXMLExportFlags nExportFlag)
498 : mpImpl( new SvXMLExport_Impl ),
499 m_xContext(xContext), m_implementationName(std::move(implementationName)),
500 mxModel( rModel ),
501 mxHandler( rHandler ),
502 mxExtHandler( rHandler, uno::UNO_QUERY ),
503 mxNumberFormatsSupplier (rModel, uno::UNO_QUERY),
504 mxAttrList( new comphelper::AttributeList ),
505 msOrigFileName(std::move( fileName )),
506 mpNamespaceMap( new SvXMLNamespaceMap ),
507 mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
508 maUnitConv( xContext,
509 util::MeasureUnit::MM_100TH,
510 SvXMLUnitConverter::GetMeasureUnit(eDefaultFieldUnit),
511 getSaneDefaultVersion()),
512 meClass( XML_TOKEN_INVALID ),
513 mnExportFlags( nExportFlag ),
514 mnErrorFlags( SvXMLErrorFlags::NO ),
515 msWS( GetXMLToken(XML_WS) ),
516 mbSaveLinkedSections(true),
517 mbAutoStylesCollected(false)
519 SAL_WARN_IF(!xContext.is(), "xmloff.core", "got no service manager" );
520 mpImpl->SetSchemeOf( msOrigFileName );
521 InitCtor_();
523 if (mxNumberFormatsSupplier.is())
524 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
527 SvXMLExport::~SvXMLExport()
529 mpXMLErrors.reset();
530 mpImageMapExport.reset();
531 mpEventExport.reset();
532 mpNamespaceMap.reset();
533 if (mpProgressBarHelper || mpNumExport)
535 if (mxExportInfo.is())
537 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
538 if (xPropertySetInfo.is())
540 if (mpProgressBarHelper)
542 static constexpr OUString sProgressMax(XML_PROGRESSMAX);
543 static constexpr OUString sProgressCurrent(XML_PROGRESSCURRENT);
544 static constexpr OUString sRepeat(XML_PROGRESSREPEAT);
545 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
546 xPropertySetInfo->hasPropertyByName(sProgressCurrent))
548 sal_Int32 nProgressMax(mpProgressBarHelper->GetReference());
549 sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue());
550 mxExportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax));
551 mxExportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent));
553 if (xPropertySetInfo->hasPropertyByName(sRepeat))
554 mxExportInfo->setPropertyValue(sRepeat, css::uno::Any(mpProgressBarHelper->GetRepeat()));
556 if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES)))
558 static constexpr OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES);
559 if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats))
561 mxExportInfo->setPropertyValue(sWrittenNumberFormats, Any(mpNumExport->GetWasUsed()));
566 mpProgressBarHelper.reset();
567 mpNumExport.reset();
570 if (mxEventListener.is() && mxModel.is())
571 mxModel->removeEventListener(mxEventListener);
574 // XExporter
575 void SAL_CALL SvXMLExport::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
577 mxModel.set( xDoc, UNO_QUERY );
578 if( !mxModel.is() )
579 throw lang::IllegalArgumentException();
580 if (mxModel.is() && ! mxEventListener.is())
582 mxEventListener.set( new SvXMLExportEventListener(this));
583 mxModel->addEventListener(mxEventListener);
586 if(!mxNumberFormatsSupplier.is() )
588 mxNumberFormatsSupplier.set(mxModel, css::uno::UNO_QUERY);
589 if(mxNumberFormatsSupplier.is() && mxHandler.is())
590 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
592 if (mxExportInfo.is())
594 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
595 if (xPropertySetInfo.is())
597 OUString sUsePrettyPrinting(XML_USEPRETTYPRINTING);
598 if (xPropertySetInfo->hasPropertyByName(sUsePrettyPrinting))
600 uno::Any aAny = mxExportInfo->getPropertyValue(sUsePrettyPrinting);
601 if (::cppu::any2bool(aAny))
602 mnExportFlags |= SvXMLExportFlags::PRETTY;
603 else
604 mnExportFlags &= ~SvXMLExportFlags::PRETTY;
607 if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES)))
609 OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES);
610 if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats))
612 uno::Any aAny = mxExportInfo->getPropertyValue(sWrittenNumberFormats);
613 uno::Sequence<sal_Int32> aWasUsed;
614 if(aAny >>= aWasUsed)
615 mpNumExport->SetWasUsed(aWasUsed);
621 // namespaces for user defined attributes
622 Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
623 if( xFactory.is() )
627 Reference < XInterface > xIfc =
628 xFactory->createInstance(u"com.sun.star.xml.NamespaceMap"_ustr);
629 if( xIfc.is() )
631 Reference< XNameAccess > xNamespaceMap( xIfc, UNO_QUERY );
632 if( xNamespaceMap.is() )
634 const Sequence< OUString > aPrefixes( xNamespaceMap->getElementNames() );
635 for( OUString const & prefix : aPrefixes )
637 OUString aURL;
638 if( xNamespaceMap->getByName( prefix ) >>= aURL )
639 GetNamespaceMap_().Add( prefix, aURL );
644 catch(const css::uno::Exception&)
649 // Determine model type (#i51726#)
650 DetermineModelType_();
653 // XInitialize
654 void SAL_CALL SvXMLExport::initialize( const uno::Sequence< uno::Any >& aArguments )
656 // #93186# we need to queryInterface every single Any with any expected outcome. This variable hold the queryInterface results.
658 for( const auto& rAny : aArguments )
660 Reference<XInterface> xValue;
661 rAny >>= xValue;
663 // status indicator
664 uno::Reference<task::XStatusIndicator> xTmpStatus( xValue, UNO_QUERY );
665 if ( xTmpStatus.is() )
666 mxStatusIndicator = std::move(xTmpStatus);
668 // graphic storage handler
669 uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY);
670 if (xGraphicStorageHandler.is())
671 mxGraphicStorageHandler = std::move(xGraphicStorageHandler);
673 // object resolver
674 uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
675 xValue, UNO_QUERY );
676 if ( xTmpObjectResolver.is() )
677 mxEmbeddedResolver = std::move(xTmpObjectResolver);
679 // document handler
680 uno::Reference<xml::sax::XDocumentHandler> xTmpDocHandler(
681 xValue, UNO_QUERY );
682 if( xTmpDocHandler.is() )
684 mxHandler = std::move(xTmpDocHandler);
685 rAny >>= mxExtHandler;
687 if (mxNumberFormatsSupplier.is() && mpNumExport == nullptr)
688 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
691 // property set to transport data across
692 uno::Reference<beans::XPropertySet> xTmpPropertySet(
693 xValue, UNO_QUERY );
694 if( xTmpPropertySet.is() )
695 mxExportInfo = std::move(xTmpPropertySet);
698 if( !mxExportInfo.is() )
699 return;
701 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
702 mxExportInfo->getPropertySetInfo();
703 static constexpr OUString sBaseURI = u"BaseURI"_ustr;
704 if( xPropertySetInfo->hasPropertyByName(sBaseURI) )
706 uno::Any aAny = mxExportInfo->getPropertyValue(sBaseURI);
707 aAny >>= msOrigFileName;
708 mpImpl->msPackageURI = msOrigFileName;
709 mpImpl->SetSchemeOf( msOrigFileName );
711 OUString sRelPath;
712 static constexpr OUString sStreamRelPath = u"StreamRelPath"_ustr;
713 if( xPropertySetInfo->hasPropertyByName(sStreamRelPath) )
715 uno::Any aAny = mxExportInfo->getPropertyValue(sStreamRelPath);
716 aAny >>= sRelPath;
718 OUString sName;
719 static constexpr OUString sStreamName = u"StreamName"_ustr;
720 if( xPropertySetInfo->hasPropertyByName(sStreamName) )
722 uno::Any aAny = mxExportInfo->getPropertyValue(sStreamName);
723 aAny >>= sName;
725 if( !msOrigFileName.isEmpty() && !sName.isEmpty() )
727 INetURLObject aBaseURL( msOrigFileName );
728 if( !sRelPath.isEmpty() )
729 aBaseURL.insertName( sRelPath );
730 aBaseURL.insertName( sName );
731 msOrigFileName = aBaseURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
733 mpImpl->mStreamName = sName; // Note: may be empty (XSLT)
735 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
736 static constexpr OUString sOutlineStyleAsNormalListStyle(
737 u"OutlineStyleAsNormalListStyle"_ustr );
738 if( xPropertySetInfo->hasPropertyByName( sOutlineStyleAsNormalListStyle ) )
740 uno::Any aAny = mxExportInfo->getPropertyValue( sOutlineStyleAsNormalListStyle );
741 aAny >>= mpImpl->mbOutlineStyleAsNormalListStyle;
744 OUString sTargetStorage( u"TargetStorage"_ustr );
745 if( xPropertySetInfo->hasPropertyByName( sTargetStorage ) )
746 mxExportInfo->getPropertyValue( sTargetStorage ) >>= mpImpl->mxTargetStorage;
748 static constexpr OUString sExportTextNumberElement(
749 u"ExportTextNumberElement"_ustr );
750 if( xPropertySetInfo->hasPropertyByName( sExportTextNumberElement ) )
752 uno::Any aAny = mxExportInfo->getPropertyValue( sExportTextNumberElement );
753 aAny >>= mpImpl->mbExportTextNumberElement;
757 // XFilter
758 sal_Bool SAL_CALL SvXMLExport::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
760 // check for xHandler first... should have been supplied in initialize
761 if( !mxHandler.is() )
762 return false;
766 const SvXMLExportFlags nTest =
767 SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS;
768 if( (mnExportFlags & nTest) == nTest && msOrigFileName.isEmpty() )
770 // evaluate descriptor only for flat files and if a base URI
771 // has not been provided already
773 for( const auto& rProp : aDescriptor )
775 const OUString& rPropName = rProp.Name;
776 const Any& rValue = rProp.Value;
778 if ( rPropName == "FileName" )
780 if( !(rValue >>= msOrigFileName ) )
781 return false;
783 else if ( rPropName == "FilterName" )
785 if( !(rValue >>= msFilterName ) )
786 return false;
791 for( const auto& rProp : aDescriptor )
793 const OUString& rPropName = rProp.Name;
794 const Any& rValue = rProp.Value;
796 if (rPropName == "SourceShellID")
798 if (!(rValue >>= mpImpl->maSrcShellID))
799 return false;
801 else if (rPropName == "DestinationShellID")
803 if (!(rValue >>= mpImpl->maDestShellID))
804 return false;
806 else if( rPropName == "ImageFilter")
808 if (!(rValue >>= msImgFilterName))
809 return false;
814 exportDoc( meClass );
816 catch(const uno::Exception& e)
818 // We must catch exceptions, because according to the
819 // API definition export must not throw one!
820 css::uno::Any ex(cppu::getCaughtException());
821 OUString sMessage( ex.getValueTypeName() + ": \"" + e.Message + "\"");
822 if (e.Context.is())
824 const char* pContext = typeid(*e.Context).name();
825 sMessage += " (context: " + OUString::createFromAscii(pContext) + " )";
827 SetError( XMLERROR_FLAG_ERROR | XMLERROR_FLAG_SEVERE | XMLERROR_API,
828 Sequence<OUString>(), sMessage, nullptr );
831 // return true only if no error occurred
832 return (mnErrorFlags & (SvXMLErrorFlags::DO_NOTHING|SvXMLErrorFlags::ERROR_OCCURRED)) == SvXMLErrorFlags::NO;
835 void SAL_CALL SvXMLExport::cancel()
837 // stop export
838 Sequence<OUString> aEmptySeq;
839 SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
842 OUString SAL_CALL SvXMLExport::getName( )
844 return msFilterName;
847 void SAL_CALL SvXMLExport::setName( const OUString& )
849 // do nothing, because it is not possible to set the FilterName
852 // XServiceInfo
853 OUString SAL_CALL SvXMLExport::getImplementationName( )
855 return m_implementationName;
858 sal_Bool SAL_CALL SvXMLExport::supportsService( const OUString& rServiceName )
860 return cppu::supportsService(this, rServiceName);
863 uno::Sequence< OUString > SAL_CALL SvXMLExport::getSupportedServiceNames( )
865 return { u"com.sun.star.document.ExportFilter"_ustr, u"com.sun.star.xml.XMLExportFilter"_ustr };
868 OUString
869 SvXMLExport::EnsureNamespace(OUString const & i_rNamespace)
871 static constexpr OUString aPreferredPrefix(u"gen"_ustr);
872 OUString sPrefix;
873 sal_uInt16 nKey( GetNamespaceMap_().GetKeyByName( i_rNamespace ) );
874 if( XML_NAMESPACE_UNKNOWN == nKey )
876 // There is no prefix for the namespace, so
877 // we have to generate one and have to add it.
878 sPrefix = aPreferredPrefix;
879 nKey = GetNamespaceMap_().GetKeyByPrefix( sPrefix );
880 sal_Int32 n( 0 );
881 while( nKey != USHRT_MAX )
883 sPrefix = aPreferredPrefix + OUString::number(++n);
884 nKey = GetNamespaceMap_().GetKeyByPrefix( sPrefix );
887 if (mpImpl->mNamespaceMaps.empty()
888 || (mpImpl->mNamespaceMaps.top().second != mpImpl->mDepth))
890 // top was created for lower depth... need a new namespace map!
891 auto pNew = new SvXMLNamespaceMap( *mpNamespaceMap );
892 mpImpl->mNamespaceMaps.push(
893 ::std::make_pair(std::move(mpNamespaceMap), mpImpl->mDepth) );
894 mpNamespaceMap.reset( pNew );
897 // add the namespace to the map and as attribute
898 mpNamespaceMap->Add( sPrefix, i_rNamespace );
899 AddAttribute( GetXMLToken(XML_XMLNS) + ":" + sPrefix, i_rNamespace );
901 else
903 // If there is a prefix for the namespace, reuse that.
904 sPrefix = GetNamespaceMap_().GetPrefixByKey( nKey );
906 return sPrefix;
909 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const OUString& rName,
910 const OUString& rValue )
912 AddAttribute(GetNamespaceMap_().GetQNameByKey(nPrefixKey, rName), rValue);
915 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey,
916 enum XMLTokenEnum eName,
917 const OUString& rValue )
919 AddAttribute(nPrefixKey, GetXMLToken(eName), rValue);
922 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey,
923 enum XMLTokenEnum eName,
924 enum XMLTokenEnum eValue)
926 AddAttribute(nPrefixKey, eName, GetXMLToken(eValue));
929 void SvXMLExport::AddAttribute( const OUString& rQName,
930 const OUString& rValue )
932 mxAttrList->AddAttribute(
933 rQName,
934 rValue );
937 void SvXMLExport::AddAttribute( const OUString& rQName,
938 enum ::xmloff::token::XMLTokenEnum eValue )
940 AddAttribute(rQName, GetXMLToken(eValue));
943 void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
944 const css::lang::Locale& rLocale, bool bWriteEmpty )
946 if (rLocale.Variant.isEmpty())
948 // Per convention The BCP 47 string is always stored in Variant, if
949 // that is empty we have a plain language-country combination, no need
950 // to convert to LanguageTag first. Also catches the case of empty
951 // locale denoting system locale.
952 xmloff::token::XMLTokenEnum eLanguage, eCountry;
953 eLanguage = XML_LANGUAGE;
954 eCountry = XML_COUNTRY;
955 if (bWriteEmpty || !rLocale.Language.isEmpty())
956 AddAttribute( nPrefix, eLanguage, rLocale.Language);
957 if (bWriteEmpty || !rLocale.Country.isEmpty())
958 AddAttribute( nPrefix, eCountry, rLocale.Country);
960 else
962 LanguageTag aLanguageTag( rLocale);
963 AddLanguageTagAttributes( nPrefix, nPrefixRfc, aLanguageTag, bWriteEmpty);
967 void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
968 const LanguageTag& rLanguageTag, bool bWriteEmpty )
970 if (rLanguageTag.isIsoODF())
972 if (bWriteEmpty || !rLanguageTag.isSystemLocale())
974 AddAttribute( nPrefix, XML_LANGUAGE, rLanguageTag.getLanguage());
975 if (rLanguageTag.hasScript() && getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
976 AddAttribute( nPrefix, XML_SCRIPT, rLanguageTag.getScript());
977 if (bWriteEmpty || !rLanguageTag.getCountry().isEmpty())
978 AddAttribute( nPrefix, XML_COUNTRY, rLanguageTag.getCountry());
981 else
983 if (getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
984 AddAttribute( nPrefixRfc, XML_RFC_LANGUAGE_TAG, rLanguageTag.getBcp47());
985 // Also in case of non-pure-ISO tag store best matching fo: attributes
986 // for consumers not handling *:rfc-language-tag, ensuring that only
987 // valid ISO codes are stored. Here the bWriteEmpty parameter has no
988 // meaning.
989 OUString aLanguage, aScript, aCountry;
990 rLanguageTag.getIsoLanguageScriptCountry( aLanguage, aScript, aCountry);
991 if (!aLanguage.isEmpty())
993 AddAttribute( nPrefix, XML_LANGUAGE, aLanguage);
994 if (!aScript.isEmpty() && getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
995 AddAttribute( nPrefix, XML_SCRIPT, aScript);
996 if (!aCountry.isEmpty())
997 AddAttribute( nPrefix, XML_COUNTRY, aCountry);
1002 void SvXMLExport::AddAttributeList( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
1004 if( xAttrList.is())
1005 mxAttrList->AppendAttributeList( xAttrList );
1008 void SvXMLExport::ClearAttrList()
1010 mxAttrList->Clear();
1013 #ifdef DBG_UTIL
1014 void SvXMLExport::CheckAttrList()
1016 SAL_WARN_IF( mxAttrList->getLength(), "xmloff.core", "XMLExport::CheckAttrList: list is not empty" );
1018 #endif
1020 void SvXMLExport::ImplExportMeta()
1022 CheckAttrList();
1024 ExportMeta_();
1027 void SvXMLExport::ImplExportSettings()
1029 CheckAttrList();
1031 ::std::vector< SettingsGroup > aSettings;
1032 sal_Int32 nSettingsCount = 0;
1034 // view settings
1035 uno::Sequence< beans::PropertyValue > aViewSettings;
1036 GetViewSettingsAndViews( aViewSettings );
1037 aSettings.emplace_back( XML_VIEW_SETTINGS, aViewSettings );
1038 nSettingsCount += aViewSettings.getLength();
1040 // configuration settings
1041 uno::Sequence<beans::PropertyValue> aConfigSettings;
1042 GetConfigurationSettings( aConfigSettings );
1043 aSettings.emplace_back( XML_CONFIGURATION_SETTINGS, aConfigSettings );
1044 nSettingsCount += aConfigSettings.getLength();
1046 // any document specific settings
1047 nSettingsCount += GetDocumentSpecificSettings( aSettings );
1050 SvXMLElementExport aElem( *this,
1051 nSettingsCount != 0,
1052 XML_NAMESPACE_OFFICE, XML_SETTINGS,
1053 true, true );
1055 SettingsExportFacade aSettingsExportContext( *this );
1056 XMLSettingsExportHelper aSettingsExportHelper( aSettingsExportContext );
1058 for (auto const& settings : aSettings)
1060 if ( !settings.aSettings.hasElements() )
1061 continue;
1063 const OUString& sSettingsName( GetXMLToken( settings.eGroupName ) );
1064 OUString sQName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OOO, sSettingsName );
1065 aSettingsExportHelper.exportAllSettings( settings.aSettings, sQName );
1070 void SvXMLExport::ImplExportStyles()
1072 CheckAttrList();
1075 // <style:styles>
1076 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_STYLES,
1077 true, true );
1079 ExportStyles_( false );
1082 // transfer style names (+ families) TO other components (if appropriate)
1083 if( ( mnExportFlags & SvXMLExportFlags::CONTENT ) || !mxExportInfo.is() )
1084 return;
1086 static constexpr OUString sStyleNames( u"StyleNames"_ustr );
1087 static constexpr OUString sStyleFamilies( u"StyleFamilies"_ustr );
1088 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
1089 if ( xPropertySetInfo->hasPropertyByName( sStyleNames ) && xPropertySetInfo->hasPropertyByName( sStyleFamilies ) )
1091 Sequence<sal_Int32> aStyleFamilies;
1092 Sequence<OUString> aStyleNames;
1093 mxAutoStylePool->GetRegisteredNames( aStyleFamilies, aStyleNames );
1094 mxExportInfo->setPropertyValue( sStyleNames, Any( aStyleNames ) );
1095 mxExportInfo->setPropertyValue( sStyleFamilies,
1096 Any( aStyleFamilies ) );
1100 void SvXMLExport::ImplExportAutoStyles()
1102 // transfer style names (+ families) FROM other components (if appropriate)
1103 OUString sStyleNames( u"StyleNames"_ustr );
1104 OUString sStyleFamilies( u"StyleFamilies"_ustr );
1105 if( ( !( mnExportFlags & SvXMLExportFlags::STYLES ) )
1106 && mxExportInfo.is()
1107 && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleNames )
1108 && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleFamilies ) )
1110 Sequence<sal_Int32> aStyleFamilies;
1111 mxExportInfo->getPropertyValue( sStyleFamilies ) >>= aStyleFamilies;
1112 Sequence<OUString> aStyleNames;
1113 mxExportInfo->getPropertyValue( sStyleNames ) >>= aStyleNames;
1114 mxAutoStylePool->RegisterNames( aStyleFamilies, aStyleNames );
1118 // <style:automatic-styles>
1119 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE,
1120 XML_AUTOMATIC_STYLES, true, true );
1122 ExportAutoStyles_();
1126 void SvXMLExport::ImplExportMasterStyles()
1128 // <style:master-styles>
1129 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_MASTER_STYLES,
1130 true, true );
1132 ExportMasterStyles_();
1135 void SvXMLExport::ImplExportContent()
1137 CheckAttrList();
1140 SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_BODY,
1141 true, true );
1143 XMLTokenEnum eClass = meClass;
1144 if( XML_TEXT_GLOBAL == eClass )
1146 AddAttribute( XML_NAMESPACE_TEXT, XML_GLOBAL,
1147 GetXMLToken( XML_TRUE ) );
1148 eClass = XML_TEXT;
1150 if ( XML_GRAPHICS == eClass )
1151 eClass = XML_DRAWING;
1152 // <office:body ...>
1153 SetBodyAttributes();
1154 SvXMLElementExport aElem( *this, meClass != XML_TOKEN_INVALID,
1155 XML_NAMESPACE_OFFICE, eClass,
1156 true, true );
1158 ExportContent_();
1163 void SvXMLExport::SetBodyAttributes()
1167 static void
1168 lcl_AddGrddl(SvXMLExport const & rExport, const SvXMLExportFlags /*nExportMode*/)
1170 // check version >= 1.2
1171 switch (rExport.getSaneDefaultVersion()) {
1172 case SvtSaveOptions::ODFSVER_011: // fall through
1173 case SvtSaveOptions::ODFSVER_010: return;
1174 default: break;
1177 // #i115030#: disabled, the XSLT is not finished, and not available via HTTP
1178 #if 0
1179 if (SvXMLExportFlags::SETTINGS != nExportMode) // meta, content, styles
1181 rExport.AddAttribute( XML_NAMESPACE_GRDDL, XML_TRANSFORMATION,
1182 OUString("http://FIXME") );
1184 #endif
1187 // note: the point of this is presumably to mitigate SHA/1k info leak of plain text
1188 void SvXMLExport::addChaffWhenEncryptedStorage()
1190 uno::Reference<embed::XEncryptionProtectedStorage> const xEncr(mpImpl->mxTargetStorage, uno::UNO_QUERY);
1192 if (xEncr.is() && xEncr->hasEncryptionData() && mxExtHandler.is())
1194 uno::Sequence<beans::NamedValue> const algo(xEncr->getEncryptionAlgorithms());
1195 for (auto const& it : algo)
1197 if (it.Name == "ChecksumAlgorithm")
1199 if (!it.Value.hasValue())
1201 return; // no checksum => no chaff
1203 break;
1206 mxExtHandler->comment(OStringToOUString(comphelper::xml::makeXMLChaff(), RTL_TEXTENCODING_ASCII_US));
1210 auto SvXMLExport::GetODFVersionAttributeValue() const -> char const*
1212 char const* pVersion(nullptr);
1213 switch (getSaneDefaultVersion())
1215 case SvtSaveOptions::ODFSVER_014_EXTENDED: [[fallthrough]];
1216 case SvtSaveOptions::ODFSVER_014: pVersion = "1.4"; break;
1217 case SvtSaveOptions::ODFSVER_013_EXTENDED: [[fallthrough]];
1218 case SvtSaveOptions::ODFSVER_013: pVersion = "1.3"; break;
1219 case SvtSaveOptions::ODFSVER_012_EXTENDED: [[fallthrough]];
1220 case SvtSaveOptions::ODFSVER_012_EXT_COMPAT: [[fallthrough]];
1221 case SvtSaveOptions::ODFSVER_012: pVersion = "1.2"; break;
1222 case SvtSaveOptions::ODFSVER_011: pVersion = "1.1"; break;
1223 case SvtSaveOptions::ODFSVER_010: break;
1225 default:
1226 assert(!"xmloff::SvXMLExport::exportDoc(), unexpected odf default version!");
1228 return pVersion;
1231 ErrCode SvXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass )
1233 bool bOwnGraphicResolver = false;
1234 bool bOwnEmbeddedResolver = false;
1236 if (!mxGraphicStorageHandler.is() || !mxEmbeddedResolver.is())
1238 Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
1239 if( xFactory.is() )
1243 if (!mxGraphicStorageHandler.is())
1245 mxGraphicStorageHandler.set(xFactory->createInstance( u"com.sun.star.document.ExportGraphicStorageHandler"_ustr), UNO_QUERY);
1246 bOwnGraphicResolver = mxGraphicStorageHandler.is();
1249 if( !mxEmbeddedResolver.is() )
1251 mxEmbeddedResolver.set(
1252 xFactory->createInstance( u"com.sun.star.document.ExportEmbeddedObjectResolver"_ustr ), UNO_QUERY);
1253 bOwnEmbeddedResolver = mxEmbeddedResolver.is();
1256 catch(const css::uno::Exception&)
1261 if( (getExportFlags() & SvXMLExportFlags::OASIS) == SvXMLExportFlags::NONE )
1265 static ::comphelper::PropertyMapEntry const aInfoMap[] =
1267 { u"Class"_ustr, 0,
1268 ::cppu::UnoType<OUString>::get(),
1269 PropertyAttribute::MAYBEVOID, 0},
1271 Reference< XPropertySet > xConvPropSet(
1272 ::comphelper::GenericPropertySet_CreateInstance(
1273 new ::comphelper::PropertySetInfo( aInfoMap ) ) );
1275 xConvPropSet->setPropertyValue( u"Class"_ustr, Any(GetXMLToken( eClass )) );
1277 Reference< XPropertySet > xPropSet =
1278 mxExportInfo.is()
1279 ? PropertySetMerger_CreateInstance( mxExportInfo,
1280 xConvPropSet )
1281 : xConvPropSet;
1283 Sequence<Any> aArgs{ Any(mxHandler), Any(xPropSet), Any(mxModel) };
1284 // get filter component
1285 Reference< xml::sax::XDocumentHandler > xTmpDocHandler(
1286 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(u"com.sun.star.comp.Oasis2OOoTransformer"_ustr, aArgs, m_xContext),
1287 UNO_QUERY);
1288 SAL_WARN_IF(!xTmpDocHandler.is(), "xmloff.core", "can't instantiate OASIS transformer component" );
1289 if( xTmpDocHandler.is() )
1291 mxHandler = std::move(xTmpDocHandler);
1292 mxExtHandler.set( mxHandler, UNO_QUERY );
1295 catch(const css::uno::Exception&)
1300 mxHandler->startDocument();
1302 addChaffWhenEncryptedStorage();
1304 // <office:document ...>
1305 CheckAttrList();
1307 // namespace attributes
1308 // ( The namespace decls should be first attributes in the element;
1309 // some faulty XML parsers (JAXP1.1) have a problem with this,
1310 // also it's more elegant )
1311 sal_uInt16 nPos = mpNamespaceMap->GetFirstKey();
1312 while( USHRT_MAX != nPos )
1314 mxAttrList->AddAttribute( mpNamespaceMap->GetAttrNameByKey( nPos ),
1315 mpNamespaceMap->GetNameByKey( nPos ) );
1316 nPos = mpNamespaceMap->GetNextKey( nPos );
1319 // office:version = ...
1320 const char*const pVersion = GetODFVersionAttributeValue();
1322 if (pVersion)
1324 AddAttribute( XML_NAMESPACE_OFFICE, XML_VERSION,
1325 OUString::createFromAscii(pVersion) );
1329 enum XMLTokenEnum eRootService = XML_TOKEN_INVALID;
1330 const SvXMLExportFlags nExportMode = mnExportFlags & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS);
1332 lcl_AddGrddl(*this, nExportMode);
1334 if( SvXMLExportFlags::META == nExportMode )
1336 // export only meta
1337 eRootService = XML_DOCUMENT_META;
1339 else if ( SvXMLExportFlags::SETTINGS == nExportMode )
1341 // export only settings
1342 eRootService = XML_DOCUMENT_SETTINGS;
1344 else if( SvXMLExportFlags::STYLES == nExportMode )
1346 // export only styles
1347 eRootService = XML_DOCUMENT_STYLES;
1349 else if( SvXMLExportFlags::CONTENT == nExportMode )
1351 // export only content
1352 eRootService = XML_DOCUMENT_CONTENT;
1354 else
1356 // the god'ol one4all element
1357 eRootService = XML_DOCUMENT;
1358 // office:mimetype = ... (only for stream containing the content)
1359 if( eClass != XML_TOKEN_INVALID )
1361 OUString aTmp = "application/vnd.oasis.opendocument." + GetXMLToken( eClass );
1362 AddAttribute( XML_NAMESPACE_OFFICE, XML_MIMETYPE, aTmp );
1366 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, eRootService, true, true );
1368 // meta information
1369 if( mnExportFlags & SvXMLExportFlags::META )
1370 ImplExportMeta();
1372 // settings
1373 if( mnExportFlags & SvXMLExportFlags::SETTINGS )
1374 ImplExportSettings();
1376 // scripts
1377 if( mnExportFlags & SvXMLExportFlags::SCRIPTS )
1378 ExportScripts_();
1380 // font declarations
1381 if( mnExportFlags & SvXMLExportFlags::FONTDECLS )
1382 ExportFontDecls_();
1384 // styles
1385 if( mnExportFlags & SvXMLExportFlags::STYLES )
1386 ImplExportStyles();
1388 // autostyles
1389 if( mnExportFlags & SvXMLExportFlags::AUTOSTYLES )
1390 ImplExportAutoStyles();
1392 // masterstyles
1393 if( mnExportFlags & SvXMLExportFlags::MASTERSTYLES )
1394 ImplExportMasterStyles();
1396 // content
1397 if( mnExportFlags & SvXMLExportFlags::CONTENT )
1398 ImplExportContent();
1401 mxHandler->endDocument();
1403 if( bOwnGraphicResolver )
1405 uno::Reference<XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY);
1406 xComp->dispose();
1409 if( bOwnEmbeddedResolver )
1411 Reference< XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
1412 xComp->dispose();
1415 return ERRCODE_NONE;
1418 void SvXMLExport::ResetNamespaceMap()
1420 mpNamespaceMap->Clear();
1423 OUString const & SvXMLExport::GetSourceShellID() const
1425 return mpImpl->maSrcShellID;
1428 OUString const & SvXMLExport::GetDestinationShellID() const
1430 return mpImpl->maDestShellID;
1433 void SvXMLExport::ExportMeta_()
1435 OUString generator( ::utl::DocInfoHelper::GetGeneratorString() );
1436 Reference< XDocumentPropertiesSupplier > xDocPropsSupplier(mxModel,
1437 UNO_QUERY);
1438 if (xDocPropsSupplier.is()) {
1439 Reference<XDocumentProperties> xDocProps(
1440 xDocPropsSupplier->getDocumentProperties());
1441 if (!xDocProps.is()) throw;
1442 // update generator here
1443 xDocProps->setGenerator(generator);
1444 rtl::Reference<SvXMLMetaExport> pMeta = new SvXMLMetaExport(*this, xDocProps);
1445 pMeta->Export();
1446 } else {
1447 // office:meta
1448 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_META,
1449 true, true );
1451 // BM: #i60323# export generator even if xInfoProp is empty (which is the
1452 // case for charts). The generator does not depend on xInfoProp
1453 SvXMLElementExport anElem( *this, XML_NAMESPACE_META, XML_GENERATOR,
1454 true, true );
1455 Characters(generator);
1460 void SvXMLExport::ExportScripts_()
1462 SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_SCRIPTS, true, true );
1464 // export Basic macros (only for FlatXML)
1465 if ( mnExportFlags & SvXMLExportFlags::EMBEDDED )
1467 OUString aValue( GetNamespaceMap().GetPrefixByKey( XML_NAMESPACE_OOO ) + ":Basic" );
1468 AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, aValue );
1470 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_SCRIPT, true, true );
1472 // initialize Basic
1473 if ( mxModel.is() )
1475 Reference< beans::XPropertySet > xPSet( mxModel, UNO_QUERY );
1476 if ( xPSet.is() )
1477 xPSet->getPropertyValue(u"BasicLibraries"_ustr);
1480 Reference < XDocumentHandler > xHdl( new XMLBasicExportFilter( mxHandler ) );
1481 Reference< document::XXMLBasicExporter > xExporter = document::XMLOasisBasicExporter::createWithHandler( m_xContext, xHdl );
1483 xExporter->setSourceDocument( mxModel );
1484 Sequence< PropertyValue > aMediaDesc( 0 );
1485 xExporter->filter( aMediaDesc );
1488 // export document events
1489 Reference< document::XEventsSupplier > xEvents( GetModel(), UNO_QUERY );
1490 GetEventExport().Export( xEvents );
1493 void SvXMLExport::ExportFontDecls_()
1495 if( mxFontAutoStylePool.is() )
1496 mxFontAutoStylePool->exportXML();
1499 void SvXMLExport::ExportStyles_( bool )
1501 uno::Reference< lang::XMultiServiceFactory > xFact( GetModel(), uno::UNO_QUERY );
1502 if( !xFact.is())
1503 return;
1505 // export (fill-)gradient-styles
1508 uno::Reference< container::XNameAccess > xGradient( xFact->createInstance(u"com.sun.star.drawing.GradientTable"_ustr), uno::UNO_QUERY );
1509 if( xGradient.is() )
1511 XMLGradientStyleExport aGradientStyle( *this );
1513 if( xGradient->hasElements() )
1515 const uno::Sequence< OUString > aNamesSeq ( xGradient->getElementNames() );
1516 for( const OUString& rStrName : aNamesSeq )
1520 uno::Any aValue = xGradient->getByName( rStrName );
1522 aGradientStyle.exportXML( rStrName, aValue );
1524 catch(const container::NoSuchElementException&)
1531 catch(const lang::ServiceNotRegisteredException&)
1535 // export (fill-)hatch-styles
1538 uno::Reference< container::XNameAccess > xHatch( xFact->createInstance(u"com.sun.star.drawing.HatchTable"_ustr), uno::UNO_QUERY );
1539 if( xHatch.is() )
1541 XMLHatchStyleExport aHatchStyle( *this );
1543 if( xHatch->hasElements() )
1545 const uno::Sequence< OUString > aNamesSeq ( xHatch->getElementNames() );
1546 for( const OUString& rStrName : aNamesSeq )
1550 uno::Any aValue = xHatch->getByName( rStrName );
1552 aHatchStyle.exportXML( rStrName, aValue );
1554 catch(const container::NoSuchElementException&)
1560 catch(const lang::ServiceNotRegisteredException&)
1564 // export (fill-)bitmap-styles
1567 uno::Reference< container::XNameAccess > xBitmap( xFact->createInstance(u"com.sun.star.drawing.BitmapTable"_ustr), uno::UNO_QUERY );
1568 if( xBitmap.is() )
1570 if( xBitmap->hasElements() )
1572 const uno::Sequence< OUString > aNamesSeq ( xBitmap->getElementNames() );
1573 for( const OUString& rStrName : aNamesSeq )
1577 uno::Any aValue = xBitmap->getByName( rStrName );
1579 XMLImageStyle::exportXML( rStrName, aValue, *this );
1581 catch(const container::NoSuchElementException&)
1588 catch(const lang::ServiceNotRegisteredException&)
1592 // export transparency-gradient -styles
1595 uno::Reference< container::XNameAccess > xTransGradient( xFact->createInstance(u"com.sun.star.drawing.TransparencyGradientTable"_ustr), uno::UNO_QUERY );
1596 if( xTransGradient.is() )
1598 XMLTransGradientStyleExport aTransGradientstyle( *this );
1600 if( xTransGradient->hasElements() )
1602 const uno::Sequence< OUString > aNamesSeq ( xTransGradient->getElementNames() );
1603 for( const OUString& rStrName : aNamesSeq )
1607 uno::Any aValue = xTransGradient->getByName( rStrName );
1609 aTransGradientstyle.exportXML( rStrName, aValue );
1611 catch(const container::NoSuchElementException&)
1618 catch(const lang::ServiceNotRegisteredException&)
1622 // export marker-styles
1625 uno::Reference< container::XNameAccess > xMarker( xFact->createInstance(u"com.sun.star.drawing.MarkerTable"_ustr), uno::UNO_QUERY );
1626 if( xMarker.is() )
1628 XMLMarkerStyleExport aMarkerStyle( *this );
1630 if( xMarker->hasElements() )
1632 const uno::Sequence< OUString > aNamesSeq ( xMarker->getElementNames() );
1633 for( const OUString& rStrName : aNamesSeq )
1637 uno::Any aValue = xMarker->getByName( rStrName );
1639 aMarkerStyle.exportXML( rStrName, aValue );
1641 catch(const container::NoSuchElementException&)
1648 catch(const lang::ServiceNotRegisteredException&)
1652 // export dash-styles
1655 uno::Reference< container::XNameAccess > xDashes( xFact->createInstance(u"com.sun.star.drawing.DashTable"_ustr), uno::UNO_QUERY );
1656 if( xDashes.is() )
1658 XMLDashStyleExport aDashStyle( *this );
1660 if( xDashes->hasElements() )
1662 const uno::Sequence< OUString > aNamesSeq ( xDashes->getElementNames() );
1663 for( const OUString& rStrName : aNamesSeq )
1667 uno::Any aValue = xDashes->getByName( rStrName );
1669 aDashStyle.exportXML( rStrName, aValue );
1671 catch(const container::NoSuchElementException&)
1678 catch(const lang::ServiceNotRegisteredException&)
1683 void SvXMLExport::ExportThemeElement(std::shared_ptr<model::Theme> const& pTheme)
1685 if (!pTheme)
1686 return;
1688 if (!pTheme->GetName().isEmpty())
1689 AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, pTheme->GetName());
1690 SvXMLElementExport aTheme(*this, XML_NAMESPACE_LO_EXT, XML_THEME, true, true);
1692 auto pColorSet = pTheme->getColorSet();
1693 if (!pColorSet)
1694 return;
1695 if (!pColorSet->getName().isEmpty())
1696 AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, pColorSet->getName());
1697 SvXMLElementExport aColorTable(*this, XML_NAMESPACE_LO_EXT, XML_THEME_COLORS, true, true);
1699 static const XMLTokenEnum aColorTokens[] =
1701 XML_DARK1, // Text 1
1702 XML_LIGHT1, // Background 1
1703 XML_DARK2, // Text 2
1704 XML_LIGHT2, // Background 2
1705 XML_ACCENT1,
1706 XML_ACCENT2,
1707 XML_ACCENT3,
1708 XML_ACCENT4,
1709 XML_ACCENT5,
1710 XML_ACCENT6,
1711 XML_HYPERLINK, // Hyperlink
1712 XML_FOLLOWED_HYPERLINK, // Followed hyperlink
1715 for (auto eThemeColorType : o3tl::enumrange<model::ThemeColorType>())
1717 if (eThemeColorType == model::ThemeColorType::Unknown)
1718 continue;
1720 auto nColor = size_t(eThemeColorType);
1721 AddAttribute(XML_NAMESPACE_LO_EXT, XML_NAME, GetXMLToken(aColorTokens[nColor]));
1722 OUStringBuffer sValue;
1723 sax::Converter::convertColor(sValue, pColorSet->getColor(eThemeColorType));
1724 AddAttribute(XML_NAMESPACE_LO_EXT, XML_COLOR, sValue.makeStringAndClear());
1725 SvXMLElementExport aColor(*this, XML_NAMESPACE_LO_EXT, XML_COLOR, true, true);
1729 XMLTextParagraphExport* SvXMLExport::CreateTextParagraphExport()
1731 return new XMLTextParagraphExport( *this, *GetAutoStylePool() );
1734 XMLShapeExport* SvXMLExport::CreateShapeExport()
1736 return new XMLShapeExport(*this);
1739 SvXMLAutoStylePoolP* SvXMLExport::CreateAutoStylePool()
1741 return new SvXMLAutoStylePoolP(*this);
1744 void SvXMLExport::collectAutoStyles()
1748 XMLPageExport* SvXMLExport::CreatePageExport()
1750 return new XMLPageExport( *this );
1753 SchXMLExportHelper* SvXMLExport::CreateChartExport()
1755 // WASM_CHART change
1756 // TODO: With Chart extracted this cannot really happen since
1757 // no Chart could've been added at all
1758 #if !ENABLE_WASM_STRIP_CHART
1759 return new SchXMLExportHelper(*this, *GetAutoStylePool());
1760 #else
1761 return nullptr;
1762 #endif
1765 XMLFontAutoStylePool* SvXMLExport::CreateFontAutoStylePool()
1767 return new XMLFontAutoStylePool( *this );
1770 xmloff::OFormLayerXMLExport* SvXMLExport::CreateFormExport()
1772 return new xmloff::OFormLayerXMLExport(*this);
1775 void SvXMLExport::GetViewSettingsAndViews(uno::Sequence<beans::PropertyValue>& rProps)
1777 GetViewSettings(rProps);
1778 uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
1779 if(!xViewDataSupplier.is())
1780 return;
1782 uno::Reference<container::XIndexAccess> xIndexAccess;
1783 xViewDataSupplier->setViewData( xIndexAccess ); // make sure we get a newly created sequence
1785 // tdf#130559: don't export preview view data if active
1786 static constexpr OUStringLiteral sNoPreviewData = u"NoPreviewData";
1787 css::uno::ContextLayer layer(comphelper::NewFlagContext(sNoPreviewData));
1788 xIndexAccess = xViewDataSupplier->getViewData();
1790 bool bAdd = false;
1791 uno::Any aAny;
1792 if(xIndexAccess.is() && xIndexAccess->hasElements() )
1794 sal_Int32 nCount = xIndexAccess->getCount();
1795 for (sal_Int32 i = 0; i < nCount; i++)
1797 aAny = xIndexAccess->getByIndex(i);
1798 uno::Sequence<beans::PropertyValue> aProps;
1799 if( aAny >>= aProps )
1801 if( aProps.hasElements() )
1803 bAdd = true;
1804 break;
1810 if( bAdd )
1812 sal_Int32 nOldLength(rProps.getLength());
1813 rProps.realloc(nOldLength + 1);
1814 rProps.getArray()[nOldLength] = comphelper::makePropertyValue(u"Views"_ustr, xIndexAccess);
1818 void SvXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>&)
1822 void SvXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>&)
1826 sal_Int32 SvXMLExport::GetDocumentSpecificSettings( ::std::vector< SettingsGroup >& )
1828 return 0;
1831 void SvXMLExport::collectDataStyles(bool bFromUsedStyles)
1833 Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(GetModel(), uno::UNO_QUERY);
1834 if (!xStyleFamiliesSupplier.is())
1835 return;
1837 Reference<container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
1838 if (!xStylesFamilies.is())
1839 return;
1841 Reference<container::XIndexAccess> xCellStyles(xStylesFamilies->getByName(u"CellStyles"_ustr), uno::UNO_QUERY);
1842 if (!xCellStyles.is())
1843 return;
1845 sal_Int32 nCount(xCellStyles->getCount());
1846 for (sal_Int32 i = 0; i < nCount; ++i)
1848 Reference<style::XStyle> xStyle(xCellStyles->getByIndex(i), uno::UNO_QUERY);
1849 if (bFromUsedStyles && !xStyle->isInUse())
1850 continue;
1852 Reference<beans::XPropertySet> xCellProperties(xStyle, uno::UNO_QUERY);
1853 if (xCellProperties.is())
1855 sal_Int32 nNumberFormat = 0;
1856 if (xCellProperties->getPropertyValue(u"NumberFormat"_ustr) >>= nNumberFormat)
1857 addDataStyle(nNumberFormat);
1862 void SvXMLExport::addDataStyle(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ )
1864 if(mpNumExport)
1865 mpNumExport->SetUsed(nNumberFormat);
1868 void SvXMLExport::exportDataStyles()
1870 if(mpNumExport)
1871 mpNumExport->Export(false);
1874 void SvXMLExport::exportAutoDataStyles()
1876 if(mpNumExport)
1877 mpNumExport->Export(true);
1879 if (mxFormExport.is())
1880 mxFormExport->exportAutoControlNumberStyles();
1883 OUString SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ ) const
1885 OUString sTemp;
1886 if(mpNumExport)
1887 sTemp = mpNumExport->GetStyleName(nNumberFormat);
1888 return sTemp;
1891 void SvXMLExport::exportAnnotationMeta(const uno::Reference<drawing::XShape>&)
1895 sal_Int32 SvXMLExport::dataStyleForceSystemLanguage(sal_Int32 nFormat) const
1897 return ( mpNumExport != nullptr )
1898 ? mpNumExport->ForceSystemLanguage( nFormat ) : nFormat;
1901 OUString SvXMLExport::AddEmbeddedXGraphic(uno::Reference<graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType, OUString const & rRequestedName)
1903 OUString sURL;
1905 Graphic aGraphic(rxGraphic);
1906 const OUString& aOriginURL = aGraphic.getOriginURL();
1908 if (!aOriginURL.isEmpty())
1910 sURL = GetRelativeReference(aOriginURL);
1912 else
1914 if (mxGraphicStorageHandler.is())
1916 if (!(getExportFlags() & SvXMLExportFlags::EMBEDDED))
1917 sURL = mxGraphicStorageHandler->saveGraphicByName(rxGraphic, rOutMimeType, rRequestedName);
1920 return sURL;
1923 bool SvXMLExport::GetGraphicMimeTypeFromStream(uno::Reference<graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType)
1925 if (mxGraphicStorageHandler.is())
1927 Reference<XInputStream> xInputStream(mxGraphicStorageHandler->createInputStream(rxGraphic));
1928 if (xInputStream.is())
1930 rOutMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForImageStream(xInputStream);
1931 return true;
1935 return false;
1938 bool SvXMLExport::AddEmbeddedXGraphicAsBase64(uno::Reference<graphic::XGraphic> const & rxGraphic)
1940 if ((getExportFlags() & SvXMLExportFlags::EMBEDDED) &&
1941 mxGraphicStorageHandler.is())
1943 Reference<XInputStream> xInputStream(mxGraphicStorageHandler->createInputStream(rxGraphic));
1944 if (xInputStream.is())
1946 Graphic aGraphic(rxGraphic);
1947 if (aGraphic.getOriginURL().isEmpty()) // don't add the base64 if the origin URL is set (image is from an external URL)
1949 XMLBase64Export aBase64Exp(*this);
1950 return aBase64Exp.exportOfficeBinaryDataElement(xInputStream);
1955 return false;
1958 OUString SvXMLExport::AddEmbeddedObject( const OUString& rEmbeddedObjectURL )
1960 OUString sRet;
1961 bool bSupportedURL = rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECT_URL_BASE) ||
1962 rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE);
1963 if (bSupportedURL && mxEmbeddedResolver.is())
1965 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL(rEmbeddedObjectURL);
1967 else
1968 sRet = GetRelativeReference( rEmbeddedObjectURL );
1970 return sRet;
1973 bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString& rEmbeddedObjectURL )
1975 bool bRet = false;
1976 bool bSupportedURL = rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECT_URL_BASE) ||
1977 rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE);
1978 if (bSupportedURL && mxEmbeddedResolver.is())
1980 Reference < XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY );
1981 if( xNA.is() )
1983 Any aAny = xNA->getByName( rEmbeddedObjectURL );
1984 Reference < XInputStream > xIn;
1985 aAny >>= xIn;
1986 if( xIn.is() )
1988 XMLBase64Export aBase64Exp( *this );
1989 bRet = aBase64Exp.exportOfficeBinaryDataElement( xIn );
1994 return bRet;
1997 OUString SvXMLExport::EncodeStyleName(
1998 const OUString& rName,
1999 bool *pEncoded ) const
2001 return GetMM100UnitConverter().encodeStyleName( rName, pEncoded );
2004 ProgressBarHelper* SvXMLExport::GetProgressBarHelper()
2006 if (!mpProgressBarHelper)
2008 mpProgressBarHelper.reset( new ProgressBarHelper(mxStatusIndicator, true) );
2010 if (mxExportInfo.is())
2012 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
2013 if (xPropertySetInfo.is())
2015 OUString sProgressRange(XML_PROGRESSRANGE);
2016 OUString sProgressMax(XML_PROGRESSMAX);
2017 OUString sProgressCurrent(XML_PROGRESSCURRENT);
2018 OUString sRepeat(XML_PROGRESSREPEAT);
2019 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
2020 xPropertySetInfo->hasPropertyByName(sProgressCurrent) &&
2021 xPropertySetInfo->hasPropertyByName(sProgressRange))
2023 uno::Any aAny;
2024 sal_Int32 nProgressMax(0);
2025 sal_Int32 nProgressCurrent(0);
2026 sal_Int32 nProgressRange(0);
2027 aAny = mxExportInfo->getPropertyValue(sProgressRange);
2028 if (aAny >>= nProgressRange)
2029 mpProgressBarHelper->SetRange(nProgressRange);
2030 aAny = mxExportInfo->getPropertyValue(sProgressMax);
2031 if (aAny >>= nProgressMax)
2032 mpProgressBarHelper->SetReference(nProgressMax);
2033 aAny = mxExportInfo->getPropertyValue(sProgressCurrent);
2034 if (aAny >>= nProgressCurrent)
2035 mpProgressBarHelper->SetValue(nProgressCurrent);
2037 if (xPropertySetInfo->hasPropertyByName(sRepeat))
2039 uno::Any aAny = mxExportInfo->getPropertyValue(sRepeat);
2040 if (aAny.getValueType() == cppu::UnoType<bool>::get())
2041 mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
2042 else {
2043 SAL_WARN("xmloff.core", "why is it no boolean?" );
2049 return mpProgressBarHelper.get();
2052 XMLEventExport& SvXMLExport::GetEventExport()
2054 if( nullptr == mpEventExport)
2056 // create EventExport on demand
2057 mpEventExport.reset( new XMLEventExport(*this) );
2059 // and register standard handlers + names
2060 mpEventExport->AddHandler(u"StarBasic"_ustr, std::make_unique<XMLStarBasicExportHandler>());
2061 mpEventExport->AddHandler(u"Script"_ustr, std::make_unique<XMLScriptExportHandler>());
2062 mpEventExport->AddTranslationTable(aStandardEventTable);
2065 return *mpEventExport;
2068 XMLImageMapExport& SvXMLExport::GetImageMapExport()
2070 // image map export, create on-demand
2071 if( nullptr == mpImageMapExport )
2073 mpImageMapExport.reset( new XMLImageMapExport(*this) );
2076 return *mpImageMapExport;
2079 void SvXMLExport::ExportEmbeddedOwnObject( Reference< XComponent > const & rComp )
2081 OUString sFilterService;
2083 Reference < lang::XServiceInfo > xServiceInfo( rComp, UNO_QUERY );
2084 if( xServiceInfo.is() )
2086 for (const auto& [sModelService, sMatchingFilterService] : aServiceMap)
2088 if( xServiceInfo->supportsService( sModelService ) )
2090 sFilterService = sMatchingFilterService;
2091 break;
2096 SAL_WARN_IF( !sFilterService.getLength(), "xmloff.core", "no export filter for own object" );
2098 if( sFilterService.isEmpty() )
2099 return;
2101 Reference < XDocumentHandler > xHdl =
2102 new XMLEmbeddedObjectExportFilter( mxHandler );
2104 Sequence < Any > aArgs{ Any(xHdl) };
2105 Reference< document::XExporter > xExporter(
2106 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService, aArgs, m_xContext),
2107 UNO_QUERY);
2108 SAL_WARN_IF( !xExporter.is(), "xmloff.core", "can't instantiate export filter component for own object" );
2109 if( !xExporter.is() )
2110 return;
2112 xExporter->setSourceDocument( rComp );
2114 Reference<XFilter> xFilter( xExporter, UNO_QUERY );
2116 Sequence < PropertyValue > aMediaDesc( 0 );
2117 xFilter->filter( aMediaDesc );
2120 OUString SvXMLExport::GetRelativeReference(const OUString& rValue)
2122 OUString sValue( rValue );
2123 // #i65474# handling of fragment URLs ("#...") is undefined
2124 // they are stored 'as is'
2125 uno::Reference< uri::XUriReference > xUriRef;
2126 if(!sValue.isEmpty() && sValue[0] != '#')
2130 xUriRef = mpImpl->mxUriReferenceFactory->parse( rValue );
2131 if( xUriRef.is() && !xUriRef->isAbsolute() )
2133 //#i61943# relative URLs need special handling
2134 INetURLObject aTemp( mpImpl->msPackageURI );
2135 bool bWasAbsolute = false;
2136 sValue = aTemp.smartRel2Abs(sValue, bWasAbsolute ).GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
2139 catch(const uno::Exception&)
2143 if( xUriRef.is() )//no conversion for empty values or for fragments
2145 //conversion for matching schemes only
2146 if( xUriRef->getScheme() == mpImpl->msPackageURIScheme )
2148 sValue = INetURLObject::GetRelURL( msOrigFileName, sValue );
2151 return sValue;
2154 void SvXMLExport::StartElement(sal_uInt16 nPrefix,
2155 enum ::xmloff::token::XMLTokenEnum eName,
2156 bool bIgnWSOutside )
2158 StartElement(GetNamespaceMap_().GetQNameByKey( nPrefix,
2159 GetXMLToken(eName) ), bIgnWSOutside);
2162 void SvXMLExport::StartElement(const OUString& rName,
2163 bool bIgnWSOutside )
2165 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING)
2169 if( bIgnWSOutside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY))
2170 mxHandler->ignorableWhitespace( msWS );
2171 mxHandler->startElement( rName, GetXAttrList() );
2173 catch (const SAXInvalidCharacterException& e)
2175 Sequence<OUString> aPars { rName };
2176 SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, nullptr );
2178 catch (const SAXException& e)
2180 Sequence<OUString> aPars { rName };
2181 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2182 aPars, e.Message, nullptr );
2185 ClearAttrList();
2186 ++mpImpl->mDepth; // increment nesting depth counter
2189 void SvXMLExport::Characters(const OUString& rChars)
2191 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) == SvXMLErrorFlags::DO_NOTHING)
2192 return;
2196 mxHandler->characters(rChars);
2198 catch (const SAXInvalidCharacterException& e)
2200 Sequence<OUString> aPars { rChars };
2201 SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, nullptr );
2203 catch (const SAXException& e)
2205 Sequence<OUString> aPars { rChars };
2206 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2207 aPars, e.Message, nullptr );
2211 void SvXMLExport::EndElement(sal_uInt16 nPrefix,
2212 enum ::xmloff::token::XMLTokenEnum eName,
2213 bool bIgnWSInside )
2215 EndElement(GetNamespaceMap_().GetQNameByKey( nPrefix, GetXMLToken(eName) ),
2216 bIgnWSInside);
2219 void SvXMLExport::EndElement(const OUString& rName,
2220 bool bIgnWSInside )
2222 // decrement nesting depth counter & (maybe) restore namespace map
2223 --mpImpl->mDepth;
2224 if (!mpImpl->mNamespaceMaps.empty() &&
2225 (mpImpl->mNamespaceMaps.top().second == mpImpl->mDepth))
2227 mpNamespaceMap = std::move(mpImpl->mNamespaceMaps.top().first);
2228 mpImpl->mNamespaceMaps.pop();
2230 SAL_WARN_IF(!mpImpl->mNamespaceMaps.empty() &&
2231 (mpImpl->mNamespaceMaps.top().second >= mpImpl->mDepth), "xmloff.core", "SvXMLExport: NamespaceMaps corrupted");
2233 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) == SvXMLErrorFlags::DO_NOTHING)
2234 return;
2238 if( bIgnWSInside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY))
2239 mxHandler->ignorableWhitespace( msWS );
2240 mxHandler->endElement( rName );
2242 catch (const SAXException& e)
2244 Sequence<OUString> aPars { rName };
2245 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2246 aPars, e.Message, nullptr );
2250 void SvXMLExport::IgnorableWhitespace()
2252 if ((mnExportFlags & SvXMLExportFlags::PRETTY) != SvXMLExportFlags::PRETTY)
2253 return;
2255 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) == SvXMLErrorFlags::DO_NOTHING)
2256 return;
2260 mxHandler->ignorableWhitespace( msWS );
2262 catch (const SAXException& e)
2264 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2265 {}, e.Message, nullptr );
2269 void SvXMLExport::SetError(
2270 sal_Int32 nId,
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 std::mutex aMutex;
2277 std::scoped_lock 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(
2296 sal_Int32 nId,
2297 const Sequence<OUString>& rMsgParams)
2299 SetError( nId, rMsgParams, u""_ustr, nullptr );
2302 void SvXMLExport::DisposingModel()
2304 mxModel.clear();
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 // cache this because it is surprising expensive when used extensively from ScXMLExport::WriteCell
2330 if (!mpImpl->m_oODFVersion)
2331 mpImpl->m_oODFVersion = GetODFSaneDefaultVersion();
2332 return *mpImpl->m_oODFVersion;
2335 void
2336 SvXMLExport::AddAttributeIdLegacy(
2337 sal_uInt16 const nLegacyPrefix, OUString const& rValue)
2339 switch (getSaneDefaultVersion()) {
2340 case SvtSaveOptions::ODFSVER_011: // fall through
2341 case SvtSaveOptions::ODFSVER_010: break;
2342 default: // ODF 1.2: xml:id
2343 AddAttribute(XML_NAMESPACE_XML, XML_ID, rValue);
2345 // in ODF 1.1 this was form:id, anim:id, draw:id, or text:id
2346 // backward compatibility: in ODF 1.2 write _both_ id attrs
2347 AddAttribute(nLegacyPrefix, XML_ID, rValue);
2348 // FIXME: this function simply assumes that rValue is unique
2351 void
2352 SvXMLExport::AddAttributeXmlId(uno::Reference<uno::XInterface> const & i_xIfc)
2354 // check version >= 1.2
2355 switch (getSaneDefaultVersion()) {
2356 case SvtSaveOptions::ODFSVER_011: // fall through
2357 case SvtSaveOptions::ODFSVER_010: return;
2358 default: break;
2360 const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
2361 uno::UNO_QUERY);
2362 //FIXME not yet...
2363 if ( !xMeta.is() )
2364 return;
2366 const beans::StringPair mdref( xMeta->getMetadataReference() );
2367 if ( mdref.Second.isEmpty() )
2368 return;
2370 const OUString streamName = mpImpl->mStreamName;
2371 if ( !streamName.isEmpty() )
2373 if ( streamName == mdref.First )
2375 AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second );
2377 else
2379 SAL_WARN("xmloff.core","SvXMLExport::AddAttributeXmlId: invalid stream name");
2382 else
2384 // FIXME: this is ugly
2385 // there is no stream name (e.g. XSLT, flat-xml format)!
2386 // but how do we ensure uniqueness in this case?
2387 // a) just omit styles.xml ids -- they are unlikely anyway...
2388 // b) somehow find out whether we are currently exporting styles
2389 // or content, and prefix "s" or "c" => unique
2390 if ( mdref.First == "content.xml" )
2392 AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second );
2394 else
2396 SAL_INFO("xmloff.core", "SvXMLExport::AddAttributeXmlId: no stream name given: dropping styles.xml xml:id");
2401 void
2402 SvXMLExport::AddAttributesRDFa(
2403 uno::Reference<text::XTextContent> const & i_xTextContent)
2405 // check version >= 1.2
2406 switch (getSaneDefaultVersion()) {
2407 case SvtSaveOptions::ODFSVER_011: // fall through
2408 case SvtSaveOptions::ODFSVER_010: return;
2409 default: break;
2412 const uno::Reference<rdf::XMetadatable> xMeta(
2413 i_xTextContent, uno::UNO_QUERY);
2414 if (!xMeta.is() || xMeta->getMetadataReference().Second.isEmpty())
2416 return; // no xml:id => no RDFa
2419 if (!mpImpl->mpRDFaHelper)
2421 mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaExportHelper(*this) );
2423 mpImpl->mpRDFaHelper->AddRDFa(xMeta);
2426 bool SvXMLExport::exportTextNumberElement() const
2428 return mpImpl->mbExportTextNumberElement;
2431 bool SvXMLExport::SetNullDateOnUnitConverter()
2433 // if the null date has already been set, don't set it again (performance)
2434 if (!mpImpl->mbNullDateInitialized)
2435 mpImpl->mbNullDateInitialized = GetMM100UnitConverter().setNullDate(GetModel());
2437 return mpImpl->mbNullDateInitialized;
2440 OUString const & SvXMLExport::GetImageFilterName() const
2442 return msImgFilterName;
2445 void SvXMLElementExport::StartElement(
2446 const sal_uInt16 nPrefixKey,
2447 const OUString& rLName,
2448 const bool bIgnoreWhitespaceOutside )
2450 maElementName = mrExport.GetNamespaceMap().GetQNameByKey(nPrefixKey, rLName);
2451 mrExport.StartElement(maElementName, bIgnoreWhitespaceOutside);
2454 SvXMLElementExport::SvXMLElementExport(
2455 SvXMLExport& rExp,
2456 sal_uInt16 nPrefixKey,
2457 const OUString& rLName,
2458 bool bIWSOutside,
2459 bool bIWSInside )
2460 : mrExport( rExp )
2461 , mbIgnoreWhitespaceInside( bIWSInside )
2462 , mbDoSomething( true )
2464 StartElement( nPrefixKey, rLName, bIWSOutside );
2467 SvXMLElementExport::SvXMLElementExport(
2468 SvXMLExport& rExp,
2469 sal_uInt16 nPrefixKey,
2470 enum XMLTokenEnum eLName,
2471 bool bIWSOutside,
2472 bool bIWSInside )
2473 : mrExport( rExp )
2474 , mbIgnoreWhitespaceInside( bIWSInside )
2475 , mbDoSomething( true )
2477 StartElement( nPrefixKey, GetXMLToken(eLName), bIWSOutside );
2480 SvXMLElementExport::SvXMLElementExport(
2481 SvXMLExport& rExp,
2482 bool bDoSth,
2483 sal_uInt16 nPrefixKey,
2484 enum XMLTokenEnum eLName,
2485 bool bIWSOutside,
2486 bool bIWSInside )
2487 : mrExport( rExp )
2488 , mbIgnoreWhitespaceInside( bIWSInside )
2489 , mbDoSomething( bDoSth )
2491 if ( mbDoSomething )
2492 StartElement( nPrefixKey, GetXMLToken( eLName ), bIWSOutside );
2495 SvXMLElementExport::SvXMLElementExport(
2496 SvXMLExport& rExp,
2497 const OUString& rQName,
2498 bool bIWSOutside,
2499 bool bIWSInside )
2500 : mrExport( rExp )
2501 , mbIgnoreWhitespaceInside( bIWSInside )
2502 , mbDoSomething( true )
2504 maElementName = rQName;
2505 rExp.StartElement( rQName, bIWSOutside );
2508 SvXMLElementExport::~SvXMLElementExport()
2510 if ( mbDoSomething )
2512 mrExport.EndElement( maElementName, mbIgnoreWhitespaceInside );
2516 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */