nss: upgrade to release 3.73
[LibreOffice.git] / xmloff / source / core / xmlexp.cxx
blob732ea6a453fb4966f0a8660f3962a26651f1884a
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 <memory>
21 #include <sal/config.h>
22 #include <sal/log.hxx>
24 #include <stack>
25 #include <optional>
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:"
124 namespace {
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 }
151 namespace {
153 class SettingsExportFacade : public ::xmloff::XMLSettingsExportContext
155 public:
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;
177 private:
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 );
205 m_aElements.pop();
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();
218 namespace {
220 class SvXMLExportEventListener : public cppu::WeakImplHelper<
221 css::lang::XEventListener >
223 private:
224 SvXMLExport* pExport;
226 public:
227 explicit SvXMLExportEventListener(SvXMLExport* pExport);
229 // XEventListener
230 virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
235 SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport* pTempExport)
236 : pExport(pTempExport)
240 // XEventListener
241 void SAL_CALL SvXMLExportEventListener::disposing( const lang::EventObject& )
243 if (pExport)
245 pExport->DisposingModel();
246 pExport = nullptr;
250 class SvXMLExport_Impl
252 public:
253 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)
277 tools::Long mDepth;
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(':');
287 if( nSep != -1 )
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 ),
296 mDepth( 0 ),
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)
357 mpNamespaceMap->Add(
358 GetXMLToken(XML_NP_TABLE_EXT), GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT);
359 mpNamespaceMap->Add(
360 GetXMLToken(XML_NP_CALC_EXT), GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT);
361 mpNamespaceMap->Add(
362 GetXMLToken(XML_NP_DRAW_EXT), GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT);
363 mpNamespaceMap->Add(
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) )
402 mpNamespaceMap->Add(
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;
421 if ( mxModel.is() )
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");
431 if (isBaseForm)
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);
439 break;
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);
444 break;
445 default:
446 break;
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()),
463 meClass( eClass ),
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" );
471 InitCtor_();
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 );
497 InitCtor_();
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),
513 mxModel( rModel ),
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 );
533 InitCtor_();
535 if (mxNumberFormatsSupplier.is())
536 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
539 SvXMLExport::~SvXMLExport()
541 mpXMLErrors.reset();
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();
579 mpNumExport.reset();
582 if (mxEventListener.is() && mxModel.is())
583 mxModel->removeEventListener(mxEventListener);
586 // XExporter
587 void SAL_CALL SvXMLExport::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
589 mxModel.set( xDoc, UNO_QUERY );
590 if( !mxModel.is() )
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;
615 else
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 );
635 if( xFactory.is() )
639 Reference < XInterface > xIfc =
640 xFactory->createInstance("com.sun.star.xml.NamespaceMap");
641 if( xIfc.is() )
643 Reference< XNameAccess > xNamespaceMap( xIfc, UNO_QUERY );
644 if( xNamespaceMap.is() )
646 const Sequence< OUString > aPrefixes( xNamespaceMap->getElementNames() );
647 for( OUString const & prefix : aPrefixes )
649 OUString aURL;
650 if( xNamespaceMap->getByName( prefix ) >>= aURL )
651 GetNamespaceMap_().Add( prefix, aURL );
656 catch(const css::uno::Exception&)
661 // Determine model type (#i51726#)
662 DetermineModelType_();
665 // XInitialize
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;
673 rAny >>= xValue;
675 // status indicator
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;
685 // object resolver
686 uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
687 xValue, UNO_QUERY );
688 if ( xTmpObjectResolver.is() )
689 mxEmbeddedResolver = xTmpObjectResolver;
691 // document handler
692 uno::Reference<xml::sax::XDocumentHandler> xTmpDocHandler(
693 xValue, UNO_QUERY );
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(
705 xValue, UNO_QUERY );
706 if( xTmpPropertySet.is() )
707 mxExportInfo = xTmpPropertySet;
710 if( !mxExportInfo.is() )
711 return;
713 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
714 mxExportInfo->getPropertySetInfo();
715 OUString sPropName(
716 "BaseURI" );
717 if( xPropertySetInfo->hasPropertyByName(sPropName) )
719 uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
720 aAny >>= msOrigFileName;
721 mpImpl->msPackageURI = msOrigFileName;
722 mpImpl->SetSchemeOf( msOrigFileName );
724 OUString sRelPath;
725 sPropName = "StreamRelPath";
726 if( xPropertySetInfo->hasPropertyByName(sPropName) )
728 uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
729 aAny >>= sRelPath;
731 OUString sName;
732 sPropName = "StreamName";
733 if( xPropertySetInfo->hasPropertyByName(sPropName) )
735 uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
736 aAny >>= sName;
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;
770 // XFilter
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() )
775 return false;
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 ) )
794 return false;
796 else if ( rPropName == "FilterName" )
798 if( !(rValue >>= msFilterName ) )
799 return false;
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))
812 return false;
814 else if (rPropName == "DestinationShellID")
816 if (!(rValue >>= mpImpl->maDestShellID))
817 return false;
819 else if( rPropName == "ImageFilter")
821 if (!(rValue >>= msImgFilterName))
822 return false;
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 + "\"");
835 if (e.Context.is())
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()
850 // stop export
851 Sequence<OUString> aEmptySeq;
852 SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
855 OUString SAL_CALL SvXMLExport::getName( )
857 return msFilterName;
860 void SAL_CALL SvXMLExport::setName( const OUString& )
862 // do nothing, because it is not possible to set the FilterName
865 // XServiceInfo
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" };
881 OUString
882 SvXMLExport::EnsureNamespace(OUString const & i_rNamespace)
884 OUString const aPreferredPrefix("gen");
885 OUString sPrefix;
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 );
893 sal_Int32 n( 0 );
894 OUStringBuffer buf;
895 while( nKey != USHRT_MAX )
897 buf.append( aPreferredPrefix );
898 buf.append( ++n );
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) );
916 buf.append( ':' );
917 buf.append( sPrefix );
918 AddAttribute( buf.makeStringAndClear(), i_rNamespace );
920 else
922 // If there is a prefix for the namespace, reuse that.
923 sPrefix = GetNamespaceMap_().GetPrefixByKey( nKey );
925 return sPrefix;
928 void SvXMLExport::AddAttributeASCII( sal_uInt16 nPrefixKey,
929 const char *pName,
930 const char *pValue )
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) ),
961 rValue );
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(
977 rQName,
978 rValue );
981 void SvXMLExport::AddAttribute( const OUString& rQName,
982 enum ::xmloff::token::XMLTokenEnum eValue )
984 mxAttrList->AddAttribute(
985 rQName,
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);
1006 else
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());
1027 else
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
1034 // meaning.
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 )
1050 if( xAttrList.is())
1051 mxAttrList->AppendAttributeList( xAttrList );
1054 void SvXMLExport::ClearAttrList()
1056 mxAttrList->Clear();
1059 #ifdef DBG_UTIL
1060 void SvXMLExport::CheckAttrList()
1062 SAL_WARN_IF( mxAttrList->getLength(), "xmloff.core", "XMLExport::CheckAttrList: list is not empty" );
1064 #endif
1066 void SvXMLExport::ImplExportMeta()
1068 CheckAttrList();
1070 ExportMeta_();
1073 void SvXMLExport::ImplExportSettings()
1075 CheckAttrList();
1077 ::std::vector< SettingsGroup > aSettings;
1078 sal_Int32 nSettingsCount = 0;
1080 // view settings
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,
1099 true, true );
1101 SettingsExportFacade aSettingsExportContext( *this );
1102 XMLSettingsExportHelper aSettingsExportHelper( aSettingsExportContext );
1104 for (auto const& settings : aSettings)
1106 if ( !settings.aSettings.hasElements() )
1107 continue;
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()
1118 CheckAttrList();
1121 // <style:styles>
1122 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_STYLES,
1123 true, true );
1125 ExportStyles_( false );
1128 // transfer style names (+ families) TO other components (if appropriate)
1129 if( ( mnExportFlags & SvXMLExportFlags::CONTENT ) || !mxExportInfo.is() )
1130 return;
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,
1176 true, true );
1178 ExportMasterStyles_();
1181 void SvXMLExport::ImplExportContent()
1183 CheckAttrList();
1185 CheckAttrList();
1188 SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_BODY,
1189 true, true );
1191 XMLTokenEnum eClass = meClass;
1192 if( XML_TEXT_GLOBAL == eClass )
1194 AddAttribute( XML_NAMESPACE_TEXT, XML_GLOBAL,
1195 GetXMLToken( XML_TRUE ) );
1196 eClass = XML_TEXT;
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,
1204 true, true );
1206 ExportContent_();
1211 void SvXMLExport::SetBodyAttributes()
1215 static void
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;
1222 default: break;
1225 // #i115030#: disabled, the XSLT is not finished, and not available via HTTP
1226 #if 0
1227 if (SvXMLExportFlags::SETTINGS != nExportMode) // meta, content, styles
1229 rExport.AddAttribute( XML_NAMESPACE_GRDDL, XML_TRANSFORMATION,
1230 OUString("http://FIXME") );
1232 #endif
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;
1258 default:
1259 assert(!"xmloff::SvXMLExport::exportDoc(), unexpected odf default version!");
1261 return pVersion;
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 );
1272 if( xFactory.is() )
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 =
1312 mxExportInfo.is()
1313 ? PropertySetMerger_CreateInstance( mxExportInfo,
1314 xConvPropSet )
1315 : xConvPropSet;
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),
1325 UNO_QUERY);
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 ...>
1343 CheckAttrList();
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();
1360 if (pVersion)
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 )
1374 // export only meta
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;
1392 else
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 );
1406 // meta information
1407 if( mnExportFlags & SvXMLExportFlags::META )
1408 ImplExportMeta();
1410 // settings
1411 if( mnExportFlags & SvXMLExportFlags::SETTINGS )
1412 ImplExportSettings();
1414 // scripts
1415 if( mnExportFlags & SvXMLExportFlags::SCRIPTS )
1416 ExportScripts_();
1418 // font declarations
1419 if( mnExportFlags & SvXMLExportFlags::FONTDECLS )
1420 ExportFontDecls_();
1422 // styles
1423 if( mnExportFlags & SvXMLExportFlags::STYLES )
1424 ImplExportStyles();
1426 // autostyles
1427 if( mnExportFlags & SvXMLExportFlags::AUTOSTYLES )
1428 ImplExportAutoStyles();
1430 // masterstyles
1431 if( mnExportFlags & SvXMLExportFlags::MASTERSTYLES )
1432 ImplExportMasterStyles();
1434 // content
1435 if( mnExportFlags & SvXMLExportFlags::CONTENT )
1436 ImplExportContent();
1439 mxHandler->endDocument();
1441 if( bOwnGraphicResolver )
1443 uno::Reference<XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY);
1444 xComp->dispose();
1447 if( bOwnEmbeddedResolver )
1449 Reference< XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
1450 xComp->dispose();
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,
1475 UNO_QUERY);
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);
1483 pMeta->Export();
1484 } else {
1485 // office:meta
1486 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_META,
1487 true, true );
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,
1492 true, true );
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 );
1510 // initialize Basic
1511 if ( mxModel.is() )
1513 Reference< beans::XPropertySet > xPSet( mxModel, UNO_QUERY );
1514 if ( xPSet.is() )
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 );
1540 if( !xFact.is())
1541 return;
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 );
1577 if( xHatch.is() )
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 );
1606 if( xBitmap.is() )
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 );
1664 if( xMarker.is() )
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 );
1694 if( xDashes.is() )
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())
1765 return;
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();
1774 bool bAdd = false;
1775 uno::Any aAny;
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() )
1787 bAdd = true;
1788 break;
1794 if( bAdd )
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 >& )
1815 return 0;
1818 void SvXMLExport::collectDataStyles(bool bFromUsedStyles)
1820 Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(GetModel(), uno::UNO_QUERY);
1821 if (!xStyleFamiliesSupplier.is())
1822 return;
1824 Reference<container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
1825 if (!xStylesFamilies.is())
1826 return;
1828 Reference<container::XIndexAccess> xCellStyles(xStylesFamilies->getByName("CellStyles"), uno::UNO_QUERY);
1829 if (!xCellStyles.is())
1830 return;
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())
1837 continue;
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*/ )
1851 if(mpNumExport)
1852 mpNumExport->SetUsed(nNumberFormat);
1855 void SvXMLExport::exportDataStyles()
1857 if(mpNumExport)
1858 mpNumExport->Export(false);
1861 void SvXMLExport::exportAutoDataStyles()
1863 if(mpNumExport)
1864 mpNumExport->Export(true);
1866 if (mxFormExport.is())
1867 mxFormExport->exportAutoControlNumberStyles();
1870 OUString SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ ) const
1872 OUString sTemp;
1873 if(mpNumExport)
1874 sTemp = mpNumExport->GetStyleName(nNumberFormat);
1875 return sTemp;
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)
1890 OUString sURL;
1892 Graphic aGraphic(rxGraphic);
1893 OUString aOriginURL = aGraphic.getOriginURL();
1895 if (!aOriginURL.isEmpty())
1897 sURL = GetRelativeReference(aOriginURL);
1899 else
1901 if (mxGraphicStorageHandler.is())
1903 if (!(getExportFlags() & SvXMLExportFlags::EMBEDDED))
1904 sURL = mxGraphicStorageHandler->saveGraphicByName(rxGraphic, rOutMimeType, rRequestedName);
1907 return sURL;
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);
1918 return true;
1922 return false;
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);
1942 return false;
1945 OUString SvXMLExport::AddEmbeddedObject( const OUString& rEmbeddedObjectURL )
1947 OUString sRet;
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);
1954 else
1955 sRet = GetRelativeReference( rEmbeddedObjectURL );
1957 return sRet;
1960 bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString& rEmbeddedObjectURL )
1962 bool bRet = false;
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 );
1968 if( xNA.is() )
1970 Any aAny = xNA->getByName( rEmbeddedObjectURL );
1971 Reference < XInputStream > xIn;
1972 aAny >>= xIn;
1973 if( xIn.is() )
1975 XMLBase64Export aBase64Exp( *this );
1976 bRet = aBase64Exp.exportOfficeBinaryDataElement( xIn );
1981 return bRet;
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))
2010 uno::Any aAny;
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));
2029 else {
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;
2066 // XUnoTunnel & co
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 );
2087 break;
2089 pEntry++;
2093 SAL_WARN_IF( !sFilterService.getLength(), "xmloff.core", "no export filter for own object" );
2095 if( sFilterService.isEmpty() )
2096 return;
2098 Reference < XDocumentHandler > xHdl =
2099 new XMLEmbeddedObjectExportFilter( mxHandler );
2101 Sequence < Any > aArgs( 1 );
2102 aArgs[0] <<= xHdl;
2104 Reference< document::XExporter > xExporter(
2105 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService, aArgs, m_xContext),
2106 UNO_QUERY);
2107 SAL_WARN_IF( !xExporter.is(), "xmloff.core", "can't instantiate export filter component for own object" );
2108 if( !xExporter.is() )
2109 return;
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 );
2150 return 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 );
2184 ClearAttrList();
2185 ++mpImpl->mDepth; // increment nesting depth counter
2188 void SvXMLExport::Characters(const OUString& rChars)
2190 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) == SvXMLErrorFlags::DO_NOTHING)
2191 return;
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,
2212 bool bIgnWSInside )
2214 EndElement(GetNamespaceMap_().GetQNameByKey( nPrefix, GetXMLToken(eName) ),
2215 bIgnWSInside);
2218 void SvXMLExport::EndElement(const OUString& rName,
2219 bool bIgnWSInside )
2221 // decrement nesting depth counter & (maybe) restore namespace map
2222 --mpImpl->mDepth;
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)
2233 return;
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)
2252 return;
2254 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) == SvXMLErrorFlags::DO_NOTHING)
2255 return;
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(
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 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(
2296 sal_Int32 nId,
2297 const Sequence<OUString>& rMsgParams)
2299 SetError( nId, rMsgParams, "", 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 if (mpImpl->m_oOverrideODFVersion)
2331 return *mpImpl->m_oOverrideODFVersion;
2333 return mpImpl->maSaveOptions.GetODFSaneDefaultVersion();
2336 void
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
2352 void
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;
2359 default: break;
2361 const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
2362 uno::UNO_QUERY);
2363 //FIXME not yet...
2364 if ( !xMeta.is() )
2365 return;
2367 const beans::StringPair mdref( xMeta->getMetadataReference() );
2368 if ( mdref.Second.isEmpty() )
2369 return;
2371 const OUString streamName = mpImpl->mStreamName;
2372 if ( !streamName.isEmpty() )
2374 if ( streamName == mdref.First )
2376 AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second );
2378 else
2380 SAL_WARN("xmloff.core","SvXMLExport::AddAttributeXmlId: invalid stream name");
2383 else
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 );
2395 else
2397 SAL_INFO("xmloff.core", "SvXMLExport::AddAttributeXmlId: no stream name given: dropping styles.xml xml:id");
2402 void
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;
2410 default: break;
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(
2456 SvXMLExport& rExp,
2457 sal_uInt16 nPrefixKey,
2458 const char *pLName,
2459 bool bIWSOutside,
2460 bool bIWSInside )
2461 : mrExport( rExp )
2462 , maElementName()
2463 , mbIgnoreWhitespaceInside( bIWSInside )
2464 , mbDoSomething( true )
2466 const OUString sLName( OUString::createFromAscii( pLName ) );
2467 StartElement( nPrefixKey, sLName, bIWSOutside );
2470 SvXMLElementExport::SvXMLElementExport(
2471 SvXMLExport& rExp,
2472 sal_uInt16 nPrefixKey,
2473 const OUString& rLName,
2474 bool bIWSOutside,
2475 bool bIWSInside )
2476 : mrExport( rExp )
2477 , maElementName()
2478 , mbIgnoreWhitespaceInside( bIWSInside )
2479 , mbDoSomething( true )
2481 StartElement( nPrefixKey, rLName, bIWSOutside );
2484 SvXMLElementExport::SvXMLElementExport(
2485 SvXMLExport& rExp,
2486 sal_uInt16 nPrefixKey,
2487 enum XMLTokenEnum eLName,
2488 bool bIWSOutside,
2489 bool bIWSInside )
2490 : mrExport( rExp )
2491 , maElementName()
2492 , mbIgnoreWhitespaceInside( bIWSInside )
2493 , mbDoSomething( true )
2495 StartElement( nPrefixKey, GetXMLToken(eLName), bIWSOutside );
2498 SvXMLElementExport::SvXMLElementExport(
2499 SvXMLExport& rExp,
2500 bool bDoSth,
2501 sal_uInt16 nPrefixKey,
2502 enum XMLTokenEnum eLName,
2503 bool bIWSOutside,
2504 bool bIWSInside )
2505 : mrExport( rExp )
2506 , maElementName()
2507 , mbIgnoreWhitespaceInside( bIWSInside )
2508 , mbDoSomething( bDoSth )
2510 if ( mbDoSomething )
2511 StartElement( nPrefixKey, GetXMLToken( eLName ), bIWSOutside );
2514 SvXMLElementExport::SvXMLElementExport(
2515 SvXMLExport& rExp,
2516 const OUString& rQName,
2517 bool bIWSOutside,
2518 bool bIWSInside )
2519 : mrExport( rExp )
2520 , maElementName()
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: */