1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <sal/config.h>
22 #include <sal/log.hxx>
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:"
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
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
;
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
);
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
>
217 SvXMLExport
* pExport
;
220 explicit SvXMLExportEventListener(SvXMLExport
* pExport
);
223 virtual void SAL_CALL
disposing(const lang::EventObject
& rEventObject
) override
;
226 SvXMLExportEventListener::SvXMLExportEventListener(SvXMLExport
* pTempExport
)
227 : pExport(pTempExport
)
232 void SAL_CALL
SvXMLExportEventListener::disposing( const lang::EventObject
& )
236 pExport
->DisposingModel();
241 class 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)
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(':');
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 ),
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
)
350 GetXMLToken(XML_NP_TABLE_EXT
), GetXMLToken(XML_N_TABLE_EXT
), XML_NAMESPACE_TABLE_EXT
);
352 GetXMLToken(XML_NP_CALC_EXT
), GetXMLToken(XML_N_CALC_EXT
), XML_NAMESPACE_CALC_EXT
);
354 GetXMLToken(XML_NP_DRAW_EXT
), GetXMLToken(XML_N_DRAW_EXT
), XML_NAMESPACE_DRAW_EXT
);
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
) )
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
;
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
),
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" );
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
);
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
),
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
);
508 if (mxNumberFormatsSupplier
.is())
509 mpNumExport
.reset( new SvXMLNumFmtExport(*this, mxNumberFormatsSupplier
) );
512 SvXMLExport::~SvXMLExport()
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();
555 if (mxEventListener
.is() && mxModel
.is())
556 mxModel
->removeEventListener(mxEventListener
);
560 void SAL_CALL
SvXMLExport::setSourceDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
562 mxModel
.set( xDoc
, UNO_QUERY
);
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
;
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
;
609 mnExportFlags
&= ~SvXMLExportFlags::SAVEBACKWARDCOMPATIBLE
;
611 // namespaces for user defined attributes
612 Reference
< XMultiServiceFactory
> xFactory( mxModel
, UNO_QUERY
);
617 Reference
< XInterface
> xIfc
=
618 xFactory
->createInstance("com.sun.star.xml.NamespaceMap");
621 Reference
< XNameAccess
> xNamespaceMap( xIfc
, UNO_QUERY
);
622 if( xNamespaceMap
.is() )
624 const Sequence
< OUString
> aPrefixes( xNamespaceMap
->getElementNames() );
625 for( OUString
const & prefix
: aPrefixes
)
628 if( xNamespaceMap
->getByName( prefix
) >>= aURL
)
629 GetNamespaceMap_().Add( prefix
, aURL
);
634 catch(const css::uno::Exception
&)
639 // Determine model type (#i51726#)
640 DetermineModelType_();
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
;
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
;
664 uno::Reference
<document::XEmbeddedObjectResolver
> xTmpObjectResolver(
666 if ( xTmpObjectResolver
.is() )
667 mxEmbeddedResolver
= xTmpObjectResolver
;
670 uno::Reference
<xml::sax::XDocumentHandler
> xTmpDocHandler(
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(
684 if( xTmpPropertySet
.is() )
685 mxExportInfo
= xTmpPropertySet
;
688 if( !mxExportInfo
.is() )
691 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
=
692 mxExportInfo
->getPropertySetInfo();
695 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
697 uno::Any aAny
= mxExportInfo
->getPropertyValue(sPropName
);
698 aAny
>>= msOrigFileName
;
699 mpImpl
->msPackageURI
= msOrigFileName
;
700 mpImpl
->SetSchemeOf( msOrigFileName
);
703 sPropName
= "StreamRelPath";
704 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
706 uno::Any aAny
= mxExportInfo
->getPropertyValue(sPropName
);
710 sPropName
= "StreamName";
711 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
713 uno::Any aAny
= mxExportInfo
->getPropertyValue(sPropName
);
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
;
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() )
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
) )
774 else if ( rPropName
== "FilterName" )
776 if( !(rValue
>>= msFilterName
) )
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
))
792 else if (rPropName
== "DestinationShellID")
794 if (!(rValue
>>= mpImpl
->maDestShellID
))
797 else if( rPropName
== "ImageFilter")
799 if (!(rValue
>>= msImgFilterName
))
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
+ "\"");
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()
829 Sequence
<OUString
> aEmptySeq
;
830 SetError(XMLERROR_CANCEL
|XMLERROR_FLAG_SEVERE
, aEmptySeq
);
833 OUString SAL_CALL
SvXMLExport::getName( )
838 void SAL_CALL
SvXMLExport::setName( const OUString
& )
840 // do nothing, because it is not possible to set the FilterName
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" };
860 SvXMLExport::EnsureNamespace(OUString
const & i_rNamespace
)
862 OUString
const aPreferredPrefix("gen");
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
);
873 while( nKey
!= USHRT_MAX
)
875 buf
.append( aPreferredPrefix
);
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
) );
895 buf
.append( sPrefix
);
896 AddAttribute( buf
.makeStringAndClear(), i_rNamespace
);
900 // If there is a prefix for the namespace, reuse that.
901 sPrefix
= GetNamespaceMap_().GetPrefixByKey( nKey
);
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
) ),
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(
959 void SvXMLExport::AddAttribute( const OUString
& rQName
,
960 enum ::xmloff::token::XMLTokenEnum eValue
)
962 mxAttrList
->AddAttribute(
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
);
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());
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
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
)
1029 mxAttrList
->AppendAttributeList( xAttrList
);
1032 void SvXMLExport::ClearAttrList()
1034 mxAttrList
->Clear();
1038 void SvXMLExport::CheckAttrList()
1040 SAL_WARN_IF( mxAttrList
->getLength(), "xmloff.core", "XMLExport::CheckAttrList: list is not empty" );
1044 void SvXMLExport::ImplExportMeta()
1051 void SvXMLExport::ImplExportSettings()
1055 ::std::vector
< SettingsGroup
> aSettings
;
1056 sal_Int32 nSettingsCount
= 0;
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
,
1079 SettingsExportFacade
aSettingsExportContext( *this );
1080 XMLSettingsExportHelper
aSettingsExportHelper( aSettingsExportContext
);
1082 for (auto const& settings
: aSettings
)
1084 if ( !settings
.aSettings
.hasElements() )
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()
1100 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
, XML_STYLES
,
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
,
1156 ExportMasterStyles_();
1159 void SvXMLExport::ImplExportContent()
1166 SvXMLElementExport
aElement( *this, XML_NAMESPACE_OFFICE
, XML_BODY
,
1169 XMLTokenEnum eClass
= meClass
;
1170 if( XML_TEXT_GLOBAL
== eClass
)
1172 AddAttribute( XML_NAMESPACE_TEXT
, XML_GLOBAL
,
1173 GetXMLToken( XML_TRUE
) );
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
,
1189 void SvXMLExport::SetBodyAttributes()
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;
1203 // #i115030#: disabled, the XSLT is not finished, and not available via HTTP
1205 if (SvXMLExportFlags::SETTINGS
!= nExportMode
) // meta, content, styles
1207 rExport
.AddAttribute( XML_NAMESPACE_GRDDL
, XML_TRANSFORMATION
,
1208 OUString("http://FIXME") );
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
);
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
=
1272 ? PropertySetMerger_CreateInstance( mxExportInfo
,
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
),
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 ...>
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;
1327 SAL_WARN("xmloff.core", "xmloff::SvXMLExport::exportDoc(), unexpected odf default version!");
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
)
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
;
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 );
1377 if( mnExportFlags
& SvXMLExportFlags::META
)
1381 if( mnExportFlags
& SvXMLExportFlags::SETTINGS
)
1382 ImplExportSettings();
1385 if( mnExportFlags
& SvXMLExportFlags::SCRIPTS
)
1388 // font declarations
1389 if( mnExportFlags
& SvXMLExportFlags::FONTDECLS
)
1393 if( mnExportFlags
& SvXMLExportFlags::STYLES
)
1397 if( mnExportFlags
& SvXMLExportFlags::AUTOSTYLES
)
1398 ImplExportAutoStyles();
1401 if( mnExportFlags
& SvXMLExportFlags::MASTERSTYLES
)
1402 ImplExportMasterStyles();
1405 if( mnExportFlags
& SvXMLExportFlags::CONTENT
)
1406 ImplExportContent();
1409 mxHandler
->endDocument();
1411 if( bOwnGraphicResolver
)
1413 uno::Reference
<XComponent
> xComp(mxGraphicStorageHandler
, UNO_QUERY
);
1417 if( bOwnEmbeddedResolver
)
1419 Reference
< XComponent
> xComp( mxEmbeddedResolver
, UNO_QUERY
);
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
,
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
);
1456 SvXMLElementExport
aElem( *this, XML_NAMESPACE_OFFICE
, XML_META
,
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
,
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 );
1483 Reference
< beans::XPropertySet
> xPSet( mxModel
, UNO_QUERY
);
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
);
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
);
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
);
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
);
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
);
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();
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() )
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
>& )
1784 void SvXMLExport::collectDataStyles(bool bFromUsedStyles
)
1786 Reference
<style::XStyleFamiliesSupplier
> xStyleFamiliesSupplier(GetModel(), uno::UNO_QUERY
);
1787 if (!xStyleFamiliesSupplier
.is())
1790 Reference
<container::XNameAccess
> xStylesFamilies(xStyleFamiliesSupplier
->getStyleFamilies());
1791 if (!xStylesFamilies
.is())
1794 Reference
<container::XIndexAccess
> xCellStyles(xStylesFamilies
->getByName("CellStyles"), uno::UNO_QUERY
);
1795 if (!xCellStyles
.is())
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())
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*/ )
1818 mpNumExport
->SetUsed(nNumberFormat
);
1821 void SvXMLExport::exportDataStyles()
1824 mpNumExport
->Export(false);
1827 void SvXMLExport::exportAutoDataStyles()
1830 mpNumExport
->Export(true);
1832 if (mxFormExport
.is())
1833 mxFormExport
->exportAutoControlNumberStyles();
1836 OUString
SvXMLExport::getDataStyleName(const sal_Int32 nNumberFormat
, bool /*bTimeFormat*/ ) const
1840 sTemp
= mpNumExport
->GetStyleName(nNumberFormat
);
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
)
1858 Graphic
aGraphic(rxGraphic
);
1859 OUString aOriginURL
= aGraphic
.getOriginURL();
1861 if (!aOriginURL
.isEmpty())
1863 sURL
= GetRelativeReference(aOriginURL
);
1867 if (mxGraphicStorageHandler
.is())
1869 if (!(getExportFlags() & SvXMLExportFlags::EMBEDDED
))
1870 sURL
= mxGraphicStorageHandler
->saveGraphicByName(rxGraphic
, rOutMimeType
, rRequestedName
);
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
);
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
);
1911 OUString
SvXMLExport::AddEmbeddedObject( const OUString
& rEmbeddedObjectURL
)
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
);
1921 sRet
= GetRelativeReference( rEmbeddedObjectURL
);
1926 bool SvXMLExport::AddEmbeddedObjectAsBase64( const OUString
& rEmbeddedObjectURL
)
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
);
1936 Any aAny
= xNA
->getByName( rEmbeddedObjectURL
);
1937 Reference
< XInputStream
> xIn
;
1941 XMLBase64Export
aBase64Exp( *this );
1942 bRet
= aBase64Exp
.exportOfficeBinaryDataElement( xIn
);
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
))
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
));
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
;
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
);
2059 SAL_WARN_IF( !sFilterService
.getLength(), "xmloff.core", "no export filter for own object" );
2061 if( sFilterService
.isEmpty() )
2064 Reference
< XDocumentHandler
> xHdl
=
2065 new XMLEmbeddedObjectExportFilter( mxHandler
);
2067 Sequence
< Any
> aArgs( 1 );
2070 Reference
< document::XExporter
> xExporter(
2071 m_xContext
->getServiceManager()->createInstanceWithArgumentsAndContext(sFilterService
, aArgs
, m_xContext
),
2073 SAL_WARN_IF( !xExporter
.is(), "xmloff.core", "can't instantiate export filter component for own object" );
2074 if( !xExporter
.is() )
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
);
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 );
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
,
2180 EndElement(GetNamespaceMap_().GetQNameByKey( nPrefix
, GetXMLToken(eName
) ),
2184 void SvXMLExport::EndElement(const OUString
& rName
,
2187 // decrement nesting depth counter & (maybe) restore namespace map
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
)
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(
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(
2263 const Sequence
<OUString
>& rMsgParams
)
2265 SetError( nId
, rMsgParams
, "", nullptr );
2268 void SvXMLExport::DisposingModel()
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
2297 return mpImpl
->maSaveOptions
.GetODFDefaultVersion();
2299 // fatal error, use current version as default
2300 return SvtSaveOptions::ODFVER_012
;
2303 SvtSaveOptions::ODFSaneDefaultVersion
SvXMLExport::getSaneDefaultVersion() const
2306 return mpImpl
->maSaveOptions
.GetODFSaneDefaultVersion();
2308 // fatal error, use current version as default
2309 return SvtSaveOptions::ODFSVER_LATEST
;
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
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;
2337 const uno::Reference
<rdf::XMetadatable
> xMeta(i_xIfc
,
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
);
2354 SAL_WARN("xmloff.core","SvXMLExport::AddAttributeXmlId: invalid stream name");
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
);
2371 SAL_INFO("xmloff.core", "SvXMLExport::AddAttributeXmlId: no stream name given: dropping styles.xml xml:id");
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;
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(
2433 sal_uInt16 nPrefixKey
,
2434 const sal_Char
*pLName
,
2439 , mbIgnoreWhitespaceInside( bIWSInside
)
2440 , mbDoSomething( true )
2442 const OUString
sLName( OUString::createFromAscii( pLName
) );
2443 StartElement( nPrefixKey
, sLName
, bIWSOutside
);
2446 SvXMLElementExport::SvXMLElementExport(
2448 sal_uInt16 nPrefixKey
,
2449 const OUString
& rLName
,
2454 , mbIgnoreWhitespaceInside( bIWSInside
)
2455 , mbDoSomething( true )
2457 StartElement( nPrefixKey
, rLName
, bIWSOutside
);
2460 SvXMLElementExport::SvXMLElementExport(
2462 sal_uInt16 nPrefixKey
,
2463 enum XMLTokenEnum eLName
,
2468 , mbIgnoreWhitespaceInside( bIWSInside
)
2469 , mbDoSomething( true )
2471 StartElement( nPrefixKey
, GetXMLToken(eLName
), bIWSOutside
);
2474 SvXMLElementExport::SvXMLElementExport(
2477 sal_uInt16 nPrefixKey
,
2478 enum XMLTokenEnum eLName
,
2483 , mbIgnoreWhitespaceInside( bIWSInside
)
2484 , mbDoSomething( bDoSth
)
2486 if ( mbDoSomething
)
2487 StartElement( nPrefixKey
, GetXMLToken( eLName
), bIWSOutside
);
2490 SvXMLElementExport::SvXMLElementExport(
2492 const OUString
& rQName
,
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: */