Bump version to 6.4.0.12
[LibreOffice.git] / xmloff / source / core / xmlexp.cxx
bloba314b6a39670f06d323fc529ec460cd0f6fafe65
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>
26 #include <officecfg/Office/Common.hxx>
27 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
28 #include <osl/mutex.hxx>
29 #include <tools/urlobj.hxx>
30 #include <vcl/graph.hxx>
31 #include <comphelper/genericpropertyset.hxx>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/io/XInputStream.hpp>
34 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
35 #include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
36 #include <com/sun/star/xml/sax/SAXInvalidCharacterException.hpp>
37 #include <com/sun/star/uri/XUriReferenceFactory.hpp>
38 #include <com/sun/star/uri/UriReferenceFactory.hpp>
39 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
40 #include <com/sun/star/util/MeasureUnit.hpp>
41 #include <i18nlangtag/languagetag.hxx>
42 #include <comphelper/processfactory.hxx>
43 #include <comphelper/propertysetinfo.hxx>
44 #include <xmloff/attrlist.hxx>
45 #include <xmloff/nmspmap.hxx>
46 #include <xmloff/xmluconv.hxx>
47 #include <xmloff/xmlnmspe.hxx>
48 #include <xmloff/xmltoken.hxx>
49 #include <xmloff/xmlexp.hxx>
50 #include <xmloff/xmlnumfe.hxx>
51 #include <xmloff/xmlmetae.hxx>
52 #include <xmloff/XMLSettingsExportContext.hxx>
53 #include <xmloff/XMLEventExport.hxx>
54 #include <xmloff/ProgressBarHelper.hxx>
55 #include <XMLStarBasicExportHandler.hxx>
56 #include <XMLScriptExportHandler.hxx>
57 #include <xmloff/SettingsExportHelper.hxx>
58 #include <com/sun/star/document/XEventsSupplier.hpp>
59 #include <com/sun/star/document/XViewDataSupplier.hpp>
60 #include <com/sun/star/frame/XModel.hpp>
61 #include <xmloff/GradientStyle.hxx>
62 #include <xmloff/HatchStyle.hxx>
63 #include <xmloff/ImageStyle.hxx>
64 #include <TransGradientStyle.hxx>
65 #include <xmloff/MarkerStyle.hxx>
66 #include <xmloff/DashStyle.hxx>
67 #include <xmloff/XMLFontAutoStylePool.hxx>
68 #include <XMLImageMapExport.hxx>
69 #include <XMLBase64Export.hxx>
70 #include <xmloff/xmlerror.hxx>
71 #include <com/sun/star/style/XStyle.hpp>
72 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
73 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
74 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
75 #include <com/sun/star/beans/PropertyAttribute.hpp>
76 #include <xmloff/XMLFilterServiceNames.h>
77 #include <xmloff/XMLEmbeddedObjectExportFilter.hxx>
78 #include <XMLBasicExportFilter.hxx>
79 #include <cppuhelper/exc_hlp.hxx>
80 #include <cppuhelper/implbase.hxx>
81 #include <cppuhelper/supportsservice.hxx>
82 #include <comphelper/extract.hxx>
83 #include <PropertySetMerger.hxx>
85 #include <unotools/docinfohelper.hxx>
86 #include <com/sun/star/document/XDocumentProperties.hpp>
87 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
88 #include <com/sun/star/document/XMLOasisBasicExporter.hpp>
89 #include <com/sun/star/embed/XEncryptionProtectedSource2.hpp>
90 #include <com/sun/star/document/XGraphicStorageHandler.hpp>
91 #include <com/sun/star/rdf/XMetadatable.hpp>
92 #include <RDFaExportHelper.hxx>
94 #include <comphelper/xmltools.hxx>
95 #include <comphelper/graphicmimetype.hxx>
97 using namespace ::osl;
98 using namespace ::com::sun::star;
99 using namespace ::com::sun::star::uno;
100 using namespace ::com::sun::star::frame;
101 using namespace ::com::sun::star::container;
102 using namespace ::com::sun::star::lang;
103 using namespace ::com::sun::star::document;
104 using namespace ::com::sun::star::beans;
105 using namespace ::com::sun::star::xml::sax;
106 using namespace ::com::sun::star::io;
107 using namespace ::xmloff::token;
109 sal_Char const sXML_1_2[] = "1.2";
111 #define XML_MODEL_SERVICE_WRITER "com.sun.star.text.TextDocument"
112 #define XML_MODEL_SERVICE_CALC "com.sun.star.sheet.SpreadsheetDocument"
113 #define XML_MODEL_SERVICE_DRAW "com.sun.star.drawing.DrawingDocument"
114 #define XML_MODEL_SERVICE_IMPRESS "com.sun.star.presentation.PresentationDocument"
115 #define XML_MODEL_SERVICE_MATH "com.sun.star.formula.FormulaProperties"
116 #define XML_MODEL_SERVICE_CHART "com.sun.star.chart.ChartDocument"
118 #define XML_USEPRETTYPRINTING "UsePrettyPrinting"
120 #define XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE "vnd.sun.star.GraphicObject:"
121 #define XML_EMBEDDEDOBJECT_URL_BASE "vnd.sun.star.EmbeddedObject:"
123 namespace {
125 struct XMLServiceMapEntry_Impl
127 const sal_Char *sModelService;
128 sal_Int32 const nModelServiceLen;
129 const sal_Char *sFilterService;
130 sal_Int32 const nFilterServiceLen;
135 #define SERVICE_MAP_ENTRY( app ) \
136 { XML_MODEL_SERVICE_##app, sizeof(XML_MODEL_SERVICE_##app)-1, \
137 XML_EXPORT_FILTER_##app, sizeof(XML_EXPORT_FILTER_##app)-1 }
139 const XMLServiceMapEntry_Impl aServiceMap[] =
141 SERVICE_MAP_ENTRY( WRITER ),
142 SERVICE_MAP_ENTRY( CALC ),
143 SERVICE_MAP_ENTRY( IMPRESS ),// Impress supports DrawingDocument, too, so
144 SERVICE_MAP_ENTRY( DRAW ), // it must appear before Draw
145 SERVICE_MAP_ENTRY( MATH ),
146 SERVICE_MAP_ENTRY( CHART ),
147 { nullptr, 0, nullptr, 0 }
150 class SettingsExportFacade : public ::xmloff::XMLSettingsExportContext
152 public:
153 explicit SettingsExportFacade( SvXMLExport& i_rExport )
154 :m_rExport( i_rExport )
158 virtual ~SettingsExportFacade()
162 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
163 const OUString& i_rValue ) override;
164 virtual void AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName,
165 enum ::xmloff::token::XMLTokenEnum i_eValue ) override;
167 virtual void StartElement( enum ::xmloff::token::XMLTokenEnum i_eName ) override;
168 virtual void EndElement( const bool i_bIgnoreWhitespace ) override;
170 virtual void Characters( const OUString& i_rCharacters ) override;
172 virtual css::uno::Reference< css::uno::XComponentContext >
173 GetComponentContext() const override;
174 private:
175 SvXMLExport& m_rExport;
176 ::std::stack< OUString > m_aElements;
179 void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, const OUString& i_rValue )
181 m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_rValue );
184 void SettingsExportFacade::AddAttribute( enum ::xmloff::token::XMLTokenEnum i_eName, enum ::xmloff::token::XMLTokenEnum i_eValue )
186 m_rExport.AddAttribute( XML_NAMESPACE_CONFIG, i_eName, i_eValue );
189 void SettingsExportFacade::StartElement( enum ::xmloff::token::XMLTokenEnum i_eName )
191 const OUString sElementName( m_rExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_CONFIG, GetXMLToken( i_eName ) ) );
192 m_rExport.StartElement( sElementName, true/*i_bIgnoreWhitespace*/ );
193 m_aElements.push( sElementName );
196 void SettingsExportFacade::EndElement( const bool i_bIgnoreWhitespace )
198 const OUString sElementName( m_aElements.top() );
199 m_rExport.EndElement( sElementName, i_bIgnoreWhitespace );
200 m_aElements.pop();
203 void SettingsExportFacade::Characters( const OUString& i_rCharacters )
205 m_rExport.GetDocHandler()->characters( i_rCharacters );
208 Reference< XComponentContext > SettingsExportFacade::GetComponentContext() const
210 return m_rExport.getComponentContext();
213 class SvXMLExportEventListener : public cppu::WeakImplHelper<
214 css::lang::XEventListener >
216 private:
217 SvXMLExport* pExport;
219 public:
220 explicit SvXMLExportEventListener(SvXMLExport* pExport);
222 // XEventListener
223 virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
226 SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport* pTempExport)
227 : pExport(pTempExport)
231 // XEventListener
232 void SAL_CALL SvXMLExportEventListener::disposing( const lang::EventObject& )
234 if (pExport)
236 pExport->DisposingModel();
237 pExport = nullptr;
241 class SvXMLExport_Impl
243 public:
244 SvXMLExport_Impl();
246 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper;
247 uno::Reference< uri::XUriReferenceFactory > mxUriReferenceFactory;
248 OUString msPackageURI;
249 OUString msPackageURIScheme;
250 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
251 bool mbOutlineStyleAsNormalListStyle;
252 bool mbSaveBackwardCompatibleODF;
254 uno::Reference< embed::XStorage > mxTargetStorage;
256 SvtSaveOptions const maSaveOptions;
258 /// name of stream in package, e.g., "content.xml"
259 OUString mStreamName;
261 OUString maSrcShellID;
262 OUString maDestShellID;
264 /// stack of backed up namespace maps
265 /// long: depth at which namespace map has been backed up into the stack
266 ::std::stack< ::std::pair< std::unique_ptr<SvXMLNamespaceMap>, long > > mNamespaceMaps;
267 /// counts depth (number of open elements/start tags)
268 long mDepth;
270 ::std::unique_ptr< ::xmloff::RDFaExportHelper> mpRDFaHelper;
272 bool mbExportTextNumberElement;
273 bool mbNullDateInitialized;
275 void SetSchemeOf( const OUString& rOrigFileName )
277 sal_Int32 nSep = rOrigFileName.indexOf(':');
278 if( nSep != -1 )
279 msPackageURIScheme = rOrigFileName.copy( 0, nSep );
283 SvXMLExport_Impl::SvXMLExport_Impl()
284 : mxUriReferenceFactory( uri::UriReferenceFactory::create(comphelper::getProcessComponentContext()) ),
285 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
286 mbOutlineStyleAsNormalListStyle( false ),
287 mbSaveBackwardCompatibleODF( true ),
288 mDepth( 0 ),
289 mbExportTextNumberElement( false ),
290 mbNullDateInitialized( false )
294 void SvXMLExport::SetDocHandler( const uno::Reference< xml::sax::XDocumentHandler > &rHandler )
296 mxHandler = rHandler;
297 mxExtHandler.set( mxHandler, UNO_QUERY );
300 void SvXMLExport::InitCtor_()
302 // note: it is not necessary to add XML_NP_XML (it is declared implicitly)
303 if( getExportFlags() & ~SvXMLExportFlags::OASIS )
305 mpNamespaceMap->Add( GetXMLToken(XML_NP_OFFICE), GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
306 mpNamespaceMap->Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
308 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::FONTDECLS) )
310 mpNamespaceMap->Add( GetXMLToken(XML_NP_FO), GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
312 if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS|SvXMLExportFlags::SETTINGS) )
314 mpNamespaceMap->Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
316 if( getExportFlags() & SvXMLExportFlags::SETTINGS )
318 mpNamespaceMap->Add( GetXMLToken(XML_NP_CONFIG), GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
321 if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
323 mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
324 mpNamespaceMap->Add( GetXMLToken(XML_NP_META), GetXMLToken(XML_N_META), XML_NAMESPACE_META );
326 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::FONTDECLS) )
328 mpNamespaceMap->Add( GetXMLToken(XML_NP_STYLE), GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
331 // namespaces for documents
332 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
334 mpNamespaceMap->Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
335 mpNamespaceMap->Add( GetXMLToken(XML_NP_TEXT), GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT );
336 mpNamespaceMap->Add( GetXMLToken(XML_NP_DRAW), GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW );
337 mpNamespaceMap->Add( GetXMLToken(XML_NP_DR3D), GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D );
338 mpNamespaceMap->Add( GetXMLToken(XML_NP_SVG), GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG );
339 mpNamespaceMap->Add( GetXMLToken(XML_NP_CHART), GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART );
340 mpNamespaceMap->Add( GetXMLToken(XML_NP_RPT), GetXMLToken(XML_N_RPT), XML_NAMESPACE_REPORT );
341 mpNamespaceMap->Add( GetXMLToken(XML_NP_TABLE), GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE );
342 mpNamespaceMap->Add( GetXMLToken(XML_NP_NUMBER),GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER );
343 mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOW), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
344 mpNamespaceMap->Add( GetXMLToken(XML_NP_OOOC), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
345 mpNamespaceMap->Add( GetXMLToken(XML_NP_OF), GetXMLToken(XML_N_OF), XML_NAMESPACE_OF );
347 if (getDefaultVersion() > SvtSaveOptions::ODFVER_012)
349 mpNamespaceMap->Add(
350 GetXMLToken(XML_NP_TABLE_EXT), GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT);
351 mpNamespaceMap->Add(
352 GetXMLToken(XML_NP_CALC_EXT), GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT);
353 mpNamespaceMap->Add(
354 GetXMLToken(XML_NP_DRAW_EXT), GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT);
355 mpNamespaceMap->Add(
356 GetXMLToken(XML_NP_LO_EXT), GetXMLToken(XML_N_LO_EXT),
357 XML_NAMESPACE_LO_EXT);
358 mpNamespaceMap->Add( GetXMLToken(XML_NP_FIELD), GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD );
361 if( getExportFlags() & (SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
363 mpNamespaceMap->Add( GetXMLToken(XML_NP_MATH), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
364 mpNamespaceMap->Add( GetXMLToken(XML_NP_FORM), GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM );
366 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SCRIPTS) )
368 mpNamespaceMap->Add( GetXMLToken(XML_NP_SCRIPT), GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT );
369 mpNamespaceMap->Add( GetXMLToken(XML_NP_DOM), GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
371 if( getExportFlags() & SvXMLExportFlags::CONTENT )
373 mpNamespaceMap->Add( GetXMLToken(XML_NP_XFORMS_1_0), GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS );
374 mpNamespaceMap->Add( GetXMLToken(XML_NP_XSD), GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD );
375 mpNamespaceMap->Add( GetXMLToken(XML_NP_XSI), GetXMLToken(XML_N_XSI), XML_NAMESPACE_XSI );
376 mpNamespaceMap->Add( GetXMLToken(XML_NP_FORMX), GetXMLToken(XML_N_FORMX), XML_NAMESPACE_FORMX );
379 // RDFa: needed for content and header/footer styles
380 if( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
382 mpNamespaceMap->Add( GetXMLToken(XML_NP_XHTML),
383 GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML );
385 // GRDDL: to convert RDFa and meta.xml to RDF
386 if( getExportFlags() & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES|SvXMLExportFlags::CONTENT) )
388 mpNamespaceMap->Add( GetXMLToken(XML_NP_GRDDL),
389 GetXMLToken(XML_N_GRDDL), XML_NAMESPACE_GRDDL );
391 // CSS Text Level 3 for distributed text justification.
392 if ( getExportFlags() & (SvXMLExportFlags::STYLES|SvXMLExportFlags::AUTOSTYLES|SvXMLExportFlags::MASTERSTYLES) )
394 mpNamespaceMap->Add(
395 GetXMLToken(XML_NP_CSS3TEXT), GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT );
398 if (mxModel.is() && !mxEventListener.is())
400 mxEventListener.set( new SvXMLExportEventListener(this));
401 mxModel->addEventListener(mxEventListener);
404 // Determine model type (#i51726#)
405 DetermineModelType_();
407 // cl: but only if we do export to current oasis format, old openoffice format *must* always be compatible
408 if( getExportFlags() & SvXMLExportFlags::OASIS )
410 mpImpl->mbSaveBackwardCompatibleODF =
411 officecfg::Office::Common::Save::Document::
412 SaveBackwardCompatibleODF::get( comphelper::getProcessComponentContext() );
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 );
427 SvXMLExport::SvXMLExport(
428 sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/,
429 const uno::Reference< uno::XComponentContext >& xContext,
430 OUString const & implementationName,
431 const enum XMLTokenEnum eClass, SvXMLExportFlags nExportFlags )
432 : mpImpl( new SvXMLExport_Impl ),
433 m_xContext(xContext), m_implementationName(implementationName),
434 mxAttrList( new SvXMLAttributeList ),
435 mpNamespaceMap( new SvXMLNamespaceMap ),
436 maUnitConv( xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit ),
437 meClass( eClass ),
438 mnExportFlags( nExportFlags ),
439 mnErrorFlags( SvXMLErrorFlags::NO ),
440 msWS( GetXMLToken(XML_WS) ),
441 mbSaveLinkedSections(true),
442 mbAutoStylesCollected(false)
444 SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" );
445 InitCtor_();
448 SvXMLExport::SvXMLExport(
449 const css::uno::Reference< css::uno::XComponentContext >& xContext,
450 OUString const & implementationName,
451 const OUString &rFileName,
452 sal_Int16 const eDefaultMeasureUnit /*css::util::MeasureUnit*/,
453 const uno::Reference< xml::sax::XDocumentHandler > & rHandler)
454 : mpImpl( new SvXMLExport_Impl ),
455 m_xContext(xContext), m_implementationName(implementationName),
456 mxHandler( rHandler ),
457 mxExtHandler( rHandler, uno::UNO_QUERY ),
458 mxAttrList( new SvXMLAttributeList ),
459 msOrigFileName( rFileName ),
460 mpNamespaceMap( new SvXMLNamespaceMap ),
461 maUnitConv( xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit ),
462 meClass( XML_TOKEN_INVALID ),
463 mnExportFlags( SvXMLExportFlags::NONE ),
464 mnErrorFlags( SvXMLErrorFlags::NO ),
465 msWS( GetXMLToken(XML_WS) ),
466 mbSaveLinkedSections(true),
467 mbAutoStylesCollected(false)
469 SAL_WARN_IF( !xContext.is(), "xmloff.core", "got no service manager" );
470 mpImpl->SetSchemeOf( msOrigFileName );
471 InitCtor_();
473 if (mxNumberFormatsSupplier.is())
474 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
477 SvXMLExport::SvXMLExport(
478 const css::uno::Reference< css::uno::XComponentContext >& xContext,
479 OUString const & implementationName,
480 const OUString &rFileName,
481 const uno::Reference< xml::sax::XDocumentHandler > & rHandler,
482 const Reference< XModel >& rModel,
483 FieldUnit const eDefaultFieldUnit,
484 SvXMLExportFlags nExportFlag)
485 : mpImpl( new SvXMLExport_Impl ),
486 m_xContext(xContext), m_implementationName(implementationName),
487 mxModel( rModel ),
488 mxHandler( rHandler ),
489 mxExtHandler( rHandler, uno::UNO_QUERY ),
490 mxNumberFormatsSupplier (rModel, uno::UNO_QUERY),
491 mxAttrList( new SvXMLAttributeList ),
492 msOrigFileName( rFileName ),
493 mpNamespaceMap( new SvXMLNamespaceMap ),
494 maUnitConv( xContext,
495 util::MeasureUnit::MM_100TH,
496 SvXMLUnitConverter::GetMeasureUnit(eDefaultFieldUnit) ),
497 meClass( XML_TOKEN_INVALID ),
498 mnExportFlags( nExportFlag ),
499 mnErrorFlags( SvXMLErrorFlags::NO ),
500 msWS( GetXMLToken(XML_WS) ),
501 mbSaveLinkedSections(true),
502 mbAutoStylesCollected(false)
504 SAL_WARN_IF(!xContext.is(), "xmloff.core", "got no service manager" );
505 mpImpl->SetSchemeOf( msOrigFileName );
506 InitCtor_();
508 if (mxNumberFormatsSupplier.is())
509 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
512 SvXMLExport::~SvXMLExport()
514 mpXMLErrors.reset();
515 mpImageMapExport.reset();
516 mpEventExport.reset();
517 mpNamespaceMap.reset();
518 if (mpProgressBarHelper || mpNumExport)
520 if (mxExportInfo.is())
522 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
523 if (xPropertySetInfo.is())
525 if (mpProgressBarHelper)
527 OUString sProgressMax(XML_PROGRESSMAX);
528 OUString sProgressCurrent(XML_PROGRESSCURRENT);
529 OUString sRepeat(XML_PROGRESSREPEAT);
530 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
531 xPropertySetInfo->hasPropertyByName(sProgressCurrent))
533 sal_Int32 nProgressMax(mpProgressBarHelper->GetReference());
534 sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue());
535 mxExportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax));
536 mxExportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent));
538 if (xPropertySetInfo->hasPropertyByName(sRepeat))
539 mxExportInfo->setPropertyValue(sRepeat, css::uno::makeAny(mpProgressBarHelper->GetRepeat()));
541 if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES)))
543 OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES);
544 if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats))
546 mxExportInfo->setPropertyValue(sWrittenNumberFormats, Any(mpNumExport->GetWasUsed()));
551 mpProgressBarHelper.reset();
552 mpNumExport.reset();
555 if (mxEventListener.is() && mxModel.is())
556 mxModel->removeEventListener(mxEventListener);
559 // XExporter
560 void SAL_CALL SvXMLExport::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
562 mxModel.set( xDoc, UNO_QUERY );
563 if( !mxModel.is() )
564 throw lang::IllegalArgumentException();
565 if (mxModel.is() && ! mxEventListener.is())
567 mxEventListener.set( new SvXMLExportEventListener(this));
568 mxModel->addEventListener(mxEventListener);
571 if(!mxNumberFormatsSupplier.is() )
573 mxNumberFormatsSupplier.set(mxModel, css::uno::UNO_QUERY);
574 if(mxNumberFormatsSupplier.is() && mxHandler.is())
575 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
577 if (mxExportInfo.is())
579 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
580 if (xPropertySetInfo.is())
582 OUString sUsePrettyPrinting(XML_USEPRETTYPRINTING);
583 if (xPropertySetInfo->hasPropertyByName(sUsePrettyPrinting))
585 uno::Any aAny = mxExportInfo->getPropertyValue(sUsePrettyPrinting);
586 if (::cppu::any2bool(aAny))
587 mnExportFlags |= SvXMLExportFlags::PRETTY;
588 else
589 mnExportFlags &= ~SvXMLExportFlags::PRETTY;
592 if (mpNumExport && (mnExportFlags & (SvXMLExportFlags::AUTOSTYLES | SvXMLExportFlags::STYLES)))
594 OUString sWrittenNumberFormats(XML_WRITTENNUMBERSTYLES);
595 if (xPropertySetInfo->hasPropertyByName(sWrittenNumberFormats))
597 uno::Any aAny = mxExportInfo->getPropertyValue(sWrittenNumberFormats);
598 uno::Sequence<sal_Int32> aWasUsed;
599 if(aAny >>= aWasUsed)
600 mpNumExport->SetWasUsed(aWasUsed);
606 if ( mpImpl->mbSaveBackwardCompatibleODF )
607 mnExportFlags |= SvXMLExportFlags::SAVEBACKWARDCOMPATIBLE;
608 else
609 mnExportFlags &= ~SvXMLExportFlags::SAVEBACKWARDCOMPATIBLE;
611 // namespaces for user defined attributes
612 Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
613 if( xFactory.is() )
617 Reference < XInterface > xIfc =
618 xFactory->createInstance("com.sun.star.xml.NamespaceMap");
619 if( xIfc.is() )
621 Reference< XNameAccess > xNamespaceMap( xIfc, UNO_QUERY );
622 if( xNamespaceMap.is() )
624 const Sequence< OUString > aPrefixes( xNamespaceMap->getElementNames() );
625 for( OUString const & prefix : aPrefixes )
627 OUString aURL;
628 if( xNamespaceMap->getByName( prefix ) >>= aURL )
629 GetNamespaceMap_().Add( prefix, aURL );
634 catch(const css::uno::Exception&)
639 // Determine model type (#i51726#)
640 DetermineModelType_();
643 // XInitialize
644 void SAL_CALL SvXMLExport::initialize( const uno::Sequence< uno::Any >& aArguments )
646 // #93186# we need to queryInterface every single Any with any expected outcome. This variable hold the queryInterface results.
648 for( const auto& rAny : aArguments )
650 Reference<XInterface> xValue;
651 rAny >>= xValue;
653 // status indicator
654 uno::Reference<task::XStatusIndicator> xTmpStatus( xValue, UNO_QUERY );
655 if ( xTmpStatus.is() )
656 mxStatusIndicator = xTmpStatus;
658 // graphic storage handler
659 uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY);
660 if (xGraphicStorageHandler.is())
661 mxGraphicStorageHandler = xGraphicStorageHandler;
663 // object resolver
664 uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
665 xValue, UNO_QUERY );
666 if ( xTmpObjectResolver.is() )
667 mxEmbeddedResolver = xTmpObjectResolver;
669 // document handler
670 uno::Reference<xml::sax::XDocumentHandler> xTmpDocHandler(
671 xValue, UNO_QUERY );
672 if( xTmpDocHandler.is() )
674 mxHandler = xTmpDocHandler;
675 rAny >>= mxExtHandler;
677 if (mxNumberFormatsSupplier.is() && mpNumExport == nullptr)
678 mpNumExport.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier) );
681 // property set to transport data across
682 uno::Reference<beans::XPropertySet> xTmpPropertySet(
683 xValue, UNO_QUERY );
684 if( xTmpPropertySet.is() )
685 mxExportInfo = xTmpPropertySet;
688 if( !mxExportInfo.is() )
689 return;
691 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo =
692 mxExportInfo->getPropertySetInfo();
693 OUString sPropName(
694 "BaseURI" );
695 if( xPropertySetInfo->hasPropertyByName(sPropName) )
697 uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
698 aAny >>= msOrigFileName;
699 mpImpl->msPackageURI = msOrigFileName;
700 mpImpl->SetSchemeOf( msOrigFileName );
702 OUString sRelPath;
703 sPropName = "StreamRelPath";
704 if( xPropertySetInfo->hasPropertyByName(sPropName) )
706 uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
707 aAny >>= sRelPath;
709 OUString sName;
710 sPropName = "StreamName";
711 if( xPropertySetInfo->hasPropertyByName(sPropName) )
713 uno::Any aAny = mxExportInfo->getPropertyValue(sPropName);
714 aAny >>= sName;
716 if( !msOrigFileName.isEmpty() && !sName.isEmpty() )
718 INetURLObject aBaseURL( msOrigFileName );
719 if( !sRelPath.isEmpty() )
720 aBaseURL.insertName( sRelPath );
721 aBaseURL.insertName( sName );
722 msOrigFileName = aBaseURL.GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
724 mpImpl->mStreamName = sName; // Note: may be empty (XSLT)
726 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
727 const OUString sOutlineStyleAsNormalListStyle(
728 "OutlineStyleAsNormalListStyle" );
729 if( xPropertySetInfo->hasPropertyByName( sOutlineStyleAsNormalListStyle ) )
731 uno::Any aAny = mxExportInfo->getPropertyValue( sOutlineStyleAsNormalListStyle );
732 aAny >>= mpImpl->mbOutlineStyleAsNormalListStyle;
735 OUString sTargetStorage( "TargetStorage" );
736 if( xPropertySetInfo->hasPropertyByName( sTargetStorage ) )
737 mxExportInfo->getPropertyValue( sTargetStorage ) >>= mpImpl->mxTargetStorage;
739 const OUString sExportTextNumberElement(
740 "ExportTextNumberElement" );
741 if( xPropertySetInfo->hasPropertyByName( sExportTextNumberElement ) )
743 uno::Any aAny = mxExportInfo->getPropertyValue( sExportTextNumberElement );
744 aAny >>= mpImpl->mbExportTextNumberElement;
748 // XFilter
749 sal_Bool SAL_CALL SvXMLExport::filter( const uno::Sequence< beans::PropertyValue >& aDescriptor )
751 // check for xHandler first... should have been supplied in initialize
752 if( !mxHandler.is() )
753 return false;
757 const SvXMLExportFlags nTest =
758 SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS;
759 if( (mnExportFlags & nTest) == nTest && msOrigFileName.isEmpty() )
761 // evaluate descriptor only for flat files and if a base URI
762 // has not been provided already
764 for( const auto& rProp : aDescriptor )
766 const OUString& rPropName = rProp.Name;
767 const Any& rValue = rProp.Value;
769 if ( rPropName == "FileName" )
771 if( !(rValue >>= msOrigFileName ) )
772 return false;
774 else if ( rPropName == "FilterName" )
776 if( !(rValue >>= msFilterName ) )
777 return false;
782 for( const auto& rProp : aDescriptor )
784 const OUString& rPropName = rProp.Name;
785 const Any& rValue = rProp.Value;
787 if (rPropName == "SourceShellID")
789 if (!(rValue >>= mpImpl->maSrcShellID))
790 return false;
792 else if (rPropName == "DestinationShellID")
794 if (!(rValue >>= mpImpl->maDestShellID))
795 return false;
797 else if( rPropName == "ImageFilter")
799 if (!(rValue >>= msImgFilterName))
800 return false;
805 exportDoc( meClass );
807 catch(const uno::Exception& e)
809 // We must catch exceptions, because according to the
810 // API definition export must not throw one!
811 css::uno::Any ex(cppu::getCaughtException());
812 OUString sMessage( ex.getValueTypeName() + ": \"" + e.Message + "\"");
813 if (e.Context.is())
815 const char* pContext = typeid(*e.Context).name();
816 sMessage += " (context: " + OUString::createFromAscii(pContext) + " )";
818 SetError( XMLERROR_FLAG_ERROR | XMLERROR_FLAG_SEVERE | XMLERROR_API,
819 Sequence<OUString>(), sMessage, nullptr );
822 // return true only if no error occurred
823 return (mnErrorFlags & (SvXMLErrorFlags::DO_NOTHING|SvXMLErrorFlags::ERROR_OCCURRED)) == SvXMLErrorFlags::NO;
826 void SAL_CALL SvXMLExport::cancel()
828 // stop export
829 Sequence<OUString> aEmptySeq;
830 SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
833 OUString SAL_CALL SvXMLExport::getName( )
835 return msFilterName;
838 void SAL_CALL SvXMLExport::setName( const OUString& )
840 // do nothing, because it is not possible to set the FilterName
843 // XServiceInfo
844 OUString SAL_CALL SvXMLExport::getImplementationName( )
846 return m_implementationName;
849 sal_Bool SAL_CALL SvXMLExport::supportsService( const OUString& rServiceName )
851 return cppu::supportsService(this, rServiceName);
854 uno::Sequence< OUString > SAL_CALL SvXMLExport::getSupportedServiceNames( )
856 return { "com.sun.star.document.ExportFilter", "com.sun.star.xml.XMLExportFilter" };
859 OUString
860 SvXMLExport::EnsureNamespace(OUString const & i_rNamespace)
862 OUString const aPreferredPrefix("gen");
863 OUString sPrefix;
864 sal_uInt16 nKey( GetNamespaceMap_().GetKeyByName( i_rNamespace ) );
865 if( XML_NAMESPACE_UNKNOWN == nKey )
867 // There is no prefix for the namespace, so
868 // we have to generate one and have to add it.
869 sPrefix = aPreferredPrefix;
870 nKey = GetNamespaceMap_().GetKeyByPrefix( sPrefix );
871 sal_Int32 n( 0 );
872 OUStringBuffer buf;
873 while( nKey != USHRT_MAX )
875 buf.append( aPreferredPrefix );
876 buf.append( ++n );
877 sPrefix = buf.makeStringAndClear();
878 nKey = GetNamespaceMap_().GetKeyByPrefix( sPrefix );
881 if (mpImpl->mNamespaceMaps.empty()
882 || (mpImpl->mNamespaceMaps.top().second != mpImpl->mDepth))
884 // top was created for lower depth... need a new namespace map!
885 auto pNew = new SvXMLNamespaceMap( *mpNamespaceMap );
886 mpImpl->mNamespaceMaps.push(
887 ::std::make_pair(std::move(mpNamespaceMap), mpImpl->mDepth) );
888 mpNamespaceMap.reset( pNew );
891 // add the namespace to the map and as attribute
892 mpNamespaceMap->Add( sPrefix, i_rNamespace );
893 buf.append( GetXMLToken(XML_XMLNS) );
894 buf.append( ':' );
895 buf.append( sPrefix );
896 AddAttribute( buf.makeStringAndClear(), i_rNamespace );
898 else
900 // If there is a prefix for the namespace, reuse that.
901 sPrefix = GetNamespaceMap_().GetPrefixByKey( nKey );
903 return sPrefix;
906 void SvXMLExport::AddAttributeASCII( sal_uInt16 nPrefixKey,
907 const sal_Char *pName,
908 const sal_Char *pValue )
910 OUString sName( OUString::createFromAscii( pName ) );
911 OUString sValue( OUString::createFromAscii( pValue ) );
913 mxAttrList->AddAttribute(
914 GetNamespaceMap_().GetQNameByKey( nPrefixKey, sName ), sValue );
917 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const sal_Char *pName,
918 const OUString& rValue )
920 OUString sName( OUString::createFromAscii( pName ) );
922 mxAttrList->AddAttribute(
923 GetNamespaceMap_().GetQNameByKey( nPrefixKey, sName ), rValue );
926 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey, const OUString& rName,
927 const OUString& rValue )
929 mxAttrList->AddAttribute(
930 GetNamespaceMap_().GetQNameByKey( nPrefixKey, rName ), rValue );
933 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey,
934 enum XMLTokenEnum eName,
935 const OUString& rValue )
937 mxAttrList->AddAttribute(
938 GetNamespaceMap_().GetQNameByKey( nPrefixKey, GetXMLToken(eName) ),
939 rValue );
942 void SvXMLExport::AddAttribute( sal_uInt16 nPrefixKey,
943 enum XMLTokenEnum eName,
944 enum XMLTokenEnum eValue)
946 mxAttrList->AddAttribute(
947 GetNamespaceMap_().GetQNameByKey( nPrefixKey, GetXMLToken(eName) ),
948 GetXMLToken(eValue) );
951 void SvXMLExport::AddAttribute( const OUString& rQName,
952 const OUString& rValue )
954 mxAttrList->AddAttribute(
955 rQName,
956 rValue );
959 void SvXMLExport::AddAttribute( const OUString& rQName,
960 enum ::xmloff::token::XMLTokenEnum eValue )
962 mxAttrList->AddAttribute(
963 rQName,
964 GetXMLToken(eValue) );
967 void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
968 const css::lang::Locale& rLocale, bool bWriteEmpty )
970 if (rLocale.Variant.isEmpty())
972 // Per convention The BCP 47 string is always stored in Variant, if
973 // that is empty we have a plain language-country combination, no need
974 // to convert to LanguageTag first. Also catches the case of empty
975 // locale denoting system locale.
976 xmloff::token::XMLTokenEnum eLanguage, eCountry;
977 eLanguage = XML_LANGUAGE;
978 eCountry = XML_COUNTRY;
979 if (bWriteEmpty || !rLocale.Language.isEmpty())
980 AddAttribute( nPrefix, eLanguage, rLocale.Language);
981 if (bWriteEmpty || !rLocale.Country.isEmpty())
982 AddAttribute( nPrefix, eCountry, rLocale.Country);
984 else
986 LanguageTag aLanguageTag( rLocale);
987 AddLanguageTagAttributes( nPrefix, nPrefixRfc, aLanguageTag, bWriteEmpty);
991 void SvXMLExport::AddLanguageTagAttributes( sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc,
992 const LanguageTag& rLanguageTag, bool bWriteEmpty )
994 if (rLanguageTag.isIsoODF())
996 if (bWriteEmpty || !rLanguageTag.isSystemLocale())
998 AddAttribute( nPrefix, XML_LANGUAGE, rLanguageTag.getLanguage());
999 if (rLanguageTag.hasScript() && getDefaultVersion() >= SvtSaveOptions::ODFVER_012)
1000 AddAttribute( nPrefix, XML_SCRIPT, rLanguageTag.getScript());
1001 if (bWriteEmpty || !rLanguageTag.getCountry().isEmpty())
1002 AddAttribute( nPrefix, XML_COUNTRY, rLanguageTag.getCountry());
1005 else
1007 if (getDefaultVersion() >= SvtSaveOptions::ODFVER_012)
1008 AddAttribute( nPrefixRfc, XML_RFC_LANGUAGE_TAG, rLanguageTag.getBcp47());
1009 // Also in case of non-pure-ISO tag store best matching fo: attributes
1010 // for consumers not handling *:rfc-language-tag, ensuring that only
1011 // valid ISO codes are stored. Here the bWriteEmpty parameter has no
1012 // meaning.
1013 OUString aLanguage, aScript, aCountry;
1014 rLanguageTag.getIsoLanguageScriptCountry( aLanguage, aScript, aCountry);
1015 if (!aLanguage.isEmpty())
1017 AddAttribute( nPrefix, XML_LANGUAGE, aLanguage);
1018 if (!aScript.isEmpty() && getDefaultVersion() >= SvtSaveOptions::ODFVER_012)
1019 AddAttribute( nPrefix, XML_SCRIPT, aScript);
1020 if (!aCountry.isEmpty())
1021 AddAttribute( nPrefix, XML_COUNTRY, aCountry);
1026 void SvXMLExport::AddAttributeList( const uno::Reference< xml::sax::XAttributeList >& xAttrList )
1028 if( xAttrList.is())
1029 mxAttrList->AppendAttributeList( xAttrList );
1032 void SvXMLExport::ClearAttrList()
1034 mxAttrList->Clear();
1037 #ifdef DBG_UTIL
1038 void SvXMLExport::CheckAttrList()
1040 SAL_WARN_IF( mxAttrList->getLength(), "xmloff.core", "XMLExport::CheckAttrList: list is not empty" );
1042 #endif
1044 void SvXMLExport::ImplExportMeta()
1046 CheckAttrList();
1048 ExportMeta_();
1051 void SvXMLExport::ImplExportSettings()
1053 CheckAttrList();
1055 ::std::vector< SettingsGroup > aSettings;
1056 sal_Int32 nSettingsCount = 0;
1058 // view settings
1059 uno::Sequence< beans::PropertyValue > aViewSettings;
1060 GetViewSettingsAndViews( aViewSettings );
1061 aSettings.emplace_back( XML_VIEW_SETTINGS, aViewSettings );
1062 nSettingsCount += aViewSettings.getLength();
1064 // configuration settings
1065 uno::Sequence<beans::PropertyValue> aConfigSettings;
1066 GetConfigurationSettings( aConfigSettings );
1067 aSettings.emplace_back( XML_CONFIGURATION_SETTINGS, aConfigSettings );
1068 nSettingsCount += aConfigSettings.getLength();
1070 // any document specific settings
1071 nSettingsCount += GetDocumentSpecificSettings( aSettings );
1074 SvXMLElementExport aElem( *this,
1075 nSettingsCount != 0,
1076 XML_NAMESPACE_OFFICE, XML_SETTINGS,
1077 true, true );
1079 SettingsExportFacade aSettingsExportContext( *this );
1080 XMLSettingsExportHelper aSettingsExportHelper( aSettingsExportContext );
1082 for (auto const& settings : aSettings)
1084 if ( !settings.aSettings.hasElements() )
1085 continue;
1087 const OUString& sSettingsName( GetXMLToken( settings.eGroupName ) );
1088 OUString sQName = GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OOO, sSettingsName );
1089 aSettingsExportHelper.exportAllSettings( settings.aSettings, sQName );
1094 void SvXMLExport::ImplExportStyles()
1096 CheckAttrList();
1099 // <style:styles>
1100 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_STYLES,
1101 true, true );
1103 ExportStyles_( false );
1106 // transfer style names (+ families) TO other components (if appropriate)
1107 if( ( !( mnExportFlags & SvXMLExportFlags::CONTENT ) ) && mxExportInfo.is() )
1109 static OUString sStyleNames( "StyleNames" );
1110 static OUString sStyleFamilies( "StyleFamilies" );
1111 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
1112 if ( xPropertySetInfo->hasPropertyByName( sStyleNames ) && xPropertySetInfo->hasPropertyByName( sStyleFamilies ) )
1114 Sequence<sal_Int32> aStyleFamilies;
1115 Sequence<OUString> aStyleNames;
1116 mxAutoStylePool->GetRegisteredNames( aStyleFamilies, aStyleNames );
1117 mxExportInfo->setPropertyValue( sStyleNames, makeAny( aStyleNames ) );
1118 mxExportInfo->setPropertyValue( sStyleFamilies,
1119 makeAny( aStyleFamilies ) );
1124 void SvXMLExport::ImplExportAutoStyles()
1126 // transfer style names (+ families) FROM other components (if appropriate)
1127 OUString sStyleNames( "StyleNames" );
1128 OUString sStyleFamilies( "StyleFamilies" );
1129 if( ( !( mnExportFlags & SvXMLExportFlags::STYLES ) )
1130 && mxExportInfo.is()
1131 && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleNames )
1132 && mxExportInfo->getPropertySetInfo()->hasPropertyByName( sStyleFamilies ) )
1134 Sequence<sal_Int32> aStyleFamilies;
1135 mxExportInfo->getPropertyValue( sStyleFamilies ) >>= aStyleFamilies;
1136 Sequence<OUString> aStyleNames;
1137 mxExportInfo->getPropertyValue( sStyleNames ) >>= aStyleNames;
1138 mxAutoStylePool->RegisterNames( aStyleFamilies, aStyleNames );
1142 // <style:automatic-styles>
1143 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE,
1144 XML_AUTOMATIC_STYLES, true, true );
1146 ExportAutoStyles_();
1150 void SvXMLExport::ImplExportMasterStyles()
1152 // <style:master-styles>
1153 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_MASTER_STYLES,
1154 true, true );
1156 ExportMasterStyles_();
1159 void SvXMLExport::ImplExportContent()
1161 CheckAttrList();
1163 CheckAttrList();
1166 SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_BODY,
1167 true, true );
1169 XMLTokenEnum eClass = meClass;
1170 if( XML_TEXT_GLOBAL == eClass )
1172 AddAttribute( XML_NAMESPACE_TEXT, XML_GLOBAL,
1173 GetXMLToken( XML_TRUE ) );
1174 eClass = XML_TEXT;
1176 if ( XML_GRAPHICS == eClass )
1177 eClass = XML_DRAWING;
1178 // <office:body ...>
1179 SetBodyAttributes();
1180 SvXMLElementExport aElem( *this, meClass != XML_TOKEN_INVALID,
1181 XML_NAMESPACE_OFFICE, eClass,
1182 true, true );
1184 ExportContent_();
1189 void SvXMLExport::SetBodyAttributes()
1193 static void
1194 lcl_AddGrddl(SvXMLExport const & rExport, const SvXMLExportFlags /*nExportMode*/)
1196 // check version >= 1.2
1197 switch (rExport.getDefaultVersion()) {
1198 case SvtSaveOptions::ODFVER_011: // fall through
1199 case SvtSaveOptions::ODFVER_010: return;
1200 default: break;
1203 // #i115030#: disabled, the XSLT is not finished, and not available via HTTP
1204 #if 0
1205 if (SvXMLExportFlags::SETTINGS != nExportMode) // meta, content, styles
1207 rExport.AddAttribute( XML_NAMESPACE_GRDDL, XML_TRANSFORMATION,
1208 OUString("http://FIXME") );
1210 #endif
1213 void SvXMLExport::addChaffWhenEncryptedStorage()
1215 uno::Reference< embed::XEncryptionProtectedSource2 > xEncr(mpImpl->mxTargetStorage, uno::UNO_QUERY);
1217 if (xEncr.is() && xEncr->hasEncryptionData() && mxExtHandler.is())
1219 mxExtHandler->comment(OStringToOUString(comphelper::xml::makeXMLChaff(), RTL_TEXTENCODING_ASCII_US));
1223 ErrCode SvXMLExport::exportDoc( enum ::xmloff::token::XMLTokenEnum eClass )
1225 bool bOwnGraphicResolver = false;
1226 bool bOwnEmbeddedResolver = false;
1228 if (!mxGraphicStorageHandler.is() || !mxEmbeddedResolver.is())
1230 Reference< XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
1231 if( xFactory.is() )
1235 if (!mxGraphicStorageHandler.is())
1237 mxGraphicStorageHandler.set(xFactory->createInstance( "com.sun.star.document.ExportGraphicStorageHandler"), UNO_QUERY);
1238 bOwnGraphicResolver = mxGraphicStorageHandler.is();
1241 if( !mxEmbeddedResolver.is() )
1243 mxEmbeddedResolver.set(
1244 xFactory->createInstance( "com.sun.star.document.ExportEmbeddedObjectResolver" ), UNO_QUERY);
1245 bOwnEmbeddedResolver = mxEmbeddedResolver.is();
1248 catch(const css::uno::Exception&)
1253 if( (getExportFlags() & SvXMLExportFlags::OASIS) == SvXMLExportFlags::NONE )
1257 static ::comphelper::PropertyMapEntry const aInfoMap[] =
1259 { OUString("Class"), 0,
1260 ::cppu::UnoType<OUString>::get(),
1261 PropertyAttribute::MAYBEVOID, 0},
1262 { OUString(), 0, css::uno::Type(), 0, 0 }
1264 Reference< XPropertySet > xConvPropSet(
1265 ::comphelper::GenericPropertySet_CreateInstance(
1266 new ::comphelper::PropertySetInfo( aInfoMap ) ) );
1268 xConvPropSet->setPropertyValue( "Class", Any(GetXMLToken( eClass )) );
1270 Reference< XPropertySet > xPropSet =
1271 mxExportInfo.is()
1272 ? PropertySetMerger_CreateInstance( mxExportInfo,
1273 xConvPropSet )
1274 : xConvPropSet;
1276 Sequence<Any> aArgs( 3 );
1277 aArgs[0] <<= mxHandler;
1278 aArgs[1] <<= xPropSet;
1279 aArgs[2] <<= mxModel;
1281 // get filter component
1282 Reference< xml::sax::XDocumentHandler > xTmpDocHandler(
1283 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext("com.sun.star.comp.Oasis2OOoTransformer", aArgs, m_xContext),
1284 UNO_QUERY);
1285 SAL_WARN_IF(!xTmpDocHandler.is(), "xmloff.core", "can't instantiate OASIS transformer component" );
1286 if( xTmpDocHandler.is() )
1288 mxHandler = xTmpDocHandler;
1289 mxExtHandler.set( mxHandler, UNO_QUERY );
1292 catch(const css::uno::Exception&)
1297 mxHandler->startDocument();
1299 addChaffWhenEncryptedStorage();
1301 // <office:document ...>
1302 CheckAttrList();
1304 // namespace attributes
1305 // ( The namespace decls should be first attributes in the element;
1306 // some faulty XML parsers (JAXP1.1) have a problem with this,
1307 // also it's more elegant )
1308 sal_uInt16 nPos = mpNamespaceMap->GetFirstKey();
1309 while( USHRT_MAX != nPos )
1311 mxAttrList->AddAttribute( mpNamespaceMap->GetAttrNameByKey( nPos ),
1312 mpNamespaceMap->GetNameByKey( nPos ) );
1313 nPos = mpNamespaceMap->GetNextKey( nPos );
1316 // office:version = ...
1317 const sal_Char* pVersion = nullptr;
1318 switch (getDefaultVersion())
1320 case SvtSaveOptions::ODFVER_LATEST: pVersion = sXML_1_2; break;
1321 case SvtSaveOptions::ODFVER_012_EXT_COMPAT: pVersion = sXML_1_2; break;
1322 case SvtSaveOptions::ODFVER_012: pVersion = sXML_1_2; break;
1323 case SvtSaveOptions::ODFVER_011: pVersion = "1.1"; break;
1324 case SvtSaveOptions::ODFVER_010: break;
1326 default:
1327 SAL_WARN("xmloff.core", "xmloff::SvXMLExport::exportDoc(), unexpected odf default version!");
1330 if (pVersion)
1332 AddAttribute( XML_NAMESPACE_OFFICE, XML_VERSION,
1333 OUString::createFromAscii(pVersion) );
1337 enum XMLTokenEnum eRootService = XML_TOKEN_INVALID;
1338 const SvXMLExportFlags nExportMode = mnExportFlags & (SvXMLExportFlags::META|SvXMLExportFlags::STYLES|SvXMLExportFlags::CONTENT|SvXMLExportFlags::SETTINGS);
1340 lcl_AddGrddl(*this, nExportMode);
1342 if( SvXMLExportFlags::META == nExportMode )
1344 // export only meta
1345 eRootService = XML_DOCUMENT_META;
1347 else if ( SvXMLExportFlags::SETTINGS == nExportMode )
1349 // export only settings
1350 eRootService = XML_DOCUMENT_SETTINGS;
1352 else if( SvXMLExportFlags::STYLES == nExportMode )
1354 // export only styles
1355 eRootService = XML_DOCUMENT_STYLES;
1357 else if( SvXMLExportFlags::CONTENT == nExportMode )
1359 // export only content
1360 eRootService = XML_DOCUMENT_CONTENT;
1362 else
1364 // the god'ol one4all element
1365 eRootService = XML_DOCUMENT;
1366 // office:mimetype = ... (only for stream containing the content)
1367 if( eClass != XML_TOKEN_INVALID )
1369 OUString aTmp = "application/vnd.oasis.opendocument." + GetXMLToken( eClass );
1370 AddAttribute( XML_NAMESPACE_OFFICE, XML_MIMETYPE, aTmp );
1374 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, eRootService, true, true );
1376 // meta information
1377 if( mnExportFlags & SvXMLExportFlags::META )
1378 ImplExportMeta();
1380 // settings
1381 if( mnExportFlags & SvXMLExportFlags::SETTINGS )
1382 ImplExportSettings();
1384 // scripts
1385 if( mnExportFlags & SvXMLExportFlags::SCRIPTS )
1386 ExportScripts_();
1388 // font declarations
1389 if( mnExportFlags & SvXMLExportFlags::FONTDECLS )
1390 ExportFontDecls_();
1392 // styles
1393 if( mnExportFlags & SvXMLExportFlags::STYLES )
1394 ImplExportStyles();
1396 // autostyles
1397 if( mnExportFlags & SvXMLExportFlags::AUTOSTYLES )
1398 ImplExportAutoStyles();
1400 // masterstyles
1401 if( mnExportFlags & SvXMLExportFlags::MASTERSTYLES )
1402 ImplExportMasterStyles();
1404 // content
1405 if( mnExportFlags & SvXMLExportFlags::CONTENT )
1406 ImplExportContent();
1409 mxHandler->endDocument();
1411 if( bOwnGraphicResolver )
1413 uno::Reference<XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY);
1414 xComp->dispose();
1417 if( bOwnEmbeddedResolver )
1419 Reference< XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
1420 xComp->dispose();
1423 return ERRCODE_NONE;
1426 void SvXMLExport::ResetNamespaceMap()
1428 mpNamespaceMap.reset( new SvXMLNamespaceMap );
1431 OUString const & SvXMLExport::GetSourceShellID() const
1433 return mpImpl->maSrcShellID;
1436 OUString const & SvXMLExport::GetDestinationShellID() const
1438 return mpImpl->maDestShellID;
1441 void SvXMLExport::ExportMeta_()
1443 OUString generator( ::utl::DocInfoHelper::GetGeneratorString() );
1444 Reference< XDocumentPropertiesSupplier > xDocPropsSupplier(mxModel,
1445 UNO_QUERY);
1446 if (xDocPropsSupplier.is()) {
1447 Reference<XDocumentProperties> xDocProps(
1448 xDocPropsSupplier->getDocumentProperties());
1449 if (!xDocProps.is()) throw;
1450 // update generator here
1451 xDocProps->setGenerator(generator);
1452 rtl::Reference<SvXMLMetaExport> pMeta = new SvXMLMetaExport(*this, xDocProps);
1453 pMeta->Export();
1454 } else {
1455 // office:meta
1456 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_META,
1457 true, true );
1459 // BM: #i60323# export generator even if xInfoProp is empty (which is the
1460 // case for charts). The generator does not depend on xInfoProp
1461 SvXMLElementExport anElem( *this, XML_NAMESPACE_META, XML_GENERATOR,
1462 true, true );
1463 Characters(generator);
1468 void SvXMLExport::ExportScripts_()
1470 SvXMLElementExport aElement( *this, XML_NAMESPACE_OFFICE, XML_SCRIPTS, true, true );
1472 // export Basic macros (only for FlatXML)
1473 if ( mnExportFlags & SvXMLExportFlags::EMBEDDED )
1475 OUString aValue( GetNamespaceMap().GetPrefixByKey( XML_NAMESPACE_OOO ) + ":Basic" );
1476 AddAttribute( XML_NAMESPACE_SCRIPT, XML_LANGUAGE, aValue );
1478 SvXMLElementExport aElem( *this, XML_NAMESPACE_OFFICE, XML_SCRIPT, true, true );
1480 // initialize Basic
1481 if ( mxModel.is() )
1483 Reference< beans::XPropertySet > xPSet( mxModel, UNO_QUERY );
1484 if ( xPSet.is() )
1485 xPSet->getPropertyValue("BasicLibraries");
1488 Reference < XDocumentHandler > xHdl( new XMLBasicExportFilter( mxHandler ) );
1489 Reference< document::XXMLBasicExporter > xExporter = document::XMLOasisBasicExporter::createWithHandler( m_xContext, xHdl );
1491 xExporter->setSourceDocument( mxModel );
1492 Sequence< PropertyValue > aMediaDesc( 0 );
1493 xExporter->filter( aMediaDesc );
1496 // export document events
1497 Reference< document::XEventsSupplier > xEvents( GetModel(), UNO_QUERY );
1498 GetEventExport().Export( xEvents );
1501 void SvXMLExport::ExportFontDecls_()
1503 if( mxFontAutoStylePool.is() )
1504 mxFontAutoStylePool->exportXML();
1507 void SvXMLExport::ExportStyles_( bool )
1509 uno::Reference< lang::XMultiServiceFactory > xFact( GetModel(), uno::UNO_QUERY );
1510 if( xFact.is())
1512 // export (fill-)gradient-styles
1515 uno::Reference< container::XNameAccess > xGradient( xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY );
1516 if( xGradient.is() )
1518 XMLGradientStyleExport aGradientStyle( *this );
1520 if( xGradient->hasElements() )
1522 const uno::Sequence< OUString > aNamesSeq ( xGradient->getElementNames() );
1523 for( const OUString& rStrName : aNamesSeq )
1527 uno::Any aValue = xGradient->getByName( rStrName );
1529 aGradientStyle.exportXML( rStrName, aValue );
1531 catch(const container::NoSuchElementException&)
1538 catch(const lang::ServiceNotRegisteredException&)
1542 // export (fill-)hatch-styles
1545 uno::Reference< container::XNameAccess > xHatch( xFact->createInstance("com.sun.star.drawing.HatchTable"), uno::UNO_QUERY );
1546 if( xHatch.is() )
1548 XMLHatchStyleExport aHatchStyle( *this );
1550 if( xHatch->hasElements() )
1552 const uno::Sequence< OUString > aNamesSeq ( xHatch->getElementNames() );
1553 for( const OUString& rStrName : aNamesSeq )
1557 uno::Any aValue = xHatch->getByName( rStrName );
1559 aHatchStyle.exportXML( rStrName, aValue );
1561 catch(const container::NoSuchElementException&)
1567 catch(const lang::ServiceNotRegisteredException&)
1571 // export (fill-)bitmap-styles
1574 uno::Reference< container::XNameAccess > xBitmap( xFact->createInstance("com.sun.star.drawing.BitmapTable"), uno::UNO_QUERY );
1575 if( xBitmap.is() )
1577 if( xBitmap->hasElements() )
1579 const uno::Sequence< OUString > aNamesSeq ( xBitmap->getElementNames() );
1580 for( const OUString& rStrName : aNamesSeq )
1584 uno::Any aValue = xBitmap->getByName( rStrName );
1586 XMLImageStyle::exportXML( rStrName, aValue, *this );
1588 catch(const container::NoSuchElementException&)
1595 catch(const lang::ServiceNotRegisteredException&)
1599 // export transparency-gradient -styles
1602 uno::Reference< container::XNameAccess > xTransGradient( xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"), uno::UNO_QUERY );
1603 if( xTransGradient.is() )
1605 XMLTransGradientStyleExport aTransGradientstyle( *this );
1607 if( xTransGradient->hasElements() )
1609 const uno::Sequence< OUString > aNamesSeq ( xTransGradient->getElementNames() );
1610 for( const OUString& rStrName : aNamesSeq )
1614 uno::Any aValue = xTransGradient->getByName( rStrName );
1616 aTransGradientstyle.exportXML( rStrName, aValue );
1618 catch(const container::NoSuchElementException&)
1625 catch(const lang::ServiceNotRegisteredException&)
1629 // export marker-styles
1632 uno::Reference< container::XNameAccess > xMarker( xFact->createInstance("com.sun.star.drawing.MarkerTable"), uno::UNO_QUERY );
1633 if( xMarker.is() )
1635 XMLMarkerStyleExport aMarkerStyle( *this );
1637 if( xMarker->hasElements() )
1639 const uno::Sequence< OUString > aNamesSeq ( xMarker->getElementNames() );
1640 for( const OUString& rStrName : aNamesSeq )
1644 uno::Any aValue = xMarker->getByName( rStrName );
1646 aMarkerStyle.exportXML( rStrName, aValue );
1648 catch(const container::NoSuchElementException&)
1655 catch(const lang::ServiceNotRegisteredException&)
1659 // export dash-styles
1662 uno::Reference< container::XNameAccess > xDashes( xFact->createInstance("com.sun.star.drawing.DashTable"), uno::UNO_QUERY );
1663 if( xDashes.is() )
1665 XMLDashStyleExport aDashStyle( *this );
1667 if( xDashes->hasElements() )
1669 const uno::Sequence< OUString > aNamesSeq ( xDashes->getElementNames() );
1670 for( const OUString& rStrName : aNamesSeq )
1674 uno::Any aValue = xDashes->getByName( rStrName );
1676 aDashStyle.exportXML( rStrName, aValue );
1678 catch(const container::NoSuchElementException&)
1685 catch(const lang::ServiceNotRegisteredException&)
1691 XMLTextParagraphExport* SvXMLExport::CreateTextParagraphExport()
1693 return new XMLTextParagraphExport( *this, *GetAutoStylePool() );
1696 XMLShapeExport* SvXMLExport::CreateShapeExport()
1698 return new XMLShapeExport(*this);
1701 SvXMLAutoStylePoolP* SvXMLExport::CreateAutoStylePool()
1703 return new SvXMLAutoStylePoolP(*this);
1706 void SvXMLExport::collectAutoStyles()
1710 XMLPageExport* SvXMLExport::CreatePageExport()
1712 return new XMLPageExport( *this );
1715 SchXMLExportHelper* SvXMLExport::CreateChartExport()
1717 return new SchXMLExportHelper(*this, *GetAutoStylePool());
1720 XMLFontAutoStylePool* SvXMLExport::CreateFontAutoStylePool()
1722 return new XMLFontAutoStylePool( *this );
1725 xmloff::OFormLayerXMLExport* SvXMLExport::CreateFormExport()
1727 return new xmloff::OFormLayerXMLExport(*this);
1730 void SvXMLExport::GetViewSettingsAndViews(uno::Sequence<beans::PropertyValue>& rProps)
1732 GetViewSettings(rProps);
1733 uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
1734 if(xViewDataSupplier.is())
1736 uno::Reference<container::XIndexAccess> xIndexAccess;
1737 xViewDataSupplier->setViewData( xIndexAccess ); // make sure we get a newly created sequence
1738 xIndexAccess = xViewDataSupplier->getViewData();
1739 bool bAdd = false;
1740 uno::Any aAny;
1741 if(xIndexAccess.is() && xIndexAccess->hasElements() )
1743 sal_Int32 nCount = xIndexAccess->getCount();
1744 for (sal_Int32 i = 0; i < nCount; i++)
1746 aAny = xIndexAccess->getByIndex(i);
1747 uno::Sequence<beans::PropertyValue> aProps;
1748 if( aAny >>= aProps )
1750 if( aProps.hasElements() )
1752 bAdd = true;
1753 break;
1759 if( bAdd )
1761 sal_Int32 nOldLength(rProps.getLength());
1762 rProps.realloc(nOldLength + 1);
1763 beans::PropertyValue aProp;
1764 aProp.Name = "Views";
1765 aProp.Value <<= xIndexAccess;
1766 rProps[nOldLength] = aProp;
1771 void SvXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>&)
1775 void SvXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>&)
1779 sal_Int32 SvXMLExport::GetDocumentSpecificSettings( ::std::vector< SettingsGroup >& )
1781 return 0;
1784 void SvXMLExport::collectDataStyles(bool bFromUsedStyles)
1786 Reference<style::XStyleFamiliesSupplier> xStyleFamiliesSupplier(GetModel(), uno::UNO_QUERY);
1787 if (!xStyleFamiliesSupplier.is())
1788 return;
1790 Reference<container::XNameAccess> xStylesFamilies(xStyleFamiliesSupplier->getStyleFamilies());
1791 if (!xStylesFamilies.is())
1792 return;
1794 Reference<container::XIndexAccess> xCellStyles(xStylesFamilies->getByName("CellStyles"), uno::UNO_QUERY);
1795 if (!xCellStyles.is())
1796 return;
1798 sal_Int32 nCount(xCellStyles->getCount());
1799 for (sal_Int32 i = 0; i < nCount; ++i)
1801 Reference<style::XStyle> xStyle(xCellStyles->getByIndex(i), uno::UNO_QUERY);
1802 if (bFromUsedStyles && !xStyle->isInUse())
1803 continue;
1805 Reference<beans::XPropertySet> xCellProperties(xStyle, uno::UNO_QUERY);
1806 if (xCellProperties.is())
1808 sal_Int32 nNumberFormat = 0;
1809 if (xCellProperties->getPropertyValue("NumberFormat") >>= nNumberFormat)
1810 addDataStyle(nNumberFormat);
1815 void SvXMLExport::addDataStyle(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ )
1817 if(mpNumExport)
1818 mpNumExport->SetUsed(nNumberFormat);
1821 void SvXMLExport::exportDataStyles()
1823 if(mpNumExport)
1824 mpNumExport->Export(false);
1827 void SvXMLExport::exportAutoDataStyles()
1829 if(mpNumExport)
1830 mpNumExport->Export(true);
1832 if (mxFormExport.is())
1833 mxFormExport->exportAutoControlNumberStyles();
1836 OUString SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat, bool /*bTimeFormat*/ ) const
1838 OUString sTemp;
1839 if(mpNumExport)
1840 sTemp = mpNumExport->GetStyleName(nNumberFormat);
1841 return sTemp;
1844 void SvXMLExport::exportAnnotationMeta(const uno::Reference<drawing::XShape>&)
1848 sal_Int32 SvXMLExport::dataStyleForceSystemLanguage(sal_Int32 nFormat) const
1850 return ( mpNumExport != nullptr )
1851 ? mpNumExport->ForceSystemLanguage( nFormat ) : nFormat;
1854 OUString SvXMLExport::AddEmbeddedXGraphic(uno::Reference<graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType, OUString const & rRequestedName)
1856 OUString sURL;
1858 Graphic aGraphic(rxGraphic);
1859 OUString aOriginURL = aGraphic.getOriginURL();
1861 if (!aOriginURL.isEmpty())
1863 sURL = GetRelativeReference(aOriginURL);
1865 else
1867 if (mxGraphicStorageHandler.is())
1869 if (!(getExportFlags() & SvXMLExportFlags::EMBEDDED))
1870 sURL = mxGraphicStorageHandler->saveGraphicByName(rxGraphic, rOutMimeType, rRequestedName);
1873 return sURL;
1876 bool SvXMLExport::GetGraphicMimeTypeFromStream(uno::Reference<graphic::XGraphic> const & rxGraphic, OUString & rOutMimeType)
1878 if (mxGraphicStorageHandler.is())
1880 Reference<XInputStream> xInputStream(mxGraphicStorageHandler->createInputStream(rxGraphic));
1881 if (xInputStream.is())
1883 rOutMimeType = comphelper::GraphicMimeTypeHelper::GetMimeTypeForImageStream(xInputStream);
1884 return true;
1888 return false;
1891 bool SvXMLExport::AddEmbeddedXGraphicAsBase64(uno::Reference<graphic::XGraphic> const & rxGraphic)
1893 if ((getExportFlags() & SvXMLExportFlags::EMBEDDED) &&
1894 mxGraphicStorageHandler.is())
1896 Reference<XInputStream> xInputStream(mxGraphicStorageHandler->createInputStream(rxGraphic));
1897 if (xInputStream.is())
1899 Graphic aGraphic(rxGraphic);
1900 if (aGraphic.getOriginURL().isEmpty()) // don't add the base64 if the origin URL is set (image is from an external URL)
1902 XMLBase64Export aBase64Exp(*this);
1903 return aBase64Exp.exportOfficeBinaryDataElement(xInputStream);
1908 return false;
1911 OUString SvXMLExport::AddEmbeddedObject( const OUString& rEmbeddedObjectURL )
1913 OUString sRet;
1914 bool bSupportedURL = rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECT_URL_BASE) ||
1915 rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE);
1916 if (bSupportedURL && mxEmbeddedResolver.is())
1918 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL(rEmbeddedObjectURL);
1920 else
1921 sRet = GetRelativeReference( rEmbeddedObjectURL );
1923 return sRet;
1926 bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString& rEmbeddedObjectURL )
1928 bool bRet = false;
1929 bool bSupportedURL = rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECT_URL_BASE) ||
1930 rEmbeddedObjectURL.startsWith(XML_EMBEDDEDOBJECTGRAPHIC_URL_BASE);
1931 if (bSupportedURL && mxEmbeddedResolver.is())
1933 Reference < XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY );
1934 if( xNA.is() )
1936 Any aAny = xNA->getByName( rEmbeddedObjectURL );
1937 Reference < XInputStream > xIn;
1938 aAny >>= xIn;
1939 if( xIn.is() )
1941 XMLBase64Export aBase64Exp( *this );
1942 bRet = aBase64Exp.exportOfficeBinaryDataElement( xIn );
1947 return bRet;
1950 OUString SvXMLExport::EncodeStyleName(
1951 const OUString& rName,
1952 bool *pEncoded ) const
1954 return GetMM100UnitConverter().encodeStyleName( rName, pEncoded );
1957 ProgressBarHelper* SvXMLExport::GetProgressBarHelper()
1959 if (!mpProgressBarHelper)
1961 mpProgressBarHelper.reset( new ProgressBarHelper(mxStatusIndicator, true) );
1963 if (mxExportInfo.is())
1965 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxExportInfo->getPropertySetInfo();
1966 if (xPropertySetInfo.is())
1968 OUString sProgressRange(XML_PROGRESSRANGE);
1969 OUString sProgressMax(XML_PROGRESSMAX);
1970 OUString sProgressCurrent(XML_PROGRESSCURRENT);
1971 OUString sRepeat(XML_PROGRESSREPEAT);
1972 if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
1973 xPropertySetInfo->hasPropertyByName(sProgressCurrent) &&
1974 xPropertySetInfo->hasPropertyByName(sProgressRange))
1976 uno::Any aAny;
1977 sal_Int32 nProgressMax(0);
1978 sal_Int32 nProgressCurrent(0);
1979 sal_Int32 nProgressRange(0);
1980 aAny = mxExportInfo->getPropertyValue(sProgressRange);
1981 if (aAny >>= nProgressRange)
1982 mpProgressBarHelper->SetRange(nProgressRange);
1983 aAny = mxExportInfo->getPropertyValue(sProgressMax);
1984 if (aAny >>= nProgressMax)
1985 mpProgressBarHelper->SetReference(nProgressMax);
1986 aAny = mxExportInfo->getPropertyValue(sProgressCurrent);
1987 if (aAny >>= nProgressCurrent)
1988 mpProgressBarHelper->SetValue(nProgressCurrent);
1990 if (xPropertySetInfo->hasPropertyByName(sRepeat))
1992 uno::Any aAny = mxExportInfo->getPropertyValue(sRepeat);
1993 if (aAny.getValueType() == cppu::UnoType<bool>::get())
1994 mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
1995 else {
1996 SAL_WARN("xmloff.core", "why is it no boolean?" );
2002 return mpProgressBarHelper.get();
2005 XMLEventExport& SvXMLExport::GetEventExport()
2007 if( nullptr == mpEventExport)
2009 // create EventExport on demand
2010 mpEventExport.reset( new XMLEventExport(*this) );
2012 // and register standard handlers + names
2013 mpEventExport->AddHandler("StarBasic", std::make_unique<XMLStarBasicExportHandler>());
2014 mpEventExport->AddHandler("Script", std::make_unique<XMLScriptExportHandler>());
2015 mpEventExport->AddTranslationTable(aStandardEventTable);
2018 return *mpEventExport;
2021 XMLImageMapExport& SvXMLExport::GetImageMapExport()
2023 // image map export, create on-demand
2024 if( nullptr == mpImageMapExport )
2026 mpImageMapExport.reset( new XMLImageMapExport(*this) );
2029 return *mpImageMapExport;
2032 // XUnoTunnel & co
2033 UNO3_GETIMPLEMENTATION_IMPL(SvXMLExport);
2035 void SvXMLExport::ExportEmbeddedOwnObject( Reference< XComponent > const & rComp )
2037 OUString sFilterService;
2039 Reference < lang::XServiceInfo > xServiceInfo( rComp, UNO_QUERY );
2040 if( xServiceInfo.is() )
2042 const XMLServiceMapEntry_Impl *pEntry = aServiceMap;
2043 while( pEntry->sModelService )
2045 OUString sModelService( pEntry->sModelService,
2046 pEntry->nModelServiceLen,
2047 RTL_TEXTENCODING_ASCII_US );
2048 if( xServiceInfo->supportsService( sModelService ) )
2050 sFilterService = OUString( pEntry->sFilterService,
2051 pEntry->nFilterServiceLen,
2052 RTL_TEXTENCODING_ASCII_US );
2053 break;
2055 pEntry++;
2059 SAL_WARN_IF( !sFilterService.getLength(), "xmloff.core", "no export filter for own object" );
2061 if( sFilterService.isEmpty() )
2062 return;
2064 Reference < XDocumentHandler > xHdl =
2065 new XMLEmbeddedObjectExportFilter( mxHandler );
2067 Sequence < Any > aArgs( 1 );
2068 aArgs[0] <<= xHdl;
2070 Reference< document::XExporter > xExporter(
2071 m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService, aArgs, m_xContext),
2072 UNO_QUERY);
2073 SAL_WARN_IF( !xExporter.is(), "xmloff.core", "can't instantiate export filter component for own object" );
2074 if( !xExporter.is() )
2075 return;
2077 xExporter->setSourceDocument( rComp );
2079 Reference<XFilter> xFilter( xExporter, UNO_QUERY );
2081 Sequence < PropertyValue > aMediaDesc( 0 );
2082 xFilter->filter( aMediaDesc );
2085 OUString SvXMLExport::GetRelativeReference(const OUString& rValue)
2087 OUString sValue( rValue );
2088 // #i65474# handling of fragment URLs ("#...") is undefined
2089 // they are stored 'as is'
2090 uno::Reference< uri::XUriReference > xUriRef;
2091 if(!sValue.isEmpty() && sValue[0] != '#')
2095 xUriRef = mpImpl->mxUriReferenceFactory->parse( rValue );
2096 if( xUriRef.is() && !xUriRef->isAbsolute() )
2098 //#i61943# relative URLs need special handling
2099 INetURLObject aTemp( mpImpl->msPackageURI );
2100 bool bWasAbsolute = false;
2101 sValue = aTemp.smartRel2Abs(sValue, bWasAbsolute ).GetMainURL(INetURLObject::DecodeMechanism::ToIUri);
2104 catch(const uno::Exception&)
2108 if( xUriRef.is() )//no conversion for empty values or for fragments
2110 //conversion for matching schemes only
2111 if( xUriRef->getScheme() == mpImpl->msPackageURIScheme )
2113 sValue = INetURLObject::GetRelURL( msOrigFileName, sValue );
2116 return sValue;
2119 void SvXMLExport::StartElement(sal_uInt16 nPrefix,
2120 enum ::xmloff::token::XMLTokenEnum eName,
2121 bool bIgnWSOutside )
2123 StartElement(GetNamespaceMap_().GetQNameByKey( nPrefix,
2124 GetXMLToken(eName) ), bIgnWSOutside);
2127 void SvXMLExport::StartElement(const OUString& rName,
2128 bool bIgnWSOutside )
2130 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING)
2134 if( bIgnWSOutside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY))
2135 mxHandler->ignorableWhitespace( msWS );
2136 mxHandler->startElement( rName, GetXAttrList() );
2138 catch (const SAXInvalidCharacterException& e)
2140 Sequence<OUString> aPars { rName };
2141 SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, nullptr );
2143 catch (const SAXException& e)
2145 Sequence<OUString> aPars { rName };
2146 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2147 aPars, e.Message, nullptr );
2150 ClearAttrList();
2151 ++mpImpl->mDepth; // increment nesting depth counter
2154 void SvXMLExport::Characters(const OUString& rChars)
2156 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING)
2160 mxHandler->characters(rChars);
2162 catch (const SAXInvalidCharacterException& e)
2164 Sequence<OUString> aPars { rChars };
2165 SetError( XMLERROR_SAX|XMLERROR_FLAG_WARNING, aPars, e.Message, nullptr );
2167 catch (const SAXException& e)
2169 Sequence<OUString> aPars { rChars };
2170 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2171 aPars, e.Message, nullptr );
2176 void SvXMLExport::EndElement(sal_uInt16 nPrefix,
2177 enum ::xmloff::token::XMLTokenEnum eName,
2178 bool bIgnWSInside )
2180 EndElement(GetNamespaceMap_().GetQNameByKey( nPrefix, GetXMLToken(eName) ),
2181 bIgnWSInside);
2184 void SvXMLExport::EndElement(const OUString& rName,
2185 bool bIgnWSInside )
2187 // decrement nesting depth counter & (maybe) restore namespace map
2188 --mpImpl->mDepth;
2189 if (!mpImpl->mNamespaceMaps.empty() &&
2190 (mpImpl->mNamespaceMaps.top().second == mpImpl->mDepth))
2192 mpNamespaceMap = std::move(mpImpl->mNamespaceMaps.top().first);
2193 mpImpl->mNamespaceMaps.pop();
2195 SAL_WARN_IF(!mpImpl->mNamespaceMaps.empty() &&
2196 (mpImpl->mNamespaceMaps.top().second >= mpImpl->mDepth), "xmloff.core", "SvXMLExport: NamespaceMaps corrupted");
2198 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING)
2202 if( bIgnWSInside && ((mnExportFlags & SvXMLExportFlags::PRETTY) == SvXMLExportFlags::PRETTY))
2203 mxHandler->ignorableWhitespace( msWS );
2204 mxHandler->endElement( rName );
2206 catch (const SAXException& e)
2208 Sequence<OUString> aPars { rName };
2209 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2210 aPars, e.Message, nullptr );
2215 void SvXMLExport::IgnorableWhitespace()
2217 if ((mnExportFlags & SvXMLExportFlags::PRETTY) != SvXMLExportFlags::PRETTY)
2218 return;
2220 if ((mnErrorFlags & SvXMLErrorFlags::DO_NOTHING) != SvXMLErrorFlags::DO_NOTHING)
2224 mxHandler->ignorableWhitespace( msWS );
2226 catch (const SAXException& e)
2228 Sequence<OUString> aPars(0);
2229 SetError( XMLERROR_SAX|XMLERROR_FLAG_ERROR|XMLERROR_FLAG_SEVERE,
2230 aPars, e.Message, nullptr );
2235 void SvXMLExport::SetError(
2236 sal_Int32 nId,
2237 const Sequence<OUString>& rMsgParams,
2238 const OUString& rExceptionMessage,
2239 const Reference<XLocator>& rLocator )
2241 // allow multi-threaded access to the cancel() method
2242 static osl::Mutex aMutex;
2243 osl::MutexGuard aGuard(aMutex);
2245 // maintain error flags
2246 if ( ( nId & XMLERROR_FLAG_ERROR ) != 0 )
2247 mnErrorFlags |= SvXMLErrorFlags::ERROR_OCCURRED;
2248 if ( ( nId & XMLERROR_FLAG_WARNING ) != 0 )
2249 mnErrorFlags |= SvXMLErrorFlags::WARNING_OCCURRED;
2250 if ( ( nId & XMLERROR_FLAG_SEVERE ) != 0 )
2251 mnErrorFlags |= SvXMLErrorFlags::DO_NOTHING;
2253 // create error list on demand
2254 if ( mpXMLErrors == nullptr )
2255 mpXMLErrors.reset( new XMLErrors() );
2257 // save error information
2258 mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage, rLocator );
2261 void SvXMLExport::SetError(
2262 sal_Int32 nId,
2263 const Sequence<OUString>& rMsgParams)
2265 SetError( nId, rMsgParams, "", nullptr );
2268 void SvXMLExport::DisposingModel()
2270 mxModel.clear();
2271 // Shapes in Writer cannot be named via context menu (#i51726#)
2272 meModelType = SvtModuleOptions::EFactory::UNKNOWN_FACTORY;
2273 mxEventListener.clear();
2277 ::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLExport::getInterfaceToIdentifierMapper()
2279 return mpImpl->maInterfaceToIdentifierMapper;
2282 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
2283 bool SvXMLExport::writeOutlineStyleAsNormalListStyle() const
2285 return mpImpl->mbOutlineStyleAsNormalListStyle;
2288 uno::Reference< embed::XStorage > const & SvXMLExport::GetTargetStorage() const
2290 return mpImpl->mxTargetStorage;
2293 /// returns the currently configured default version for ODF export
2294 SvtSaveOptions::ODFDefaultVersion SvXMLExport::getDefaultVersion() const
2296 if( mpImpl )
2297 return mpImpl->maSaveOptions.GetODFDefaultVersion();
2299 // fatal error, use current version as default
2300 return SvtSaveOptions::ODFVER_012;
2303 SvtSaveOptions::ODFSaneDefaultVersion SvXMLExport::getSaneDefaultVersion() const
2305 if( mpImpl )
2306 return mpImpl->maSaveOptions.GetODFSaneDefaultVersion();
2308 // fatal error, use current version as default
2309 return SvtSaveOptions::ODFSVER_LATEST;
2312 void
2313 SvXMLExport::AddAttributeIdLegacy(
2314 sal_uInt16 const nLegacyPrefix, OUString const& rValue)
2316 switch (getDefaultVersion()) {
2317 case SvtSaveOptions::ODFVER_011: // fall through
2318 case SvtSaveOptions::ODFVER_010: break;
2319 default: // ODF 1.2: xml:id
2320 AddAttribute(XML_NAMESPACE_XML, XML_ID, rValue);
2322 // in ODF 1.1 this was form:id, anim:id, draw:id, or text:id
2323 // backward compatibility: in ODF 1.2 write _both_ id attrs
2324 AddAttribute(nLegacyPrefix, XML_ID, rValue);
2325 // FIXME: this function simply assumes that rValue is unique
2328 void
2329 SvXMLExport::AddAttributeXmlId(uno::Reference<uno::XInterface> const & i_xIfc)
2331 // check version >= 1.2
2332 switch (getDefaultVersion()) {
2333 case SvtSaveOptions::ODFVER_011: // fall through
2334 case SvtSaveOptions::ODFVER_010: return;
2335 default: break;
2337 const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
2338 uno::UNO_QUERY);
2339 //FIXME not yet...
2340 if ( xMeta.is() )
2342 const beans::StringPair mdref( xMeta->getMetadataReference() );
2343 if ( !mdref.Second.isEmpty() )
2345 const OUString streamName = mpImpl->mStreamName;
2346 if ( !streamName.isEmpty() )
2348 if ( streamName == mdref.First )
2350 AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second );
2352 else
2354 SAL_WARN("xmloff.core","SvXMLExport::AddAttributeXmlId: invalid stream name");
2357 else
2359 // FIXME: this is ugly
2360 // there is no stream name (e.g. XSLT, flat-xml format)!
2361 // but how do we ensure uniqueness in this case?
2362 // a) just omit styles.xml ids -- they are unlikely anyway...
2363 // b) somehow find out whether we are currently exporting styles
2364 // or content, and prefix "s" or "c" => unique
2365 if ( mdref.First == "content.xml" )
2367 AddAttribute( XML_NAMESPACE_XML, XML_ID, mdref.Second );
2369 else
2371 SAL_INFO("xmloff.core", "SvXMLExport::AddAttributeXmlId: no stream name given: dropping styles.xml xml:id");
2378 void
2379 SvXMLExport::AddAttributesRDFa(
2380 uno::Reference<text::XTextContent> const & i_xTextContent)
2382 // check version >= 1.2
2383 switch (getDefaultVersion()) {
2384 case SvtSaveOptions::ODFVER_011: // fall through
2385 case SvtSaveOptions::ODFVER_010: return;
2386 default: break;
2389 const uno::Reference<rdf::XMetadatable> xMeta(
2390 i_xTextContent, uno::UNO_QUERY);
2391 if (!xMeta.is() || xMeta->getMetadataReference().Second.isEmpty())
2393 return; // no xml:id => no RDFa
2396 if (!mpImpl->mpRDFaHelper)
2398 mpImpl->mpRDFaHelper.reset( new ::xmloff::RDFaExportHelper(*this) );
2400 mpImpl->mpRDFaHelper->AddRDFa(xMeta);
2403 bool SvXMLExport::exportTextNumberElement() const
2405 return mpImpl->mbExportTextNumberElement;
2408 bool SvXMLExport::SetNullDateOnUnitConverter()
2410 // if the null date has already been set, don't set it again (performance)
2411 if (!mpImpl->mbNullDateInitialized)
2412 mpImpl->mbNullDateInitialized = GetMM100UnitConverter().setNullDate(GetModel());
2414 return mpImpl->mbNullDateInitialized;
2417 OUString const & SvXMLExport::GetImageFilterName() const
2419 return msImgFilterName;
2422 void SvXMLElementExport::StartElement(
2423 const sal_uInt16 nPrefixKey,
2424 const OUString& rLName,
2425 const bool bIgnoreWhitespaceOutside )
2427 maElementName = mrExport.GetNamespaceMap().GetQNameByKey(nPrefixKey, rLName);
2428 mrExport.StartElement(maElementName, bIgnoreWhitespaceOutside);
2431 SvXMLElementExport::SvXMLElementExport(
2432 SvXMLExport& rExp,
2433 sal_uInt16 nPrefixKey,
2434 const sal_Char *pLName,
2435 bool bIWSOutside,
2436 bool bIWSInside )
2437 : mrExport( rExp )
2438 , maElementName()
2439 , mbIgnoreWhitespaceInside( bIWSInside )
2440 , mbDoSomething( true )
2442 const OUString sLName( OUString::createFromAscii( pLName ) );
2443 StartElement( nPrefixKey, sLName, bIWSOutside );
2446 SvXMLElementExport::SvXMLElementExport(
2447 SvXMLExport& rExp,
2448 sal_uInt16 nPrefixKey,
2449 const OUString& rLName,
2450 bool bIWSOutside,
2451 bool bIWSInside )
2452 : mrExport( rExp )
2453 , maElementName()
2454 , mbIgnoreWhitespaceInside( bIWSInside )
2455 , mbDoSomething( true )
2457 StartElement( nPrefixKey, rLName, bIWSOutside );
2460 SvXMLElementExport::SvXMLElementExport(
2461 SvXMLExport& rExp,
2462 sal_uInt16 nPrefixKey,
2463 enum XMLTokenEnum eLName,
2464 bool bIWSOutside,
2465 bool bIWSInside )
2466 : mrExport( rExp )
2467 , maElementName()
2468 , mbIgnoreWhitespaceInside( bIWSInside )
2469 , mbDoSomething( true )
2471 StartElement( nPrefixKey, GetXMLToken(eLName), bIWSOutside );
2474 SvXMLElementExport::SvXMLElementExport(
2475 SvXMLExport& rExp,
2476 bool bDoSth,
2477 sal_uInt16 nPrefixKey,
2478 enum XMLTokenEnum eLName,
2479 bool bIWSOutside,
2480 bool bIWSInside )
2481 : mrExport( rExp )
2482 , maElementName()
2483 , mbIgnoreWhitespaceInside( bIWSInside )
2484 , mbDoSomething( bDoSth )
2486 if ( mbDoSomething )
2487 StartElement( nPrefixKey, GetXMLToken( eLName ), bIWSOutside );
2490 SvXMLElementExport::SvXMLElementExport(
2491 SvXMLExport& rExp,
2492 const OUString& rQName,
2493 bool bIWSOutside,
2494 bool bIWSInside )
2495 : mrExport( rExp )
2496 , maElementName()
2497 , mbIgnoreWhitespaceInside( bIWSInside )
2498 , mbDoSomething( true )
2500 maElementName = rQName;
2501 rExp.StartElement( rQName, bIWSOutside );
2504 SvXMLElementExport::~SvXMLElementExport()
2506 if ( mbDoSomething )
2508 mrExport.EndElement( maElementName, mbIgnoreWhitespaceInside );
2512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */