Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / xmloff / source / core / xmlimp.cxx
blob3b702cd7afd9c0dde3dd5ba51da29312eb5fcb22
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <string.h>
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 >
110 private:
111 SvXMLImport* pImport;
113 public:
114 explicit SvXMLImportEventListener(SvXMLImport* pImport);
115 virtual ~SvXMLImportEventListener();
117 // XEventListener
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()
130 // XEventListener
131 void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& )
132 throw(uno::RuntimeException, std::exception)
134 if (pImport)
136 pImport->DisposingModel();
137 pImport = nullptr;
141 namespace
144 OUString
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"))
155 OUString aBuildId;
156 xImportInfo->getPropertyValue("BuildId") >>= aBuildId;
157 return aBuildId;
160 catch (Exception const&)
162 SAL_WARN("xmloff.core", "exception getting BuildId");
163 DBG_UNHANDLED_EXCEPTION();
166 return OUString();
169 class DocumentInfo
171 private:
172 sal_uInt16 mnGeneratorVersion;
174 public:
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(';');
183 if (-1 != ix)
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
212 else
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;
265 ~DocumentInfo()
268 sal_uInt16 getGeneratorVersion() const
270 return mnGeneratorVersion;
276 class SvXMLImport_Impl
278 public:
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;
292 bool mbIsOOoXML;
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 )
315 , mbIsOOoXML(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();
328 ~SvXMLImport_Impl()
330 if( hBatsFontConv )
331 DestroyFontToSubsFontConverter( hBatsFontConv );
332 if( hMathFontConv )
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 ),
433 mpStyleMap(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" );
441 InitCtor_();
444 SvXMLImport::~SvXMLImport() throw ()
446 delete mpXMLErrors;
447 delete mpNamespaceMap;
448 delete mpUnitConv;
449 delete mpEventImportHelper;
450 delete mpFastContexts;
451 if( mpContexts )
453 while( !mpContexts->empty() )
455 SvXMLImportContext *pContext = mpContexts->back();
456 mpContexts->pop_back();
457 if( pContext )
458 pContext->ReleaseRef();
460 delete mpContexts;
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.
468 delete mpNumImport;
469 delete mpProgressBarHelper;
471 if (mxEventListener.is() && mxModel.is())
472 mxModel->removeEventListener(mxEventListener);
475 namespace
477 class theSvXMLImportUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSvXMLImportUnoTunnelId> {};
480 // XUnoTunnel & co
481 const uno::Sequence< sal_Int8 > & SvXMLImport::getUnoTunnelId() throw()
483 return theSvXMLImportUnoTunnelId::get().getSeq();
486 // XUnoTunnel
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));
495 return 0;
498 void SAL_CALL SvXMLImport::startDocument()
499 throw (xml::sax::SAXException,
500 uno::RuntimeException,
501 std::exception)
503 SAL_INFO( "xmloff.core", "{ SvXMLImport::startDocument" );
504 if( !mxGraphicResolver.is() || !mxEmbeddedResolver.is() )
506 Reference< lang::XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
507 if( xFactory.is() )
511 if( !mxGraphicResolver.is() )
513 // #99870# Import... instead of Export...
514 mxGraphicResolver.set(
515 xFactory->createInstance("com.sun.star.document.ImportGraphicObjectResolver"),
516 UNO_QUERY);
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"),
525 UNO_QUERY);
526 mpImpl->mbOwnEmbeddedResolver = mxEmbeddedResolver.is();
529 catch( css::uno::Exception& )
536 void SAL_CALL SvXMLImport::endDocument()
537 throw(xml::sax::SAXException,
538 uno::RuntimeException,
539 std::exception)
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,
550 uno::UNO_QUERY);
551 if (xRS.is())
553 mpImpl->mpRDFaHelper->InsertRDFa( xRS );
557 if (mpNumImport)
559 delete mpNumImport;
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();
594 if( mxStyles.Is() )
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 );
613 xComp->dispose();
616 if( mpImpl->mbOwnEmbeddedResolver )
618 Reference< lang::XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
619 xComp->dispose();
621 if( mpStyleMap )
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 >(),
654 uno::makeAny(
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] ) )
662 if( !pRewindMap )
664 pRewindMap = mpNamespaceMap;
665 mpNamespaceMap = new SvXMLNamespaceMap( *mpNamespaceMap );
667 const OUString& rAttrValue = xAttrList->getValueByIndex( i );
669 OUString aPrefix( ( rAttrName.getLength() == 5 )
670 ? OUString()
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
675 // TC Id an version
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.
690 OUString aLocalName;
691 sal_uInt16 nPrefix =
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();
698 if( nCount > 0 )
700 pContext = (*mpContexts)[nCount - 1]->CreateChildContext( nPrefix,
701 aLocalName,
702 xAttrList );
703 SAL_WARN_IF( !pContext || (pContext->GetPrefix() != nPrefix), "xmloff.core",
704 "SvXMLImport::startElement: created context has wrong prefix" );
706 else
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" );
722 if( !pContext )
723 pContext = new SvXMLImportContext( *this, nPrefix, aLocalName );
725 pContext->AddFirstRef();
727 // Remember old namespace map.
728 if( pRewindMap )
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&
739 #ifdef DBG_UTIL
740 rName
741 #endif
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" );
747 if( nCount > 0 )
749 // Get topmost context and remove it from the stack.
750 SvXMLImportContext *pContext = mpContexts->back();
751 mpContexts->pop_back();
753 #ifdef DBG_UTIL
754 // Non product only: check if endElement call matches startELement call.
755 OUString aLocalName;
756 sal_uInt16 nPrefix =
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" );
760 #endif
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();
770 pContext = nullptr;
772 // Rewind a namespace map.
773 if( pRewindMap )
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&,
800 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();
819 if( nCount > 0 )
821 uno::Reference< XFastContextHandler > pHandler = (*mpFastContexts)[nCount - 1];
822 xContext = pHandler->createFastChildContext( Element, Attribs );
824 else
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();
847 if( nCount > 0 )
849 uno::Reference< XFastContextHandler > xContext = mpFastContexts->back();
850 mpFastContexts->pop_back();
851 xContext->endFastElement( Element );
852 xContext = nullptr;
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)
866 return this;
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)
874 return this;
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);
907 // XImporter
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 );
912 if( !mxModel.is() )
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());
921 if (xStor.is())
923 mpImpl->mbIsOOoXML =
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." );
940 if( mpNumImport )
942 delete mpNumImport;
943 mpNumImport = nullptr;
947 // XFilter
948 sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& )
949 throw (uno::RuntimeException, std::exception)
951 return false;
954 void SAL_CALL SvXMLImport::cancel( )
955 throw (uno::RuntimeException, std::exception)
959 // XInitialize
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;
969 *pAny >>= xValue;
971 uno::Reference<task::XStatusIndicator> xTmpStatusIndicator(
972 xValue, UNO_QUERY );
973 if( xTmpStatusIndicator.is() )
974 mxStatusIndicator = xTmpStatusIndicator;
976 uno::Reference<document::XGraphicObjectResolver> xTmpGraphicResolver(
977 xValue, UNO_QUERY );
978 if( xTmpGraphicResolver.is() )
979 mxGraphicResolver = xTmpGraphicResolver;
981 uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
982 xValue, UNO_QUERY );
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);
1005 aAny >>= xIfc;
1007 StyleMap *pSMap = StyleMap::getImplementation( xIfc );
1008 if( pSMap )
1010 mpStyleMap = pSMap;
1011 mpStyleMap->acquire();
1014 OUString sBaseURI;
1015 sPropName = "BaseURI";
1016 if (xPropertySetInfo->hasPropertyByName(sPropName))
1018 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1019 aAny >>= sBaseURI;
1020 mpImpl->aBaseURL.SetURL( sBaseURI );
1021 mpImpl->aDocBase.SetURL( sBaseURI );
1023 OUString sRelPath;
1024 sPropName = "StreamRelPath";
1025 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1027 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1028 aAny >>= sRelPath;
1030 OUString sName;
1031 sPropName = "StreamName";
1032 if( xPropertySetInfo->hasPropertyByName(sPropName) )
1034 uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
1035 aAny >>= sName;
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;
1066 // XServiceInfo
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";
1085 return aSeq;
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() )
1116 if( mxModel.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() )
1139 if( mxModel.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() )
1162 if( mxModel.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() )
1185 if( mxModel.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() )
1208 if( mxModel.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() )
1230 if( mxModel.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 )
1254 return false;
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
1260 return false;
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
1266 return false;
1267 else if( '/' == rURL[1] )
1268 // we are remaining on a level, so it's an package URI
1269 return true;
1272 // Now check for a RFC2396 schema
1273 sal_Int32 nPos = 1;
1274 while( nPos < nLen )
1276 switch( rURL[nPos] )
1278 case '/':
1279 // a relative path segement
1280 return true;
1281 case ':':
1282 // a schema
1283 return false;
1284 default:
1285 break;
1286 // we don't care about any other characters
1288 ++nPos;
1291 return true;
1294 OUString SvXMLImport::ResolveGraphicObjectURL( const OUString& rURL,
1295 bool bLoadOnDemand )
1297 OUString sRet;
1299 if( IsPackageURL( rURL ) )
1301 if( !bLoadOnDemand && mxGraphicResolver.is() )
1303 OUString aTmp( msPackageProtocol );
1304 aTmp += rURL;
1305 sRet = mxGraphicResolver->resolveGraphicObjectURL( aTmp );
1308 if( sRet.isEmpty() )
1310 sRet = msPackageProtocol;
1311 sRet += rURL;
1315 if( sRet.isEmpty() )
1316 sRet = GetAbsoluteReference( rURL );
1318 return sRet;
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();
1329 return xOStm;
1332 OUString SvXMLImport::ResolveGraphicObjectURLFromBase64(
1333 const Reference < XOutputStream >& rOut )
1335 OUString sURL;
1336 Reference< document::XBinaryStreamResolver > xStmResolver( mxGraphicResolver, UNO_QUERY );
1337 if( xStmResolver.is() )
1338 sURL = xStmResolver->resolveOutputStream( rOut );
1340 return sURL;
1343 OUString SvXMLImport::ResolveEmbeddedObjectURL(
1344 const OUString& rURL,
1345 const OUString& rClassId )
1347 OUString sRet;
1349 if( IsPackageURL( rURL ) )
1351 if ( mxEmbeddedResolver.is() )
1353 OUString sURL( rURL );
1354 if( !rClassId.isEmpty() )
1356 sURL += "!" + rClassId;
1358 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( sURL );
1361 else
1362 sRet = GetAbsoluteReference( rURL );
1364 return sRet;
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 );
1380 if( xNA.is() )
1382 OUString aURL( "Obj12345678" );
1383 Any aAny = xNA->getByName( aURL );
1384 aAny >>= xOLEStream;
1388 return xOLEStream;
1391 OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
1393 OUString sRet;
1395 if( mxEmbeddedResolver.is() )
1397 OUString aURL( "Obj12345678" );
1398 sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( aURL );
1401 return sRet;
1404 void SvXMLImport::AddStyleDisplayName( sal_uInt16 nFamily,
1405 const OUString& rName,
1406 const OUString& rDisplayName )
1408 if( !mpStyleMap )
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,
1431 "xmloff.core",
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;
1447 return sName;
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;
1461 (void)_rSettings;
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))
1483 uno::Any aAny;
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));
1502 else {
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();
1528 else {
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
1539 // event tables
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 )
1565 mxStyles = 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());
1575 if (nCount)
1577 const OUString* pNames = aNames.getConstArray();
1578 if ( pNames )
1580 SvXMLStyleContext* pContext;
1581 uno::Any aAny;
1582 sal_Int32 nKey(0);
1583 for (sal_uInt32 i = 0; i < nCount; i++, pNames++)
1585 aAny = mxNumberStyles->getByName(*pNames);
1586 if (aAny >>= nKey)
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] == '#' )
1641 return rValue;
1643 INetURLObject aAbsURL;
1644 if( mpImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) )
1645 return aAbsURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
1646 else
1647 return rValue;
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
1666 if (!IsOOoXML())
1668 bool bRepairPackage = false;
1671 xStorProps->getPropertyValue( "RepairPackage" )
1672 >>= bRepairPackage;
1673 } catch ( uno::Exception& )
1676 // check only if not in Repair mode
1677 if ( !bRepairPackage )
1679 OUString aStorVersion;
1680 xStorProps->getPropertyValue( "Version" )
1681 >>= aStorVersion;
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 );
1689 else
1690 xStorProps->setPropertyValue( "Version",
1691 uno::makeAny( aODFVersion ) );
1693 if ( bResult )
1695 bool bInconsistent = false;
1696 xStorProps->getPropertyValue( "IsInconsistent" )
1697 >>= bInconsistent;
1698 bResult = !bInconsistent;
1703 catch( uno::Exception& )
1707 return bResult;
1710 void SvXMLImport::CreateNumberFormatsSupplier_()
1712 SAL_WARN_IF( mxNumberFormatsSupplier.is(), "xmloff.core", "number formats supplier already exists!" );
1713 if(mxModel.is())
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();
1723 if ( xNum.is() )
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 );
1742 return cNew;
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 );
1760 return cNew;
1763 void SvXMLImport::SetError(
1764 sal_Int32 nId,
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(
1788 sal_Int32 nId,
1789 const Sequence<OUString>& rMsgParams)
1791 SetError( nId, rMsgParams, "", nullptr );
1794 void SvXMLImport::SetError(
1795 sal_Int32 nId)
1797 Sequence<OUString> aSeq(0);
1798 SetError( nId, aSeq );
1801 void SvXMLImport::SetError(
1802 sal_Int32 nId,
1803 const OUString& rMsg1)
1805 Sequence<OUString> aSeq { rMsg1 };
1806 SetError( nId, aSeq );
1809 void SvXMLImport::SetError(
1810 sal_Int32 nId,
1811 const OUString& rMsg1,
1812 const OUString& rMsg2)
1814 Sequence<OUString> aSeq(2);
1815 OUString* pSeq = aSeq.getArray();
1816 pSeq[0] = rMsg1;
1817 pSeq[1] = rMsg2;
1818 SetError( nId, aSeq );
1821 void SvXMLImport::DisposingModel()
1823 if( mxFontDecls.Is() )
1824 static_cast<SvXMLStylesContext *>(&mxFontDecls)->Clear();
1825 if( mxStyles.Is() )
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
1880 bool bRet = false;
1881 OUString const aBuildId(getBuildIdsProperty(mxImportInfo));
1882 if (!aBuildId.isEmpty())
1884 sal_Int32 nIndex = aBuildId.indexOf('$');
1885 if (nIndex != -1)
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();
1892 bRet = true;
1895 return bRet;
1898 sal_uInt16 SvXMLImport::getGeneratorVersion() const
1900 // --> ORW
1901 return mpImpl->getGeneratorVersion( *this );
1902 // <--
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()) {
1932 try {
1933 const uno::Reference<rdf::XMetadatable> xMeta(i_xIfc,
1934 uno::UNO_QUERY);
1935 //FIXME: not yet
1936 if (xMeta.is()) {
1937 const beans::StringPair mdref( GetStreamName(), i_rXmlId );
1938 try {
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;
1961 void
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 )
1978 return true;
1979 embeddedFontUrlsKnown.insert( url );
1980 return false;
1983 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */