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 .
22 #include <tools/diagnose_ex.h>
23 #include <com/sun/star/beans/XPropertySetInfo.hpp>
24 #include <tools/urlobj.hxx>
25 #include <osl/mutex.hxx>
26 #include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
27 #include <xmloff/nmspmap.hxx>
28 #include <xmloff/xmluconv.hxx>
29 #include <xmloff/xmlnmspe.hxx>
30 #include <xmloff/xmltoken.hxx>
31 #include <xmloff/XMLFontStylesContext.hxx>
32 #include <xmloff/xmlictxt.hxx>
33 #include <xmloff/xmlimp.hxx>
34 #include <xmloff/xmlnumfi.hxx>
35 #include "XMLEventImportHelper.hxx"
36 #include "XMLStarBasicContextFactory.hxx"
37 #include "XMLScriptContextFactory.hxx"
38 #include "StyleMap.hxx"
39 #include <xmloff/ProgressBarHelper.hxx>
40 #include <xmloff/xmlerror.hxx>
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
43 #include <com/sun/star/io/XOutputStream.hpp>
44 #include <com/sun/star/util/MeasureUnit.hpp>
45 #include <com/sun/star/document/XBinaryStreamResolver.hpp>
46 #include <com/sun/star/document/XStorageBasedDocument.hpp>
47 #include <com/sun/star/xml/sax/XLocator.hpp>
48 #include <com/sun/star/packages/zip/ZipIOException.hpp>
49 #include <comphelper/namecontainer.hxx>
50 #include <comphelper/servicehelper.hxx>
51 #include <cppuhelper/implbase.hxx>
52 #include <cppuhelper/supportsservice.hxx>
53 #include <comphelper/extract.hxx>
54 #include <comphelper/processfactory.hxx>
55 #include <comphelper/documentconstants.hxx>
56 #include <comphelper/storagehelper.hxx>
57 #include <unotools/fontcvt.hxx>
59 #include <com/sun/star/rdf/XMetadatable.hpp>
60 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
61 #include "RDFaImportHelper.hxx"
63 using ::com::sun::star::beans::XPropertySetInfo
;
65 using namespace ::osl
;
66 using namespace ::com::sun::star
;
67 using namespace ::com::sun::star::frame
;
68 using namespace ::com::sun::star::uno
;
69 using namespace ::com::sun::star::util
;
70 using namespace ::com::sun::star::io
;
71 using namespace ::com::sun::star::container
;
72 using namespace ::com::sun::star::document
;
73 using namespace ::xmloff::token
;
75 sal_Char
const sXML_np_office
[] = "_office";
76 sal_Char
const sXML_np_office_ext
[] = "_office_ooo";
77 sal_Char
const sXML_np_ooo
[] = "_ooo";
78 sal_Char
const sXML_np_ooow
[] = "_ooow";
79 sal_Char
const sXML_np_oooc
[] = "_oooc";
80 sal_Char
const sXML_np_of
[] = "_of";
81 sal_Char
const sXML_np_style
[] = "_style";
82 sal_Char
const sXML_np_text
[] = "_text";
83 sal_Char
const sXML_np_table
[] = "_table";
84 sal_Char
const sXML_np_table_ext
[] = "_table_ooo";
85 sal_Char
const sXML_np_draw
[] = "_draw";
86 sal_Char
const sXML_np_draw_ext
[] = "_draw_ooo";
87 sal_Char
const sXML_np_dr3d
[] = "_dr3d";
88 sal_Char
const sXML_np_fo
[] = "_fo";
89 sal_Char
const sXML_np_xlink
[] = "_xlink";
90 sal_Char
const sXML_np_dc
[] = "_dc";
91 sal_Char
const sXML_np_dom
[] = "_dom";
92 sal_Char
const sXML_np_meta
[] = "_meta";
93 sal_Char
const sXML_np_number
[] = "_number";
94 sal_Char
const sXML_np_svg
[] = "_svg";
95 sal_Char
const sXML_np_chart
[] = "_chart";
96 sal_Char
const sXML_np_math
[] = "_math";
97 sal_Char
const sXML_np_form
[] = "_form";
98 sal_Char
const sXML_np_script
[] = "_script";
99 sal_Char
const sXML_np_config
[] = "_config";
100 sal_Char
const sXML_np_xforms
[] = "_xforms";
101 sal_Char
const sXML_np_formx
[] = "_formx";
102 sal_Char
const sXML_np_xsd
[] = "_xsd";
103 sal_Char
const sXML_np_xsi
[] = "_xsi";
104 sal_Char
const sXML_np_field
[] = "_field";
105 sal_Char
const sXML_np_xhtml
[] = "_xhtml";
106 sal_Char
const sXML_np_css3text
[] = "_css3text";
108 class SvXMLImportEventListener
: public cppu::WeakImplHelper
< css::lang::XEventListener
>
111 SvXMLImport
* pImport
;
114 explicit SvXMLImportEventListener(SvXMLImport
* pImport
);
115 virtual ~SvXMLImportEventListener();
118 virtual void SAL_CALL
disposing(const lang::EventObject
& rEventObject
) throw(css::uno::RuntimeException
, std::exception
) override
;
121 SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport
* pTempImport
)
122 : pImport(pTempImport
)
126 SvXMLImportEventListener::~SvXMLImportEventListener()
131 void SAL_CALL
SvXMLImportEventListener::disposing( const lang::EventObject
& )
132 throw(uno::RuntimeException
, std::exception
)
136 pImport
->DisposingModel();
145 getBuildIdsProperty(uno::Reference
<beans::XPropertySet
> const& xImportInfo
)
147 if (xImportInfo
.is())
151 Reference
< XPropertySetInfo
> const xSetInfo(
152 xImportInfo
->getPropertySetInfo());
153 if (xSetInfo
.is() && xSetInfo
->hasPropertyByName("BuildId"))
156 xImportInfo
->getPropertyValue("BuildId") >>= aBuildId
;
160 catch (Exception
const&)
162 SAL_WARN("xmloff.core", "exception getting BuildId");
163 DBG_UNHANDLED_EXCEPTION();
172 sal_uInt16 mnGeneratorVersion
;
175 explicit DocumentInfo( const SvXMLImport
& rImport
)
176 : mnGeneratorVersion( SvXMLImport::ProductVersionUnknown
)
178 OUString
const buildIds(
179 getBuildIdsProperty(rImport
.getImportInfo()));
180 if (!buildIds
.isEmpty())
182 sal_Int32
const ix
= buildIds
.indexOf(';');
185 OUString
const loVersion(buildIds
.copy(ix
+ 1));
186 if (!loVersion
.isEmpty())
188 if ('3' == loVersion
[0])
190 mnGeneratorVersion
= SvXMLImport::LO_3x
;
192 else if ('4' == loVersion
[0])
194 if (loVersion
.getLength() > 1
195 && (loVersion
[1] == '0' || loVersion
[1] == '1'))
197 mnGeneratorVersion
= SvXMLImport::LO_41x
; // 4.0/4.1
199 else if (loVersion
.getLength() > 1 && '2' == loVersion
[1])
201 mnGeneratorVersion
= SvXMLImport::LO_42x
; // 4.2
203 else if (loVersion
.getLength() > 1 && '3' == loVersion
[1])
205 mnGeneratorVersion
= SvXMLImport::LO_43x
; // 4.3
207 else if (loVersion
.getLength() > 1 && '4' == loVersion
[1])
209 mnGeneratorVersion
= SvXMLImport::LO_44x
; // 4.4
214 SAL_INFO_IF('5' != loVersion
[0], "xmloff.core", "unknown LO version: " << loVersion
);
215 mnGeneratorVersion
= SvXMLImport::LO_5x
;
217 return; // ignore buildIds
221 sal_Int32 nUPD
, nBuild
;
222 if ( rImport
.getBuildIds( nUPD
, nBuild
) )
224 if ( nUPD
>= 640 && nUPD
<= 645 )
226 mnGeneratorVersion
= SvXMLImport::OOo_1x
;
228 else if ( nUPD
== 680 )
230 mnGeneratorVersion
= SvXMLImport::OOo_2x
;
232 else if ( nUPD
== 300 && nBuild
<= 9379 )
234 mnGeneratorVersion
= SvXMLImport::OOo_30x
;
236 else if ( nUPD
== 310 )
238 mnGeneratorVersion
= SvXMLImport::OOo_31x
;
240 else if ( nUPD
== 320 )
242 mnGeneratorVersion
= SvXMLImport::OOo_32x
;
244 else if ( nUPD
== 330 )
246 mnGeneratorVersion
= SvXMLImport::OOo_33x
;
248 else if ( nUPD
== 340 )
250 mnGeneratorVersion
= SvXMLImport::OOo_34x
;
252 else if (nUPD
== 400)
254 mnGeneratorVersion
= SvXMLImport::AOO_40x
;
256 else if (nUPD
>= 410)
258 // effectively this means "latest", see use
259 // in XMLGraphicsDefaultStyle::SetDefaults()!
260 mnGeneratorVersion
= SvXMLImport::AOO_4x
;
268 sal_uInt16
getGeneratorVersion() const
270 return mnGeneratorVersion
;
276 class SvXMLImport_Impl
279 FontToSubsFontConverter hBatsFontConv
;
280 FontToSubsFontConverter hMathFontConv
;
282 bool mbOwnGraphicResolver
;
283 bool mbOwnEmbeddedResolver
;
284 INetURLObject aBaseURL
;
285 INetURLObject aDocBase
;
287 /// name of stream in package, e.g., "content.xml"
288 OUString mStreamName
;
290 OUString aODFVersion
;
294 // Boolean, indicating that position attributes
295 // of shapes are given in horizontal left-to-right layout. This is the case
296 // for the OpenOffice.org file format. (#i28749#)
297 bool mbShapePositionInHoriL2R
;
298 bool mbTextDocInOOoFileFormat
;
300 const uno::Reference
< uno::XComponentContext
> mxComponentContext
;
301 OUString implementationName
;
303 uno::Reference
< embed::XStorage
> mxSourceStorage
;
305 std::unique_ptr
< xmloff::RDFaImportHelper
> mpRDFaHelper
;
307 std::unique_ptr
< DocumentInfo
> mpDocumentInfo
;
309 SvXMLImport_Impl( const uno::Reference
< uno::XComponentContext
>& rxContext
,
310 OUString
const & theImplementationName
)
311 : hBatsFontConv( nullptr )
312 , hMathFontConv( nullptr )
313 , mbOwnGraphicResolver( false )
314 , mbOwnEmbeddedResolver( false )
316 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
317 , mbShapePositionInHoriL2R( false )
318 , mbTextDocInOOoFileFormat( false )
319 , mxComponentContext( rxContext
)
320 , implementationName(theImplementationName
)
321 , mpRDFaHelper() // lazy
322 , mpDocumentInfo() // lazy
324 SAL_WARN_IF(!mxComponentContext
.is(), "xmloff.core", "SvXMLImport: no ComponentContext");
325 if (!mxComponentContext
.is()) throw uno::RuntimeException();
331 DestroyFontToSubsFontConverter( hBatsFontConv
);
333 DestroyFontToSubsFontConverter( hMathFontConv
);
336 sal_uInt16
getGeneratorVersion( const SvXMLImport
& rImport
)
338 if ( !mpDocumentInfo
.get() )
340 mpDocumentInfo
.reset( new DocumentInfo( rImport
) );
343 return mpDocumentInfo
->getGeneratorVersion();
346 ::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper
;
349 SvXMLImportContext
*SvXMLImport::CreateContext( sal_uInt16 nPrefix
,
350 const OUString
& rLocalName
,
351 const uno::Reference
< xml::sax::XAttributeList
>& )
353 return new SvXMLImportContext( *this, nPrefix
, rLocalName
);
356 SvXMLImportContext
*SvXMLImport::CreateFastContext( sal_Int32
/*Element*/,
357 const uno::Reference
< xml::sax::XFastAttributeList
>& /*xAttrList*/ )
359 return new SvXMLImportContext( *this );
362 void SvXMLImport::InitCtor_()
364 if( mnImportFlags
!= SvXMLImportFlags::NONE
)
366 // implicit "xml" namespace prefix
367 mpNamespaceMap
->Add( GetXMLToken(XML_XML
), GetXMLToken(XML_N_XML
), XML_NAMESPACE_XML
);
368 mpNamespaceMap
->Add( sXML_np_office
, GetXMLToken(XML_N_OFFICE
), XML_NAMESPACE_OFFICE
);
369 mpNamespaceMap
->Add( sXML_np_office_ext
, GetXMLToken(XML_N_OFFICE_EXT
), XML_NAMESPACE_OFFICE_EXT
);
370 mpNamespaceMap
->Add( sXML_np_ooo
, GetXMLToken(XML_N_OOO
), XML_NAMESPACE_OOO
);
371 mpNamespaceMap
->Add( sXML_np_style
, GetXMLToken(XML_N_STYLE
), XML_NAMESPACE_STYLE
);
372 mpNamespaceMap
->Add( sXML_np_text
, GetXMLToken(XML_N_TEXT
), XML_NAMESPACE_TEXT
);
373 mpNamespaceMap
->Add( sXML_np_table
, GetXMLToken(XML_N_TABLE
), XML_NAMESPACE_TABLE
);
374 mpNamespaceMap
->Add( sXML_np_table_ext
, GetXMLToken(XML_N_TABLE_EXT
), XML_NAMESPACE_TABLE_EXT
);
375 mpNamespaceMap
->Add( sXML_np_draw
, GetXMLToken(XML_N_DRAW
), XML_NAMESPACE_DRAW
);
376 mpNamespaceMap
->Add( sXML_np_draw_ext
, GetXMLToken(XML_N_DRAW_EXT
), XML_NAMESPACE_DRAW_EXT
);
377 mpNamespaceMap
->Add( sXML_np_dr3d
, GetXMLToken(XML_N_DR3D
), XML_NAMESPACE_DR3D
);
378 mpNamespaceMap
->Add( sXML_np_fo
, GetXMLToken(XML_N_FO_COMPAT
), XML_NAMESPACE_FO
);
379 mpNamespaceMap
->Add( sXML_np_xlink
, GetXMLToken(XML_N_XLINK
), XML_NAMESPACE_XLINK
);
380 mpNamespaceMap
->Add( sXML_np_dc
, GetXMLToken(XML_N_DC
), XML_NAMESPACE_DC
);
381 mpNamespaceMap
->Add( sXML_np_dom
, GetXMLToken(XML_N_DOM
), XML_NAMESPACE_DOM
);
382 mpNamespaceMap
->Add( sXML_np_meta
, GetXMLToken(XML_N_META
), XML_NAMESPACE_META
);
383 mpNamespaceMap
->Add( sXML_np_number
, GetXMLToken(XML_N_NUMBER
), XML_NAMESPACE_NUMBER
);
384 mpNamespaceMap
->Add( sXML_np_svg
, GetXMLToken(XML_N_SVG_COMPAT
), XML_NAMESPACE_SVG
);
385 mpNamespaceMap
->Add( sXML_np_chart
, GetXMLToken(XML_N_CHART
), XML_NAMESPACE_CHART
);
386 mpNamespaceMap
->Add( sXML_np_math
, GetXMLToken(XML_N_MATH
), XML_NAMESPACE_MATH
);
387 mpNamespaceMap
->Add(sXML_np_form
, GetXMLToken(XML_N_FORM
), XML_NAMESPACE_FORM
);
388 mpNamespaceMap
->Add( sXML_np_script
, GetXMLToken(XML_N_SCRIPT
), XML_NAMESPACE_SCRIPT
);
389 mpNamespaceMap
->Add( sXML_np_config
, GetXMLToken(XML_N_CONFIG
), XML_NAMESPACE_CONFIG
);
390 mpNamespaceMap
->Add( sXML_np_xforms
, GetXMLToken(XML_N_XFORMS_1_0
), XML_NAMESPACE_XFORMS
);
391 mpNamespaceMap
->Add( sXML_np_formx
, GetXMLToken( XML_N_FORMX
), XML_NAMESPACE_FORMX
);
392 mpNamespaceMap
->Add( sXML_np_xsd
, GetXMLToken(XML_N_XSD
), XML_NAMESPACE_XSD
);
393 mpNamespaceMap
->Add( sXML_np_xsi
, GetXMLToken(XML_N_XSI
), XML_NAMESPACE_XFORMS
);
394 mpNamespaceMap
->Add( sXML_np_ooow
, GetXMLToken(XML_N_OOOW
), XML_NAMESPACE_OOOW
);
395 mpNamespaceMap
->Add( sXML_np_oooc
, GetXMLToken(XML_N_OOOC
), XML_NAMESPACE_OOOC
);
396 mpNamespaceMap
->Add( sXML_np_field
, GetXMLToken(XML_N_FIELD
), XML_NAMESPACE_FIELD
);
397 mpNamespaceMap
->Add( sXML_np_of
, GetXMLToken(XML_N_OF
), XML_NAMESPACE_OF
);
398 mpNamespaceMap
->Add( sXML_np_xhtml
, GetXMLToken(XML_N_XHTML
), XML_NAMESPACE_XHTML
);
399 mpNamespaceMap
->Add( sXML_np_css3text
, GetXMLToken(XML_N_CSS3TEXT
), XML_NAMESPACE_CSS3TEXT
);
401 mpNamespaceMap
->Add( "_calc_libo", GetXMLToken(XML_N_CALC_EXT
), XML_NAMESPACE_CALC_EXT
);
402 mpNamespaceMap
->Add( "_office_libo",
403 GetXMLToken(XML_N_LO_EXT
), XML_NAMESPACE_LO_EXT
);
406 msPackageProtocol
= "vnd.sun.star.Package:";
408 if (mxNumberFormatsSupplier
.is())
409 mpNumImport
= new SvXMLNumFmtHelper(mxNumberFormatsSupplier
, GetComponentContext());
411 if (mxModel
.is() && !mxEventListener
.is())
413 mxEventListener
.set(new SvXMLImportEventListener(this));
414 mxModel
->addEventListener(mxEventListener
);
418 SvXMLImport::SvXMLImport(
419 const css::uno::Reference
< css::uno::XComponentContext
>& xContext
,
420 OUString
const & implementationName
, SvXMLImportFlags nImportFlags
) throw ()
421 : mpImpl( new SvXMLImport_Impl(xContext
, implementationName
) ),
422 mpNamespaceMap( new SvXMLNamespaceMap
),
424 mpUnitConv( new SvXMLUnitConverter( xContext
,
425 util::MeasureUnit::MM_100TH
, util::MeasureUnit::MM_100TH
) ),
427 mpContexts( new SvXMLImportContexts_Impl
),
428 mpFastContexts( new FastSvXMLImportContexts_Impl
),
429 mpNumImport( nullptr ),
430 mpProgressBarHelper( nullptr ),
431 mpEventImportHelper( nullptr ),
432 mpXMLErrors( nullptr ),
434 mnImportFlags( nImportFlags
),
435 mnErrorFlags(SvXMLErrorFlags::NO
),
436 mbIsFormsSupported( true ),
437 mbIsTableShapeSupported( false ),
438 mbIsGraphicLoadOnDemandSupported( true )
440 SAL_WARN_IF( !xContext
.is(), "xmloff.core", "got no service manager" );
444 SvXMLImport::~SvXMLImport() throw ()
447 delete mpNamespaceMap
;
449 delete mpEventImportHelper
;
450 delete mpFastContexts
;
453 while( !mpContexts
->empty() )
455 SvXMLImportContext
*pContext
= mpContexts
->back();
456 mpContexts
->pop_back();
458 pContext
->ReleaseRef();
463 // #i9518# the import component might not be deleted until after the document has been closed,
464 // so the stuff that accesses the document has been moved to endDocument.
466 // pNumImport is allocated in the ctor, so it must also be deleted here in case the component
467 // is created and deleted without actually importing.
469 delete mpProgressBarHelper
;
471 if (mxEventListener
.is() && mxModel
.is())
472 mxModel
->removeEventListener(mxEventListener
);
477 class theSvXMLImportUnoTunnelId
: public rtl::Static
< UnoTunnelIdInit
, theSvXMLImportUnoTunnelId
> {};
481 const uno::Sequence
< sal_Int8
> & SvXMLImport::getUnoTunnelId() throw()
483 return theSvXMLImportUnoTunnelId::get().getSeq();
487 sal_Int64 SAL_CALL
SvXMLImport::getSomething( const uno::Sequence
< sal_Int8
>& rId
)
488 throw( uno::RuntimeException
, std::exception
)
490 if( rId
.getLength() == 16 && 0 == memcmp( getUnoTunnelId().getConstArray(),
491 rId
.getConstArray(), 16 ) )
493 return sal::static_int_cast
<sal_Int64
>(reinterpret_cast<sal_uIntPtr
>(this));
498 void SAL_CALL
SvXMLImport::startDocument()
499 throw (xml::sax::SAXException
,
500 uno::RuntimeException
,
503 SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
504 if( !mxGraphicResolver
.is() || !mxEmbeddedResolver
.is() )
506 Reference
< lang::XMultiServiceFactory
> xFactory( mxModel
, UNO_QUERY
);
511 if( !mxGraphicResolver
.is() )
513 // #99870# Import... instead of Export...
514 mxGraphicResolver
.set(
515 xFactory
->createInstance("com.sun.star.document.ImportGraphicObjectResolver"),
517 mpImpl
->mbOwnGraphicResolver
= mxGraphicResolver
.is();
520 if( !mxEmbeddedResolver
.is() )
522 // #99870# Import... instead of Export...
523 mxEmbeddedResolver
.set(
524 xFactory
->createInstance("com.sun.star.document.ImportEmbeddedObjectResolver"),
526 mpImpl
->mbOwnEmbeddedResolver
= mxEmbeddedResolver
.is();
529 catch( css::uno::Exception
& )
536 void SAL_CALL
SvXMLImport::endDocument()
537 throw(xml::sax::SAXException
,
538 uno::RuntimeException
,
541 SAL_INFO( "xmloff.core", "} SvXMLImport::startDocument" );
542 // #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
543 // because the SvXMLImport dtor might not be called until after the document has been closed.
545 GetTextImport()->MapCrossRefHeadingFieldsHorribly();
547 if (mpImpl
->mpRDFaHelper
.get())
549 const uno::Reference
<rdf::XRepositorySupplier
> xRS(mxModel
,
553 mpImpl
->mpRDFaHelper
->InsertRDFa( xRS
);
560 mpNumImport
= nullptr;
562 if (mxImportInfo
.is())
564 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
565 if (xPropertySetInfo
.is())
567 if (mpProgressBarHelper
)
569 OUString
sProgressMax(XML_PROGRESSMAX
);
570 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
571 OUString
sRepeat(XML_PROGRESSREPEAT
);
572 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
573 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
))
575 sal_Int32
nProgressMax(mpProgressBarHelper
->GetReference());
576 sal_Int32
nProgressCurrent(mpProgressBarHelper
->GetValue());
577 mxImportInfo
->setPropertyValue(sProgressMax
, uno::Any(nProgressMax
));
578 mxImportInfo
->setPropertyValue(sProgressCurrent
, uno::Any(nProgressCurrent
));
580 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
581 mxImportInfo
->setPropertyValue(sRepeat
, css::uno::makeAny(mpProgressBarHelper
->GetRepeat()));
582 // pProgressBarHelper is deleted in dtor
584 OUString
sNumberStyles(XML_NUMBERSTYLES
);
585 if (mxNumberStyles
.is() && xPropertySetInfo
->hasPropertyByName(sNumberStyles
))
587 mxImportInfo
->setPropertyValue(sNumberStyles
, Any(mxNumberStyles
));
592 if( mxFontDecls
.Is() )
593 static_cast<SvXMLStylesContext
*>(&mxFontDecls
)->Clear();
595 static_cast<SvXMLStylesContext
*>(&mxStyles
)->Clear();
596 if( mxAutoStyles
.Is() )
597 static_cast<SvXMLStylesContext
*>(&mxAutoStyles
)->Clear();
598 if( mxMasterStyles
.Is() )
599 static_cast<SvXMLStylesContext
*>(&mxMasterStyles
)->Clear();
601 // possible form-layer related knittings which can only be done when
602 // the whole document exists
603 if ( mxFormImport
.is() )
604 mxFormImport
->documentDone();
606 // The shape import helper does the z-order sorting in the dtor,
607 // so it must be deleted here, too.
608 mxShapeImport
= nullptr;
610 if( mpImpl
->mbOwnGraphicResolver
)
612 Reference
< lang::XComponent
> xComp( mxGraphicResolver
, UNO_QUERY
);
616 if( mpImpl
->mbOwnEmbeddedResolver
)
618 Reference
< lang::XComponent
> xComp( mxEmbeddedResolver
, UNO_QUERY
);
623 mpStyleMap
->release();
624 mpStyleMap
= nullptr;
627 if ( mpXMLErrors
!= nullptr )
629 mpXMLErrors
->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE
);
633 void SAL_CALL
SvXMLImport::startElement( const OUString
& rName
,
634 const uno::Reference
< xml::sax::XAttributeList
>& xAttrList
)
635 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
637 SvXMLNamespaceMap
*pRewindMap
= nullptr;
638 // SAL_INFO("svg", "startElement " << rName);
639 // Process namespace attributes. This must happen before creating the
640 // context, because namespace decaration apply to the element name itself.
641 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
642 for( sal_Int16 i
=0; i
< nAttrCount
; i
++ )
644 const OUString
& rAttrName
= xAttrList
->getNameByIndex( i
);
645 if ( rAttrName
== "office:version" )
647 mpImpl
->aODFVersion
= xAttrList
->getValueByIndex( i
);
649 // the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
650 if ( mpImpl
->mStreamName
== "content.xml" && !IsODFVersionConsistent( mpImpl
->aODFVersion
) )
652 throw xml::sax::SAXException("Inconsistent ODF versions in content.xml and manifest.xml!",
653 uno::Reference
< uno::XInterface
>(),
655 packages::zip::ZipIOException("Inconsistent ODF versions in content.xml and manifest.xml!" ) ) );
658 else if( ( rAttrName
.getLength() >= 5 ) &&
659 ( rAttrName
.startsWith( GetXMLToken(XML_XMLNS
) ) ) &&
660 ( rAttrName
.getLength() == 5 || ':' == rAttrName
[5] ) )
664 pRewindMap
= mpNamespaceMap
;
665 mpNamespaceMap
= new SvXMLNamespaceMap( *mpNamespaceMap
);
667 const OUString
& rAttrValue
= xAttrList
->getValueByIndex( i
);
669 OUString
aPrefix( ( rAttrName
.getLength() == 5 )
671 : rAttrName
.copy( 6 ) );
672 // Add namespace, but only if it is known.
673 sal_uInt16 nKey
= mpNamespaceMap
->AddIfKnown( aPrefix
, rAttrValue
);
674 // If namespace is unknown, try to match a name with similar
676 if( XML_NAMESPACE_UNKNOWN
== nKey
)
678 OUString
aTestName( rAttrValue
);
679 if( SvXMLNamespaceMap::NormalizeURI( aTestName
) )
680 nKey
= mpNamespaceMap
->AddIfKnown( aPrefix
, aTestName
);
682 // If that namespace is not known, too, add it as unknown
683 if( XML_NAMESPACE_UNKNOWN
== nKey
)
684 mpNamespaceMap
->Add( aPrefix
, rAttrValue
);
689 // Get element's namespace and local name.
692 mpNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
694 // If there are contexts already, call a CreateChildContext at the topmost
695 // context. Otherwise, create a default context.
696 SvXMLImportContext
*pContext
;
697 sal_uInt16 nCount
= mpContexts
->size();
700 pContext
= (*mpContexts
)[nCount
- 1]->CreateChildContext( nPrefix
,
703 SAL_WARN_IF( !pContext
|| (pContext
->GetPrefix() != nPrefix
), "xmloff.core",
704 "SvXMLImport::startElement: created context has wrong prefix" );
708 pContext
= CreateContext( nPrefix
, aLocalName
, xAttrList
);
709 if( (nPrefix
& XML_NAMESPACE_UNKNOWN_FLAG
) != 0 &&
710 dynamic_cast< const SvXMLImportContext
*>(pContext
) != nullptr )
712 OUString
aMsg( "Root element unknown" );
713 Reference
<xml::sax::XLocator
> xDummyLocator
;
714 Sequence
< OUString
> aParams
{ rName
};
716 SetError( XMLERROR_FLAG_SEVERE
|XMLERROR_UNKNOWN_ROOT
,
717 aParams
, aMsg
, xDummyLocator
);
721 SAL_WARN_IF( !pContext
, "xmloff.core", "SvXMLImport::startElement: missing context" );
723 pContext
= new SvXMLImportContext( *this, nPrefix
, aLocalName
);
725 pContext
->AddFirstRef();
727 // Remember old namespace map.
729 pContext
->PutRewindMap( pRewindMap
);
731 // Call a startElement at the new context.
732 pContext
->StartElement( xAttrList
);
734 // Push context on stack.
735 mpContexts
->push_back( pContext
);
738 void SAL_CALL
SvXMLImport::endElement( const OUString
&
743 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
745 sal_uInt16 nCount
= mpContexts
->size();
746 SAL_WARN_IF( nCount
== 0, "xmloff.core", "SvXMLImport::endElement: no context left" );
749 // Get topmost context and remove it from the stack.
750 SvXMLImportContext
*pContext
= mpContexts
->back();
751 mpContexts
->pop_back();
754 // Non product only: check if endElement call matches startELement call.
757 mpNamespaceMap
->GetKeyByAttrName( rName
, &aLocalName
);
758 SAL_WARN_IF( pContext
->GetPrefix() != nPrefix
, "xmloff.core", "SvXMLImport::endElement: popped context has wrong prefix" );
759 SAL_WARN_IF( pContext
->GetLocalName() != aLocalName
, "xmloff.core", "SvXMLImport::endElement: popped context has wrong lname" );
762 // Call a EndElement at the current context.
763 pContext
->EndElement();
765 // Get a namespace map to rewind.
766 SvXMLNamespaceMap
*pRewindMap
= pContext
->TakeRewindMap();
768 // Delete the current context.
769 pContext
->ReleaseRef();
772 // Rewind a namespace map.
775 delete mpNamespaceMap
;
776 mpNamespaceMap
= pRewindMap
;
781 void SAL_CALL
SvXMLImport::characters( const OUString
& rChars
)
782 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
784 if( !mpContexts
->empty() )
786 mpContexts
->back()->Characters( rChars
);
788 else if ( !mpFastContexts
->empty() )
790 mpFastContexts
->back()->characters( rChars
);
794 void SAL_CALL
SvXMLImport::ignorableWhitespace( const OUString
& )
795 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
799 void SAL_CALL
SvXMLImport::processingInstruction( const OUString
&,
801 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
805 void SAL_CALL
SvXMLImport::setDocumentLocator( const uno::Reference
< xml::sax::XLocator
>& rLocator
)
806 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
808 mxLocator
= rLocator
;
811 // XFastContextHandler
812 void SAL_CALL
SvXMLImport::startFastElement (sal_Int32 Element
,
813 const uno::Reference
< xml::sax::XFastAttributeList
> & Attribs
)
814 throw (uno::RuntimeException
, xml::sax::SAXException
, std::exception
)
816 //Namespace handling is unnecessary. It is done by the fastparser itself.
817 uno::Reference
<XFastContextHandler
> xContext
;
818 sal_uInt16 nCount
= mpFastContexts
->size();
821 uno::Reference
< XFastContextHandler
> pHandler
= (*mpFastContexts
)[nCount
- 1];
822 xContext
= pHandler
->createFastChildContext( Element
, Attribs
);
825 xContext
.set( CreateFastContext( Element
, Attribs
) );
827 if ( !xContext
.is() )
828 xContext
.set( new SvXMLImportContext( *this ) );
830 // Call a startElement at the new context.
831 xContext
->startFastElement( Element
, Attribs
);
833 // Push context on stack.
834 mpFastContexts
->push_back( xContext
);
837 void SAL_CALL
SvXMLImport::startUnknownElement (const OUString
&, const OUString
&,
838 const uno::Reference
< xml::sax::XFastAttributeList
> &)
839 throw (uno::RuntimeException
, xml::sax::SAXException
, std::exception
)
843 void SAL_CALL
SvXMLImport::endFastElement (sal_Int32 Element
)
844 throw (uno::RuntimeException
, xml::sax::SAXException
, std::exception
)
846 sal_uInt16 nCount
= mpFastContexts
->size();
849 uno::Reference
< XFastContextHandler
> xContext
= mpFastContexts
->back();
850 mpFastContexts
->pop_back();
851 xContext
->endFastElement( Element
);
856 void SAL_CALL
SvXMLImport::endUnknownElement (const OUString
&, const OUString
&)
857 throw (uno::RuntimeException
, xml::sax::SAXException
, std::exception
)
861 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
862 SvXMLImport::createFastChildContext (sal_Int32
,
863 const uno::Reference
< xml::sax::XFastAttributeList
> &)
864 throw (uno::RuntimeException
, xml::sax::SAXException
, std::exception
)
869 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
870 SvXMLImport::createUnknownChildContext (const OUString
&, const OUString
&,
871 const uno::Reference
< xml::sax::XFastAttributeList
> &)
872 throw (uno::RuntimeException
, xml::sax::SAXException
, std::exception
)
877 // XExtendedDocumentHandler
878 void SAL_CALL
SvXMLImport::startCDATA() throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
882 void SAL_CALL
SvXMLImport::endCDATA() throw(uno::RuntimeException
, std::exception
)
886 void SAL_CALL
SvXMLImport::comment( const OUString
& )
887 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
891 void SAL_CALL
SvXMLImport::allowLineBreak()
892 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
896 void SAL_CALL
SvXMLImport::unknown( const OUString
& )
897 throw(xml::sax::SAXException
, uno::RuntimeException
, std::exception
)
901 void SvXMLImport::SetStatistics(const uno::Sequence
< beans::NamedValue
> &)
903 GetProgressBarHelper()->SetRepeat(false);
904 GetProgressBarHelper()->SetReference(0);
908 void SAL_CALL
SvXMLImport::setTargetDocument( const uno::Reference
< lang::XComponent
>& xDoc
)
909 throw(lang::IllegalArgumentException
, uno::RuntimeException
, std::exception
)
911 mxModel
.set( xDoc
, UNO_QUERY
);
913 throw lang::IllegalArgumentException();
917 uno::Reference
<document::XStorageBasedDocument
> const xSBDoc(mxModel
,
918 uno::UNO_QUERY_THROW
);
919 uno::Reference
<embed::XStorage
> const xStor(
920 xSBDoc
->getDocumentStorage());
924 ::comphelper::OStorageHelper::GetXStorageFormat(xStor
)
925 < SOFFICE_FILEFORMAT_8
;
928 catch (uno::Exception
const&)
930 SAL_WARN("xmloff.core", "exception caught");
931 DBG_UNHANDLED_EXCEPTION();
933 if (!mxEventListener
.is())
935 mxEventListener
.set(new SvXMLImportEventListener(this));
936 mxModel
->addEventListener(mxEventListener
);
939 SAL_WARN_IF( mpNumImport
, "xmloff.core", "number format import already exists." );
943 mpNumImport
= nullptr;
948 sal_Bool SAL_CALL
SvXMLImport::filter( const uno::Sequence
< beans::PropertyValue
>& )
949 throw (uno::RuntimeException
, std::exception
)
954 void SAL_CALL
SvXMLImport::cancel( )
955 throw (uno::RuntimeException
, std::exception
)
960 void SAL_CALL
SvXMLImport::initialize( const uno::Sequence
< uno::Any
>& aArguments
)
961 throw(css::uno::Exception
, css::uno::RuntimeException
, std::exception
)
963 const sal_Int32 nAnyCount
= aArguments
.getLength();
964 const uno::Any
* pAny
= aArguments
.getConstArray();
966 for( sal_Int32 nIndex
= 0; nIndex
< nAnyCount
; nIndex
++, pAny
++ )
968 Reference
<XInterface
> xValue
;
971 uno::Reference
<task::XStatusIndicator
> xTmpStatusIndicator(
973 if( xTmpStatusIndicator
.is() )
974 mxStatusIndicator
= xTmpStatusIndicator
;
976 uno::Reference
<document::XGraphicObjectResolver
> xTmpGraphicResolver(
978 if( xTmpGraphicResolver
.is() )
979 mxGraphicResolver
= xTmpGraphicResolver
;
981 uno::Reference
<document::XEmbeddedObjectResolver
> xTmpObjectResolver(
983 if( xTmpObjectResolver
.is() )
984 mxEmbeddedResolver
= xTmpObjectResolver
;
986 uno::Reference
<beans::XPropertySet
> xTmpPropSet( xValue
, UNO_QUERY
);
987 if( xTmpPropSet
.is() )
989 mxImportInfo
= xTmpPropSet
;
990 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
991 if (xPropertySetInfo
.is())
993 OUString
sPropName(XML_NUMBERSTYLES
);
994 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
996 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
997 aAny
>>= mxNumberStyles
;
1000 sPropName
= "PrivateData";
1001 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1003 Reference
< XInterface
> xIfc
;
1004 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1007 StyleMap
*pSMap
= StyleMap::getImplementation( xIfc
);
1011 mpStyleMap
->acquire();
1015 sPropName
= "BaseURI";
1016 if (xPropertySetInfo
->hasPropertyByName(sPropName
))
1018 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1020 mpImpl
->aBaseURL
.SetURL( sBaseURI
);
1021 mpImpl
->aDocBase
.SetURL( sBaseURI
);
1024 sPropName
= "StreamRelPath";
1025 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1027 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1031 sPropName
= "StreamName";
1032 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1034 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1037 if( !sBaseURI
.isEmpty() && !sName
.isEmpty() )
1039 if( !sRelPath
.isEmpty() )
1040 mpImpl
->aBaseURL
.insertName( sRelPath
);
1041 mpImpl
->aBaseURL
.insertName( sName
);
1043 mpImpl
->mStreamName
= sName
; // Note: may be empty (XSLT)
1044 // Retrieve property <ShapePositionInHoriL2R> (#i28749#)
1045 sPropName
= "ShapePositionInHoriL2R";
1046 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1048 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1049 aAny
>>= (mpImpl
->mbShapePositionInHoriL2R
);
1051 sPropName
= "TextDocInOOoFileFormat";
1052 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1054 uno::Any aAny
= mxImportInfo
->getPropertyValue(sPropName
);
1055 aAny
>>= (mpImpl
->mbTextDocInOOoFileFormat
);
1058 sPropName
= "SourceStorage";
1059 if( xPropertySetInfo
->hasPropertyByName(sPropName
) )
1060 mxImportInfo
->getPropertyValue(sPropName
) >>= mpImpl
->mxSourceStorage
;
1067 OUString SAL_CALL
SvXMLImport::getImplementationName()
1068 throw(uno::RuntimeException
, std::exception
)
1070 return mpImpl
->implementationName
;
1073 sal_Bool SAL_CALL
SvXMLImport::supportsService( const OUString
& rServiceName
)
1074 throw(css::uno::RuntimeException
, std::exception
)
1076 return cppu::supportsService(this, rServiceName
);
1079 uno::Sequence
< OUString
> SAL_CALL
SvXMLImport::getSupportedServiceNames( )
1080 throw(uno::RuntimeException
, std::exception
)
1082 uno::Sequence
<OUString
> aSeq(2);
1083 aSeq
[0] = "com.sun.star.document.ImportFilter";
1084 aSeq
[1] = "com.sun.star.xml.XMLImportFilter";
1088 XMLTextImportHelper
* SvXMLImport::CreateTextImport()
1090 return new XMLTextImportHelper( mxModel
, *this );
1093 XMLShapeImportHelper
* SvXMLImport::CreateShapeImport()
1095 return new XMLShapeImportHelper( *this, mxModel
);
1098 SchXMLImportHelper
* SvXMLImport::CreateChartImport()
1100 return new SchXMLImportHelper();
1103 ::xmloff::OFormLayerXMLImport
* SvXMLImport::CreateFormImport()
1105 return new ::xmloff::OFormLayerXMLImport(*this);
1109 // Get or create fill/line/lineend-style-helper
1112 const Reference
< container::XNameContainer
> & SvXMLImport::GetGradientHelper()
1114 if( !mxGradientHelper
.is() )
1118 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1119 if( xServiceFact
.is() )
1123 mxGradientHelper
.set( xServiceFact
->createInstance(
1124 "com.sun.star.drawing.GradientTable" ), UNO_QUERY
);
1126 catch( lang::ServiceNotRegisteredException
& )
1132 return mxGradientHelper
;
1135 const Reference
< container::XNameContainer
> & SvXMLImport::GetHatchHelper()
1137 if( !mxHatchHelper
.is() )
1141 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1142 if( xServiceFact
.is() )
1146 mxHatchHelper
.set( xServiceFact
->createInstance(
1147 "com.sun.star.drawing.HatchTable" ), UNO_QUERY
);
1149 catch( lang::ServiceNotRegisteredException
& )
1155 return mxHatchHelper
;
1158 const Reference
< container::XNameContainer
> & SvXMLImport::GetBitmapHelper()
1160 if( !mxBitmapHelper
.is() )
1164 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1165 if( xServiceFact
.is() )
1169 mxBitmapHelper
.set( xServiceFact
->createInstance(
1170 "com.sun.star.drawing.BitmapTable" ), UNO_QUERY
);
1172 catch( lang::ServiceNotRegisteredException
& )
1178 return mxBitmapHelper
;
1181 const Reference
< container::XNameContainer
> & SvXMLImport::GetTransGradientHelper()
1183 if( !mxTransGradientHelper
.is() )
1187 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1188 if( xServiceFact
.is() )
1192 mxTransGradientHelper
.set( xServiceFact
->createInstance(
1193 "com.sun.star.drawing.TransparencyGradientTable" ), UNO_QUERY
);
1195 catch( lang::ServiceNotRegisteredException
& )
1201 return mxTransGradientHelper
;
1204 const Reference
< container::XNameContainer
> & SvXMLImport::GetMarkerHelper()
1206 if( !mxMarkerHelper
.is() )
1210 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1211 if( xServiceFact
.is() )
1215 mxMarkerHelper
.set( xServiceFact
->createInstance( "com.sun.star.drawing.MarkerTable" ), UNO_QUERY
);
1217 catch( lang::ServiceNotRegisteredException
& )
1223 return mxMarkerHelper
;
1226 const Reference
< container::XNameContainer
> & SvXMLImport::GetDashHelper()
1228 if( !mxDashHelper
.is() )
1232 Reference
< lang::XMultiServiceFactory
> xServiceFact( mxModel
, UNO_QUERY
);
1233 if( xServiceFact
.is() )
1237 mxDashHelper
.set( xServiceFact
->createInstance( "com.sun.star.drawing.DashTable" ), UNO_QUERY
);
1239 catch( lang::ServiceNotRegisteredException
& )
1245 return mxDashHelper
;
1248 bool SvXMLImport::IsPackageURL( const OUString
& rURL
) const
1251 // if, and only if, only parts are imported, then we're in a package
1252 const SvXMLImportFlags nTest
= SvXMLImportFlags::META
|SvXMLImportFlags::STYLES
|SvXMLImportFlags::CONTENT
|SvXMLImportFlags::SETTINGS
;
1253 if( (mnImportFlags
& nTest
) == nTest
)
1256 // Some quick tests: Some may rely on the package structure!
1257 sal_Int32 nLen
= rURL
.getLength();
1258 if( (nLen
> 0 && '/' == rURL
[0]) )
1259 // RFC2396 net_path or abs_path
1261 else if( nLen
> 1 && '.' == rURL
[0] )
1263 if( '.' == rURL
[1] )
1264 // ../: We are never going up one level, so we know
1265 // it's not an external URI
1267 else if( '/' == rURL
[1] )
1268 // we are remaining on a level, so it's an package URI
1272 // Now check for a RFC2396 schema
1274 while( nPos
< nLen
)
1276 switch( rURL
[nPos
] )
1279 // a relative path segement
1286 // we don't care about any other characters
1294 OUString
SvXMLImport::ResolveGraphicObjectURL( const OUString
& rURL
,
1295 bool bLoadOnDemand
)
1299 if( IsPackageURL( rURL
) )
1301 if( !bLoadOnDemand
&& mxGraphicResolver
.is() )
1303 OUString
aTmp( msPackageProtocol
);
1305 sRet
= mxGraphicResolver
->resolveGraphicObjectURL( aTmp
);
1308 if( sRet
.isEmpty() )
1310 sRet
= msPackageProtocol
;
1315 if( sRet
.isEmpty() )
1316 sRet
= GetAbsoluteReference( rURL
);
1321 Reference
< XOutputStream
> SvXMLImport::GetStreamForGraphicObjectURLFromBase64()
1323 Reference
< XOutputStream
> xOStm
;
1324 Reference
< document::XBinaryStreamResolver
> xStmResolver( mxGraphicResolver
, UNO_QUERY
);
1326 if( xStmResolver
.is() )
1327 xOStm
= xStmResolver
->createOutputStream();
1332 OUString
SvXMLImport::ResolveGraphicObjectURLFromBase64(
1333 const Reference
< XOutputStream
>& rOut
)
1336 Reference
< document::XBinaryStreamResolver
> xStmResolver( mxGraphicResolver
, UNO_QUERY
);
1337 if( xStmResolver
.is() )
1338 sURL
= xStmResolver
->resolveOutputStream( rOut
);
1343 OUString
SvXMLImport::ResolveEmbeddedObjectURL(
1344 const OUString
& rURL
,
1345 const OUString
& rClassId
)
1349 if( IsPackageURL( rURL
) )
1351 if ( mxEmbeddedResolver
.is() )
1353 OUString
sURL( rURL
);
1354 if( !rClassId
.isEmpty() )
1356 sURL
+= "!" + rClassId
;
1358 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( sURL
);
1362 sRet
= GetAbsoluteReference( rURL
);
1367 Reference
< embed::XStorage
> SvXMLImport::GetSourceStorage()
1369 return mpImpl
->mxSourceStorage
;
1372 Reference
< XOutputStream
>
1373 SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64()
1375 Reference
< XOutputStream
> xOLEStream
;
1377 if( mxEmbeddedResolver
.is() )
1379 Reference
< XNameAccess
> xNA( mxEmbeddedResolver
, UNO_QUERY
);
1382 OUString
aURL( "Obj12345678" );
1383 Any aAny
= xNA
->getByName( aURL
);
1384 aAny
>>= xOLEStream
;
1391 OUString
SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1395 if( mxEmbeddedResolver
.is() )
1397 OUString
aURL( "Obj12345678" );
1398 sRet
= mxEmbeddedResolver
->resolveEmbeddedObjectURL( aURL
);
1404 void SvXMLImport::AddStyleDisplayName( sal_uInt16 nFamily
,
1405 const OUString
& rName
,
1406 const OUString
& rDisplayName
)
1410 mpStyleMap
= new StyleMap
;
1411 mpStyleMap
->acquire();
1412 if( mxImportInfo
.is() )
1414 OUString
sPrivateData( "PrivateData" );
1415 Reference
< beans::XPropertySetInfo
> xPropertySetInfo
=
1416 mxImportInfo
->getPropertySetInfo();
1417 if( xPropertySetInfo
.is() &&
1418 xPropertySetInfo
->hasPropertyByName(sPrivateData
) )
1420 Reference
< XInterface
> xIfc(
1421 static_cast< XUnoTunnel
*>( mpStyleMap
) );
1422 mxImportInfo
->setPropertyValue( sPrivateData
, Any(xIfc
) );
1427 StyleMap::key_type
aKey( nFamily
, rName
);
1428 StyleMap::value_type
aValue( aKey
, rDisplayName
);
1429 ::std::pair
<StyleMap::iterator
,bool> aRes( mpStyleMap
->insert( aValue
) );
1430 SAL_WARN_IF( !aRes
.second
,
1432 "duplicate style name of family " << nFamily
<< ": \"" << rName
<< "\"");
1436 OUString
SvXMLImport::GetStyleDisplayName( sal_uInt16 nFamily
,
1437 const OUString
& rName
) const
1439 OUString
sName( rName
);
1440 if( mpStyleMap
&& !rName
.isEmpty() )
1442 StyleMap::key_type
aKey( nFamily
, rName
);
1443 StyleMap::const_iterator aIter
= mpStyleMap
->find( aKey
);
1444 if( aIter
!= mpStyleMap
->end() )
1445 sName
= (*aIter
).second
;
1450 void SvXMLImport::SetViewSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1454 void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence
<css::beans::PropertyValue
>&)
1458 void SvXMLImport::SetDocumentSpecificSettings(const OUString
& _rSettingsGroupName
, const uno::Sequence
<beans::PropertyValue
>& _rSettings
)
1460 (void)_rSettingsGroupName
;
1464 ProgressBarHelper
* SvXMLImport::GetProgressBarHelper()
1466 if (!mpProgressBarHelper
)
1468 mpProgressBarHelper
= new ProgressBarHelper(mxStatusIndicator
, false);
1470 if (mxImportInfo
.is())
1472 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= mxImportInfo
->getPropertySetInfo();
1473 if (xPropertySetInfo
.is())
1475 OUString
sProgressRange(XML_PROGRESSRANGE
);
1476 OUString
sProgressMax(XML_PROGRESSMAX
);
1477 OUString
sProgressCurrent(XML_PROGRESSCURRENT
);
1478 OUString
sRepeat(XML_PROGRESSREPEAT
);
1479 if (xPropertySetInfo
->hasPropertyByName(sProgressMax
) &&
1480 xPropertySetInfo
->hasPropertyByName(sProgressCurrent
) &&
1481 xPropertySetInfo
->hasPropertyByName(sProgressRange
))
1484 sal_Int32
nProgressMax(0);
1485 sal_Int32
nProgressCurrent(0);
1486 sal_Int32
nProgressRange(0);
1487 aAny
= mxImportInfo
->getPropertyValue(sProgressRange
);
1488 if (aAny
>>= nProgressRange
)
1489 mpProgressBarHelper
->SetRange(nProgressRange
);
1490 aAny
= mxImportInfo
->getPropertyValue(sProgressMax
);
1491 if (aAny
>>= nProgressMax
)
1492 mpProgressBarHelper
->SetReference(nProgressMax
);
1493 aAny
= mxImportInfo
->getPropertyValue(sProgressCurrent
);
1494 if (aAny
>>= nProgressCurrent
)
1495 mpProgressBarHelper
->SetValue(nProgressCurrent
);
1497 if (xPropertySetInfo
->hasPropertyByName(sRepeat
))
1499 uno::Any aAny
= mxImportInfo
->getPropertyValue(sRepeat
);
1500 if (aAny
.getValueType() == cppu::UnoType
<bool>::get())
1501 mpProgressBarHelper
->SetRepeat(::cppu::any2bool(aAny
));
1503 SAL_WARN( "xmloff.core", "why is it no boolean?" );
1509 return mpProgressBarHelper
;
1512 void SvXMLImport::AddNumberStyle(sal_Int32 nKey
, const OUString
& rName
)
1514 if (!mxNumberStyles
.is())
1515 mxNumberStyles
.set( comphelper::NameContainer_createInstance( ::cppu::UnoType
<sal_Int32
>::get()) );
1516 if (mxNumberStyles
.is())
1520 mxNumberStyles
->insertByName(rName
, Any(nKey
));
1522 catch ( uno::Exception
& )
1524 SAL_WARN( "xmloff.core", "Numberformat could not be inserted");
1525 DBG_UNHANDLED_EXCEPTION();
1529 SAL_WARN( "xmloff.core", "not possible to create NameContainer");
1530 DBG_UNHANDLED_EXCEPTION();
1534 XMLEventImportHelper
& SvXMLImport::GetEventImport()
1536 if (!mpEventImportHelper
)
1538 // construct event helper and register StarBasic handler and standard
1540 mpEventImportHelper
= new XMLEventImportHelper();
1541 const OUString
& sStarBasic(GetXMLToken(XML_STARBASIC
));
1542 mpEventImportHelper
->RegisterFactory(sStarBasic
,
1543 new XMLStarBasicContextFactory());
1544 const OUString
& sScript(GetXMLToken(XML_SCRIPT
));
1545 mpEventImportHelper
->RegisterFactory(sScript
,
1546 new XMLScriptContextFactory());
1547 mpEventImportHelper
->AddTranslationTable(aStandardEventTable
);
1549 // register StarBasic event handler with capitalized spelling
1550 OUString
sStarBasicCap( "StarBasic" );
1551 mpEventImportHelper
->RegisterFactory(sStarBasicCap
,
1552 new XMLStarBasicContextFactory());
1555 return *mpEventImportHelper
;
1558 void SvXMLImport::SetFontDecls( XMLFontStylesContext
*pFontDecls
)
1560 mxFontDecls
= pFontDecls
;
1563 void SvXMLImport::SetStyles( SvXMLStylesContext
*pStyles
)
1568 void SvXMLImport::SetAutoStyles( SvXMLStylesContext
*pAutoStyles
)
1570 if (pAutoStyles
&& mxNumberStyles
.is() && (mnImportFlags
& SvXMLImportFlags::CONTENT
) )
1572 uno::Reference
<xml::sax::XAttributeList
> xAttrList
;
1573 uno::Sequence
< OUString
> aNames
= mxNumberStyles
->getElementNames();
1574 sal_uInt32
nCount(aNames
.getLength());
1577 const OUString
* pNames
= aNames
.getConstArray();
1580 SvXMLStyleContext
* pContext
;
1583 for (sal_uInt32 i
= 0; i
< nCount
; i
++, pNames
++)
1585 aAny
= mxNumberStyles
->getByName(*pNames
);
1588 pContext
= new SvXMLNumFormatContext( *this, XML_NAMESPACE_NUMBER
,
1589 *pNames
, xAttrList
, nKey
, *pAutoStyles
);
1590 pAutoStyles
->AddStyle(*pContext
);
1596 mxAutoStyles
= pAutoStyles
;
1597 GetTextImport()->SetAutoStyles( pAutoStyles
);
1598 GetShapeImport()->SetAutoStylesContext( pAutoStyles
);
1599 GetChartImport()->SetAutoStylesContext( pAutoStyles
);
1600 GetFormImport()->setAutoStyleContext( pAutoStyles
);
1603 void SvXMLImport::SetMasterStyles( SvXMLStylesContext
*pMasterStyles
)
1605 mxMasterStyles
= pMasterStyles
;
1608 XMLFontStylesContext
*SvXMLImport::GetFontDecls()
1610 return static_cast<XMLFontStylesContext
*>(&mxFontDecls
);
1613 SvXMLStylesContext
*SvXMLImport::GetStyles()
1615 return static_cast<SvXMLStylesContext
*>(&mxStyles
);
1618 SvXMLStylesContext
*SvXMLImport::GetAutoStyles()
1620 return static_cast<SvXMLStylesContext
*>(&mxAutoStyles
);
1623 const XMLFontStylesContext
*SvXMLImport::GetFontDecls() const
1625 return static_cast<const XMLFontStylesContext
*>(&mxFontDecls
);
1628 const SvXMLStylesContext
*SvXMLImport::GetStyles() const
1630 return static_cast<const SvXMLStylesContext
*>(&mxStyles
);
1633 const SvXMLStylesContext
*SvXMLImport::GetAutoStyles() const
1635 return static_cast<const SvXMLStylesContext
*>(&mxAutoStyles
);
1638 OUString
SvXMLImport::GetAbsoluteReference(const OUString
& rValue
) const
1640 if( rValue
.isEmpty() || rValue
[0] == '#' )
1643 INetURLObject aAbsURL
;
1644 if( mpImpl
->aBaseURL
.GetNewAbsURL( rValue
, &aAbsURL
) )
1645 return aAbsURL
.GetMainURL( INetURLObject::DECODE_TO_IURI
);
1650 bool SvXMLImport::IsODFVersionConsistent( const OUString
& aODFVersion
)
1652 // the check returns sal_False only if the storage version could be retrieved
1653 bool bResult
= true;
1655 if ( !aODFVersion
.isEmpty() && aODFVersion
.compareTo( ODFVER_012_TEXT
) >= 0 )
1657 // check the consistency only for the ODF1.2 and later ( according to content.xml )
1658 // manifest.xml might have no version, it should be checked here and the correct version should be set
1661 uno::Reference
< document::XStorageBasedDocument
> xDoc( mxModel
, uno::UNO_QUERY_THROW
);
1662 uno::Reference
< embed::XStorage
> xStor
= xDoc
->getDocumentStorage();
1663 uno::Reference
< beans::XPropertySet
> xStorProps( xStor
, uno::UNO_QUERY_THROW
);
1665 // the check should be done only for OASIS format
1668 bool bRepairPackage
= false;
1671 xStorProps
->getPropertyValue( "RepairPackage" )
1673 } catch ( uno::Exception
& )
1676 // check only if not in Repair mode
1677 if ( !bRepairPackage
)
1679 OUString aStorVersion
;
1680 xStorProps
->getPropertyValue( "Version" )
1683 // if the storage version is set in manifest.xml, it must be the same as in content.xml
1684 // if not, set it explicitly to be used further ( it will work even for readonly storage )
1685 // This workaround is not nice, but I see no other way to handle it, since there are
1686 // ODF1.2 documents without version in manifest.xml
1687 if ( !aStorVersion
.isEmpty() )
1688 bResult
= aODFVersion
.equals( aStorVersion
);
1690 xStorProps
->setPropertyValue( "Version",
1691 uno::makeAny( aODFVersion
) );
1695 bool bInconsistent
= false;
1696 xStorProps
->getPropertyValue( "IsInconsistent" )
1698 bResult
= !bInconsistent
;
1703 catch( uno::Exception
& )
1710 void SvXMLImport::CreateNumberFormatsSupplier_()
1712 SAL_WARN_IF( mxNumberFormatsSupplier
.is(), "xmloff.core", "number formats supplier already exists!" );
1714 mxNumberFormatsSupplier
=
1715 uno::Reference
< util::XNumberFormatsSupplier
> (mxModel
, uno::UNO_QUERY
);
1718 void SvXMLImport::CreateDataStylesImport_()
1720 SAL_WARN_IF( mpNumImport
!= nullptr, "xmloff.core", "data styles import already exists!" );
1721 uno::Reference
<util::XNumberFormatsSupplier
> xNum
=
1722 GetNumberFormatsSupplier();
1724 mpNumImport
= new SvXMLNumFmtHelper(xNum
, GetComponentContext() );
1727 sal_Unicode
SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c
)
1729 sal_Unicode cNew
= c
;
1730 if( !mpImpl
->hBatsFontConv
)
1732 OUString
sStarBats( "StarBats" );
1733 mpImpl
->hBatsFontConv
= CreateFontToSubsFontConverter( sStarBats
,
1734 FontToSubsFontFlags::IMPORT
|FontToSubsFontFlags::ONLYOLDSOSYMBOLFONTS
);
1735 SAL_WARN_IF( !mpImpl
->hBatsFontConv
, "xmloff.core", "Got no symbol font converter" );
1737 if( mpImpl
->hBatsFontConv
)
1739 cNew
= ConvertFontToSubsFontChar( mpImpl
->hBatsFontConv
, c
);
1745 sal_Unicode
SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c
)
1747 sal_Unicode cNew
= c
;
1748 if( !mpImpl
->hMathFontConv
)
1750 OUString
sStarMath( "StarMath" );
1751 mpImpl
->hMathFontConv
= CreateFontToSubsFontConverter( sStarMath
,
1752 FontToSubsFontFlags::IMPORT
|FontToSubsFontFlags::ONLYOLDSOSYMBOLFONTS
);
1753 SAL_WARN_IF( !mpImpl
->hMathFontConv
, "xmloff.core", "Got no symbol font converter" );
1755 if( mpImpl
->hMathFontConv
)
1757 cNew
= ConvertFontToSubsFontChar( mpImpl
->hMathFontConv
, c
);
1763 void SvXMLImport::SetError(
1765 const Sequence
<OUString
>& rMsgParams
,
1766 const OUString
& rExceptionMessage
,
1767 const Reference
<xml::sax::XLocator
>& rLocator
)
1769 // maintain error flags
1770 if ( ( nId
& XMLERROR_FLAG_ERROR
) != 0 )
1771 mnErrorFlags
|= SvXMLErrorFlags::ERROR_OCCURRED
;
1772 if ( ( nId
& XMLERROR_FLAG_WARNING
) != 0 )
1773 mnErrorFlags
|= SvXMLErrorFlags::WARNING_OCCURRED
;
1774 if ( ( nId
& XMLERROR_FLAG_SEVERE
) != 0 )
1775 mnErrorFlags
|= SvXMLErrorFlags::DO_NOTHING
;
1777 // create error list on demand
1778 if ( mpXMLErrors
== nullptr )
1779 mpXMLErrors
= new XMLErrors();
1781 // save error information
1782 // use document locator (if none supplied)
1783 mpXMLErrors
->AddRecord( nId
, rMsgParams
, rExceptionMessage
,
1784 rLocator
.is() ? rLocator
: mxLocator
);
1787 void SvXMLImport::SetError(
1789 const Sequence
<OUString
>& rMsgParams
)
1791 SetError( nId
, rMsgParams
, "", nullptr );
1794 void SvXMLImport::SetError(
1797 Sequence
<OUString
> aSeq(0);
1798 SetError( nId
, aSeq
);
1801 void SvXMLImport::SetError(
1803 const OUString
& rMsg1
)
1805 Sequence
<OUString
> aSeq
{ rMsg1
};
1806 SetError( nId
, aSeq
);
1809 void SvXMLImport::SetError(
1811 const OUString
& rMsg1
,
1812 const OUString
& rMsg2
)
1814 Sequence
<OUString
> aSeq(2);
1815 OUString
* pSeq
= aSeq
.getArray();
1818 SetError( nId
, aSeq
);
1821 void SvXMLImport::DisposingModel()
1823 if( mxFontDecls
.Is() )
1824 static_cast<SvXMLStylesContext
*>(&mxFontDecls
)->Clear();
1826 static_cast<SvXMLStylesContext
*>(&mxStyles
)->Clear();
1827 if( mxAutoStyles
.Is() )
1828 static_cast<SvXMLStylesContext
*>(&mxAutoStyles
)->Clear();
1829 if( mxMasterStyles
.Is() )
1830 static_cast<SvXMLStylesContext
*>(&mxMasterStyles
)->Clear();
1832 mxModel
.set(nullptr);
1833 mxEventListener
.set(nullptr);
1836 ::comphelper::UnoInterfaceToUniqueIdentifierMapper
& SvXMLImport::getInterfaceToIdentifierMapper()
1838 return mpImpl
->maInterfaceToIdentifierMapper
;
1841 uno::Reference
< uno::XComponentContext
>
1842 SvXMLImport::GetComponentContext() const
1844 return mpImpl
->mxComponentContext
;
1847 OUString
SvXMLImport::GetBaseURL() const
1849 return mpImpl
->aBaseURL
.GetMainURL( INetURLObject::NO_DECODE
);
1852 OUString
SvXMLImport::GetDocumentBase() const
1854 return mpImpl
->aDocBase
.GetMainURL( INetURLObject::NO_DECODE
);
1857 OUString
SvXMLImport::GetStreamName() const
1859 return mpImpl
->mStreamName
;
1862 // Convert drawing object positions from OOo file format to OASIS (#i28749#)
1863 bool SvXMLImport::IsShapePositionInHoriL2R() const
1865 return mpImpl
->mbShapePositionInHoriL2R
;
1868 bool SvXMLImport::IsTextDocInOOoFileFormat() const
1870 return mpImpl
->mbTextDocInOOoFileFormat
;
1873 void SvXMLImport::initXForms()
1875 // dummy method; to be implemented by derived classes supporting XForms
1878 bool SvXMLImport::getBuildIds( sal_Int32
& rUPD
, sal_Int32
& rBuild
) const
1881 OUString
const aBuildId(getBuildIdsProperty(mxImportInfo
));
1882 if (!aBuildId
.isEmpty())
1884 sal_Int32 nIndex
= aBuildId
.indexOf('$');
1887 rUPD
= aBuildId
.copy( 0, nIndex
).toInt32();
1888 sal_Int32 nIndexEnd
= aBuildId
.indexOf(';', nIndex
);
1889 rBuild
= (nIndexEnd
== -1)
1890 ? aBuildId
.copy(nIndex
+ 1).toInt32()
1891 : aBuildId
.copy(nIndex
+ 1, nIndexEnd
- nIndex
- 1).toInt32();
1898 sal_uInt16
SvXMLImport::getGeneratorVersion() const
1901 return mpImpl
->getGeneratorVersion( *this );
1905 bool SvXMLImport::isGeneratorVersionOlderThan(
1906 sal_uInt16
const nOOoVersion
, sal_uInt16
const nLOVersion
)
1908 assert( (nLOVersion
& LO_flag
));
1909 assert(!(nOOoVersion
& LO_flag
));
1910 const sal_uInt16
nGeneratorVersion(getGeneratorVersion());
1911 return (nGeneratorVersion
& LO_flag
)
1912 ? nGeneratorVersion
< nLOVersion
1913 : nGeneratorVersion
< nOOoVersion
;
1917 OUString
SvXMLImport::GetODFVersion() const
1919 return mpImpl
->aODFVersion
;
1922 bool SvXMLImport::IsOOoXML() const
1924 return mpImpl
->mbIsOOoXML
;
1927 // xml:id for RDF metadata
1928 void SvXMLImport::SetXmlId(uno::Reference
<uno::XInterface
> const & i_xIfc
,
1929 OUString
const & i_rXmlId
)
1931 if (!i_rXmlId
.isEmpty()) {
1933 const uno::Reference
<rdf::XMetadatable
> xMeta(i_xIfc
,
1937 const beans::StringPair
mdref( GetStreamName(), i_rXmlId
);
1939 xMeta
->setMetadataReference(mdref
);
1940 } catch (lang::IllegalArgumentException
&) {
1941 // probably duplicate; ignore
1942 SAL_INFO("xmloff.core", "SvXMLImport::SetXmlId: cannot set xml:id");
1945 } catch (uno::Exception
&) {
1946 SAL_WARN("xmloff.core","SvXMLImport::SetXmlId: exception?");
1951 ::xmloff::RDFaImportHelper
&
1952 SvXMLImport::GetRDFaImportHelper()
1954 if (!mpImpl
->mpRDFaHelper
.get())
1956 mpImpl
->mpRDFaHelper
.reset( new ::xmloff::RDFaImportHelper(*this) );
1958 return *mpImpl
->mpRDFaHelper
;
1962 SvXMLImport::AddRDFa(const uno::Reference
<rdf::XMetadatable
>& i_xObject
,
1963 OUString
const & i_rAbout
,
1964 OUString
const & i_rProperty
,
1965 OUString
const & i_rContent
,
1966 OUString
const & i_rDatatype
)
1968 // N.B.: we only get called if i_xObject had xhtml:about attribute
1969 // (an empty attribute value is valid)
1970 ::xmloff::RDFaImportHelper
& rRDFaHelper( GetRDFaImportHelper() );
1971 rRDFaHelper
.ParseAndAddRDFa(i_xObject
,
1972 i_rAbout
, i_rProperty
, i_rContent
, i_rDatatype
);
1975 bool SvXMLImport::embeddedFontAlreadyProcessed( const OUString
& url
)
1977 if( embeddedFontUrlsKnown
.count( url
) != 0 )
1979 embeddedFontUrlsKnown
.insert( url
);
1983 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */