Quelle xmlimp.cxx
Sprache: C
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <config_wasm_strip.h>
#include <memory>
#include <optional>
#include <comphelper/diagnose_ex.hxx>
#include <sal/log.hxx>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <tools/urlobj.hxx>
#include <utility>
#include <vcl/embeddedfontshelper.hxx>
#include <vcl/graph.hxx>
#include <xmloff/unointerfacetouniqueidentifiermapper.hxx>
#include <xmloff/namespacemap.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlnamespace.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/XMLFontStylesContext.hxx>
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmlnumfi.hxx>
#include <XMLEventImportHelper.hxx>
#include <XMLStarBasicContextFactory.hxx>
#include <XMLScriptContextFactory.hxx>
#include <StyleMap.hxx>
#include <xmloff/ProgressBarHelper.hxx>
#include <xmloff/xmlerror.hxx>
#include <com/sun/star/container/XNameContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/ServiceNotRegisteredException.hpp>
#include <com/sun/star/io/XOutputStream.hpp>
#include <com/sun/star/util/MeasureUnit.hpp>
#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/document/XBinaryStreamResolver.hpp>
#include <com/sun/star/document/XStorageBasedDocument.hpp>
#include <com/sun/star/document/XGraphicStorageHandler.hpp>
#include <com/sun/star/document/XEmbeddedObjectResolver.hpp>
#include <com/sun/star/xml/sax/XLocator.hpp>
#include <com/sun/star/xml/sax/FastParser.hpp>
#include <com/sun/star/xml/sax/SAXException.hpp>
#include <com/sun/star/packages/zip/ZipIOException.hpp>
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <comphelper/fileformat.h>
#include <comphelper/namecontainer.hxx>
#include <cppuhelper/implbase.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <comphelper/extract.hxx>
#include <comphelper/documentconstants.hxx>
#include <comphelper/documentinfo.hxx>
#include <comphelper/storagehelper.hxx>
#include <comphelper/attributelist.hxx>
#include <unotools/fontcvt.hxx>
#include <fasttokenhandler.hxx>
#include <vcl/GraphicExternalLink.hxx>
#include <o3tl/string_view.hxx>
#include <com/sun/star/rdf/XMetadatable.hpp>
#include <com/sun/star/rdf/XRepositorySupplier.hpp>
#include <RDFaImportHelper.hxx>
using ::com::sun::star::beans::XPropertySetInfo;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::document;
using namespace ::xmloff::token;
rtl::Reference<FastTokenHandler> SvXMLImport::xTokenHandler(
new FastTokenHandler);
std::unordered_map< sal_Int32, std::pair< OUString, OUString > > SvXMLImport::aNamespaceMap
;
std::unordered_map< OUString, OUString > SvXMLImport::aNamespaceURIPrefixMap;
bool SvXMLImport::bIsNSMapsInitialized = false ;
namespace {
class SvXMLImportEventListener : public cppu::WeakImplHelper< css::lang::XEventListener >
{
private :
SvXMLImport* pImport;
public :
explicit SvXMLImportEventListener(SvXMLImport* pImport);
// XEventListener
virtual void SAL_CALL disposing(const lang::EventObject& rEventObject) override;
};
}
SvXMLImportEventListener::SvXMLImportEventListener(SvXMLImport* pTempImport)
: pImport(pTempImport)
{
}
// XEventListener
void SAL_CALL SvXMLImportEventListener::disposing( const lang::EventObject& )
{
if (pImport)
{
pImport->DisposingModel();
pImport = nullptr;
}
}
namespace
{
OUString
getBuildIdsProperty(uno::Reference<beans::XPropertySet> const & xImportInfo)
{
if (xImportInfo.is())
{
try
{
Reference< XPropertySetInfo > const xSetInfo(
xImportInfo->getPropertySetInfo());
if (xSetInfo.is() && xSetInfo->hasPropertyByName(u"BuildId" _ustr))
{
OUString aBuildId;
xImportInfo->getPropertyValue(u"BuildId" _ustr) >>= aBuildId;
return aBuildId;
}
}
catch (Exception const &)
{
DBG_UNHANDLED_EXCEPTION("xmloff.core" , "exception getting BuildId" );
}
}
return OUString();
}
class DocumentInfo
{
private :
sal_uInt16 mnGeneratorVersion;
public :
explicit DocumentInfo( const SvXMLImport& rImport )
: mnGeneratorVersion( SvXMLImport::ProductVersionUnknown )
{
OUString const buildIds(
getBuildIdsProperty(rImport.getImportInfo()));
if (!buildIds.isEmpty())
{
sal_Int32 const ix = buildIds.indexOf(';' );
if (-1 != ix)
{
OUString const loVersion(buildIds.copy(ix + 1));
if (!loVersion.isEmpty())
{
auto const firstDot(loVersion.indexOf('.' ));
if (firstDot == 1)
{ // old version scheme 3.3 ... 7.6
if ('3' == loVersion[0])
{
mnGeneratorVersion = SvXMLImport::LO_3x;
}
else if ('4' == loVersion[0])
{
if (loVersion.getLength() > 2
&& (loVersion[2] == '0' || loVersion[2] == '1' ))
{
mnGeneratorVersion = SvXMLImport::LO_41x; // 4.0/4.1
}
else if (loVersion.getLength() > 2 && '2' == loVersion[2])
{
mnGeneratorVersion = SvXMLImport::LO_42x; // 4.2
}
else if (loVersion.getLength() > 2 && '3' == loVersion[2])
{
mnGeneratorVersion = SvXMLImport::LO_43x; // 4.3
}
else if (loVersion.getLength() > 2 && '4' == loVersion[2])
{
mnGeneratorVersion = SvXMLImport::LO_44x; // 4.4
}
}
else if ('5' == loVersion[0])
{
mnGeneratorVersion = SvXMLImport::LO_5x;
}
else if ('6' == loVersion[0])
{
if (loVersion.getLength() > 2
&& (loVersion[2] == '0' || loVersion[2] == '1'
|| loVersion[2] == '2' ))
{
mnGeneratorVersion = SvXMLImport::LO_6x; // 6.0/6.1/6.2
}
else
{
mnGeneratorVersion = SvXMLImport::LO_63x; // 6.3/6.4
}
}
else if ('7' == loVersion[0])
{
if (loVersion.getLength() > 2 && loVersion[2] == '6' )
{
mnGeneratorVersion = SvXMLImport::LO_76; // 7.6
}
else
{
mnGeneratorVersion = SvXMLImport::LO_7x;
}
}
else
{
SAL_INFO("xmloff.core" , "unknown LO version: " << loVersion);
}
}
else if (1 < firstDot) // new version scheme 24.2 ...
{
OUString const nMajor(loVersion.subView(0, firstDot));
auto const year(nMajor.toInt32());
auto const month(o3tl::toInt32(loVersion.subView(firstDot+1)));
if (24 == year && month == 2)
{
mnGeneratorVersion = SvXMLImport::LO_242;
}
else if (24 == year && month == 8)
{
mnGeneratorVersion = SvXMLImport::LO_248;
}
else if (0 < year)
{
mnGeneratorVersion = SvXMLImport::LO_New;
}
else
{
SAL_INFO("xmloff.core" , "unknown LO version: " << loVersion);
}
}
else
{
SAL_INFO("xmloff.core" , "unknown LO version: " << loVersion);
}
return ; // ignore buildIds
}
}
}
sal_Int32 nUPD, nBuild;
if ( !rImport.getBuildIds( nUPD, nBuild ) )
return ;
if ( nUPD >= 640 && nUPD <= 645 )
{
mnGeneratorVersion = SvXMLImport::OOo_1x;
}
else if ( nUPD == 680 )
{
mnGeneratorVersion = SvXMLImport::OOo_2x;
}
else if ( nUPD == 300 && nBuild <= 9379 )
{
mnGeneratorVersion = SvXMLImport::OOo_30x;
}
else if ( nUPD == 310 )
{
mnGeneratorVersion = SvXMLImport::OOo_31x;
}
else if ( nUPD == 320 )
{
mnGeneratorVersion = SvXMLImport::OOo_32x;
}
else if ( nUPD == 330 )
{
mnGeneratorVersion = SvXMLImport::OOo_33x;
}
else if ( nUPD == 340 )
{
mnGeneratorVersion = SvXMLImport::OOo_34x;
}
else if (nUPD == 400 || nUPD == 401)
{
mnGeneratorVersion = SvXMLImport::AOO_40x;
}
else if (nUPD >= 410)
{
// effectively this means "latest", see use
// in XMLGraphicsDefaultStyle::SetDefaults()!
mnGeneratorVersion = SvXMLImport::AOO_4x;
}
}
sal_uInt16 getGeneratorVersion() const
{
return mnGeneratorVersion;
}
};
}
class SvXMLImport_Impl
{
public :
FontToSubsFontConverter hBatsFontConv;
FontToSubsFontConverter hMathFontConv;
bool mbOwnGraphicResolver;
bool mbOwnEmbeddedResolver;
INetURLObject aBaseURL;
INetURLObject aDocBase;
/// name of stream in package, e.g., "content.xml"
OUString mStreamName;
std::optional<OUString> mxODFVersion;
bool mbIsOOoXML;
std::optional<bool > mbIsMSO;
// Boolean, indicating that position attributes
// of shapes are given in horizontal left-to-right layout. This is the case
// for the OpenOffice.org file format. (#i28749#)
bool mbShapePositionInHoriL2R;
bool mbTextDocInOOoFileFormat;
const uno::Reference< uno::XComponentContext > mxComponentContext;
OUString implementationName;
css::uno::Sequence< OUString > maSupportedServiceNames;
uno::Reference< embed::XStorage > mxSourceStorage;
std::unique_ptr< xmloff::RDFaImportHelper > mpRDFaHelper;
std::optional< DocumentInfo > moDocumentInfo;
SvXMLImport_Impl( uno::Reference< uno::XComponentContext > xContext,
OUString theImplementationName,
const css::uno::Sequence< OUString > & sSupportedServiceNames = {})
: hBatsFontConv( nullptr )
, hMathFontConv( nullptr )
, mbOwnGraphicResolver( false )
, mbOwnEmbeddedResolver( false )
, mbIsOOoXML(false )
// Convert drawing object positions from OOo file format to OASIS (#i28749#)
, mbShapePositionInHoriL2R( false )
, mbTextDocInOOoFileFormat( false )
, mxComponentContext(std::move( xContext ))
, implementationName(std::move(theImplementationName))
, maSupportedServiceNames(sSupportedServiceNames)
{
SAL_WARN_IF(!mxComponentContext.is(), "xmloff.core" , "SvXMLImport: no ComponentContext" );
if (!mxComponentContext.is()) throw uno::RuntimeException();
if (!maSupportedServiceNames.hasElements())
maSupportedServiceNames = { u"com.sun.star.document.ImportFilter" _ustr, u"com.sun.star.xml.XMLImportFilter" _ustr };
}
sal_uInt16 getGeneratorVersion( const SvXMLImport& rImport )
{
if (!moDocumentInfo)
{
moDocumentInfo.emplace( rImport );
}
return moDocumentInfo->getGeneratorVersion();
}
::comphelper::UnoInterfaceToUniqueIdentifierMapper maInterfaceToIdentifierMapper;
};
SvXMLImportContext *SvXMLImport::CreateFastContext( sal_Int32 nElement,
const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
{
assert(false );
SAL_WARN( "xmloff.core" , "CreateFastContext should be overridden, for element " << nElement);
return new SvXMLImportContext( *this );
}
void SvXMLImport::InitCtor_()
{
if ( mnImportFlags != SvXMLImportFlags::NONE )
{
// implicit "xml" namespace prefix
mxNamespaceMap->Add( GetXMLToken(XML_XML), GetXMLToken(XML_N_XML), XML_NAMESPACE_XML );
mxNamespaceMap->Add( u"_office" _ustr, GetXMLToken(XML_N_OFFICE), XML_NAMESPACE_OFFICE );
mxNamespaceMap->Add( u"_office_ooo" _ustr, GetXMLToken(XML_N_OFFICE_EXT), XML_NAMESPACE_OFFICE_EXT );
mxNamespaceMap->Add( u"_ooo" _ustr, GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
mxNamespaceMap->Add( u"_style" _ustr, GetXMLToken(XML_N_STYLE), XML_NAMESPACE_STYLE );
mxNamespaceMap->Add( u"_text" _ustr, GetXMLToken(XML_N_TEXT), XML_NAMESPACE_TEXT );
mxNamespaceMap->Add( u"_table" _ustr, GetXMLToken(XML_N_TABLE), XML_NAMESPACE_TABLE );
mxNamespaceMap->Add( u"_table_ooo" _ustr, GetXMLToken(XML_N_TABLE_EXT), XML_NAMESPACE_TABLE_EXT );
mxNamespaceMap->Add( u"_draw" _ustr, GetXMLToken(XML_N_DRAW), XML_NAMESPACE_DRAW );
mxNamespaceMap->Add( u"_draw_ooo" _ustr, GetXMLToken(XML_N_DRAW_EXT), XML_NAMESPACE_DRAW_EXT );
mxNamespaceMap->Add( u"_dr3d" _ustr, GetXMLToken(XML_N_DR3D), XML_NAMESPACE_DR3D );
mxNamespaceMap->Add( u"_fo" _ustr, GetXMLToken(XML_N_FO_COMPAT), XML_NAMESPACE_FO );
mxNamespaceMap->Add( u"_xlink" _ustr, GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
mxNamespaceMap->Add( u"_dc" _ustr, GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
mxNamespaceMap->Add( u"_dom" _ustr, GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
mxNamespaceMap->Add( u"_meta" _ustr, GetXMLToken(XML_N_META), XML_NAMESPACE_META );
mxNamespaceMap->Add( u"_number" _ustr, GetXMLToken(XML_N_NUMBER), XML_NAMESPACE_NUMBER );
mxNamespaceMap->Add( u"_svg" _ustr, GetXMLToken(XML_N_SVG_COMPAT), XML_NAMESPACE_SVG );
mxNamespaceMap->Add( u"_chart" _ustr, GetXMLToken(XML_N_CHART), XML_NAMESPACE_CHART );
mxNamespaceMap->Add( u"_math" _ustr, GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
mxNamespaceMap->Add( u"_form" _ustr, GetXMLToken(XML_N_FORM), XML_NAMESPACE_FORM );
mxNamespaceMap->Add( u"_script" _ustr, GetXMLToken(XML_N_SCRIPT), XML_NAMESPACE_SCRIPT );
mxNamespaceMap->Add( u"_config" _ustr, GetXMLToken(XML_N_CONFIG), XML_NAMESPACE_CONFIG );
mxNamespaceMap->Add( u"_xforms" _ustr, GetXMLToken(XML_N_XFORMS_1_0), XML_NAMESPACE_XFORMS );
mxNamespaceMap->Add( u"_formx" _ustr, GetXMLToken( XML_N_FORMX ), XML_NAMESPACE_FORMX );
mxNamespaceMap->Add( u"_xsd" _ustr, GetXMLToken(XML_N_XSD), XML_NAMESPACE_XSD );
mxNamespaceMap->Add( u"_xsi" _ustr, GetXMLToken(XML_N_XSI), XML_NAMESPACE_XFORMS );
mxNamespaceMap->Add( u"_ooow" _ustr, GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
mxNamespaceMap->Add( u"_oooc" _ustr, GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
mxNamespaceMap->Add( u"_field" _ustr, GetXMLToken(XML_N_FIELD), XML_NAMESPACE_FIELD );
mxNamespaceMap->Add( u"_of" _ustr, GetXMLToken(XML_N_OF), XML_NAMESPACE_OF );
mxNamespaceMap->Add( u"_xhtml" _ustr, GetXMLToken(XML_N_XHTML), XML_NAMESPACE_XHTML );
mxNamespaceMap->Add( u"_css3text" _ustr, GetXMLToken(XML_N_CSS3TEXT), XML_NAMESPACE_CSS3TEXT );
mxNamespaceMap->Add( u"_calc_libo" _ustr, GetXMLToken(XML_N_CALC_EXT), XML_NAMESPACE_CALC_EXT);
mxNamespaceMap->Add( u"_office_libo" _ustr,
GetXMLToken(XML_N_LO_EXT), XML_NAMESPACE_LO_EXT);
}
if (mxNumberFormatsSupplier.is())
mpNumImport = std::make_unique<SvXMLNumFmtHelper>(mxNumberFormatsSupplier);
if (mxModel.is() && !mxEventListener.is())
{
mxEventListener.set(new SvXMLImportEventListener(this ));
mxModel->addEventListener(mxEventListener);
}
}
SvXMLImport::SvXMLImport(
const css::uno::Reference< css::uno::XComponentContext >& xContext,
OUString const & implementationName,
SvXMLImportFlags nImportFlags,
const css::uno::Sequence< OUString > & sSupportedServiceNames )
: mpImpl( new SvXMLImport_Impl(xContext, implementationName, sSupportedServiceNames) ),
mxNamespaceMap( SvXMLNamespaceMap() ),
mpUnitConv( new SvXMLUnitConverter( xContext,
util::MeasureUnit::MM_100TH, util::MeasureUnit::MM_100TH,
SvtSaveOptions::ODFSVER_LATEST_EXTENDED) ),
mnImportFlags( nImportFlags ),
maNamespaceHandler( new SvXMLImportFastNamespaceHandler() ),
mbIsFormsSupported( true ),
mbIsTableShapeSupported( false ),
mbNotifyMacroEventRead( false )
{
SAL_WARN_IF( !xContext.is(), "xmloff.core" , "got no service manager" );
InitCtor_();
mxParser = xml::sax::FastParser::create( xContext );
setNamespaceHandler( maNamespaceHandler );
setTokenHandler( xTokenHandler );
if ( !bIsNSMapsInitialized )
{
initializeNamespaceMaps();
bIsNSMapsInitialized = true ;
}
registerNamespaces();
maNamespaceAttrList = new comphelper::AttributeList;
}
void SvXMLImport::cleanup() noexcept
{
if (mxEventListener.is() && mxModel.is())
mxModel->removeEventListener(mxEventListener);
// clear context stacks first in case of parse error because the context
// class dtors are full of application logic
while (!maContexts.empty())
{
if (SvXMLStylesContext* pStylesContext = dynamic_cast <SvXMLStylesContext*>(maContexts.top().get()))
pStylesContext->dispose();
maContexts.pop();
}
if ( mxTextImport )
mxTextImport->dispose();
mxTextImport.clear(); // XMLRedlineImportHelper needs model
DisposingModel();
}
SvXMLImport::~SvXMLImport() noexcept
{
cleanup();
}
bool SvXMLImport::addEmbeddedFont(const css::uno::Reference< css::io::XInputStream >& stream,
const OUString& fontName, std::u16string_view extra,
std::vector<unsigned char > const & key, bool eot)
{
if (!mxEmbeddedFontHelper)
mxEmbeddedFontHelper.reset(new EmbeddedFontsHelper);
return mxEmbeddedFontHelper->addEmbeddedFont(stream, fontName, extra, key, eot);
}
namespace
{
class setFastDocumentHandlerGuard
{
private :
css::uno::Reference<css::xml::sax::XFastParser> mxParser;
public :
setFastDocumentHandlerGuard(css::uno::Reference<css::xml::sax::XFastParser> Parser,
const css::uno::Reference<css::xml::sax::XFastDocumentHandler>& Handler)
: mxParser(std::move(Parser))
{
mxParser->setFastDocumentHandler(Handler);
}
//guarantee restoration of null document handler
~setFastDocumentHandlerGuard()
{
mxParser->setFastDocumentHandler(nullptr);
}
};
}
// XFastParser
void SAL_CALL SvXMLImport::parseStream( const xml::sax::InputSource& aInputSource )
{
setFastDocumentHandlerGuard aDocumentHandlerGuard(mxParser, mxFastDocumentHandler.is() ? mxFastDocumentHandler : this );
mxParser->parseStream(aInputSource);
}
void SAL_CALL SvXMLImport::setFastDocumentHandler( const uno::Reference< xml::sax::XFastDocumentHandler >& Handler )
{
mxFastDocumentHandler = Handler;
}
void SAL_CALL SvXMLImport::setTokenHandler( const uno::Reference< xml::sax::XFastTokenHandler >& Handler )
{
mxParser->setTokenHandler( Handler );
}
void SAL_CALL SvXMLImport::registerNamespace( const OUString& NamespaceURL, sal_Int32 NamespaceToken )
{
mxParser->registerNamespace( NamespaceURL, NamespaceToken );
}
OUString SAL_CALL SvXMLImport::getNamespaceURL( const OUString& rPrefix )
{
return mxParser->getNamespaceURL( rPrefix );
}
void SAL_CALL SvXMLImport::setErrorHandler( const uno::Reference< xml::sax::XErrorHandler >& Handler )
{
mxParser->setErrorHandler( Handler );
}
void SAL_CALL SvXMLImport::setEntityResolver( const uno::Reference< xml::sax::XEntityResolver >& Resolver )
{
mxParser->setEntityResolver( Resolver );
}
void SAL_CALL SvXMLImport::setLocale( const lang::Locale& rLocale )
{
mxParser->setLocale( rLocale );
}
void SAL_CALL SvXMLImport::setNamespaceHandler( const uno::Reference< xml::sax::XFastNamespaceHandler >& Handler)
{
mxParser->setNamespaceHandler( Handler );
}
void SAL_CALL SvXMLImport::setCustomEntityNames( const ::css::uno::Sequence< ::css::beans::Pair<::rtl::OUString, ::rtl::OUString> >& replacements )
{
mxParser->setCustomEntityNames( replacements );
}
void SAL_CALL SvXMLImport::startDocument()
{
SAL_INFO( "xmloff.core" , "{ SvXMLImport::startDocument" );
if (mxGraphicStorageHandler.is() && mxEmbeddedResolver.is())
return ;
Reference< lang::XMultiServiceFactory > xFactory( mxModel, UNO_QUERY );
if ( !xFactory.is() )
return ;
try
{
if (!mxGraphicStorageHandler.is())
{
// #99870# Import... instead of Export...
mxGraphicStorageHandler.set(
GetComponentContext()->getServiceManager()->createInstanceWithArgumentsAndContext(
u"com.sun.star.comp.Svx.GraphicImportHelper" _ustr, uno::Sequence<uno::Any>(), GetComponentContext()),
uno::UNO_QUERY );
mpImpl->mbOwnGraphicResolver = mxGraphicStorageHandler.is();
}
if ( !mxEmbeddedResolver.is() )
{
// #99870# Import... instead of Export...
mxEmbeddedResolver.set(
xFactory->createInstance(u"com.sun.star.document.ImportEmbeddedObjectResolver" _ustr),
UNO_QUERY);
mpImpl->mbOwnEmbeddedResolver = mxEmbeddedResolver.is();
}
}
catch ( css::uno::Exception& )
{
}
}
void SAL_CALL SvXMLImport::endDocument()
{
SAL_INFO( "xmloff.core" , "} SvXMLImport::endDocument" );
// #i9518# All the stuff that accesses the document has to be done here, not in the dtor,
// because the SvXMLImport dtor might not be called until after the document has been closed.
if (mxTextImport)
mxTextImport->MapCrossRefHeadingFieldsHorribly();
if (mpImpl->mpRDFaHelper)
{
const uno::Reference<rdf::XRepositorySupplier> xRS(mxModel,
uno::UNO_QUERY);
if (xRS.is())
{
mpImpl->mpRDFaHelper->InsertRDFa( xRS );
}
}
mpNumImport.reset();
if (mxImportInfo.is())
{
uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
if (xPropertySetInfo.is())
{
if (bool (mpProgressBarHelper))
{
OUString sProgressMax(XML_PROGRESSMAX);
OUString sProgressCurrent(XML_PROGRESSCURRENT);
OUString sRepeat(XML_PROGRESSREPEAT);
if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
xPropertySetInfo->hasPropertyByName(sProgressCurrent))
{
sal_Int32 nProgressMax(mpProgressBarHelper->GetReference());
sal_Int32 nProgressCurrent(mpProgressBarHelper->GetValue());
mxImportInfo->setPropertyValue(sProgressMax, uno::Any(nProgressMax));
mxImportInfo->setPropertyValue(sProgressCurrent, uno::Any(nProgressCurrent));
}
if (xPropertySetInfo->hasPropertyByName(sRepeat))
mxImportInfo->setPropertyValue(sRepeat, css::uno::Any(mpProgressBarHelper->GetRepeat()));
// pProgressBarHelper is deleted in dtor
}
OUString sNumberStyles(XML_NUMBERSTYLES);
if (mxNumberStyles.is() && xPropertySetInfo->hasPropertyByName(sNumberStyles))
{
mxImportInfo->setPropertyValue(sNumberStyles, Any(mxNumberStyles));
}
}
}
if ( mxFontDecls.is() )
mxFontDecls->dispose();
if ( mxStyles.is() )
mxStyles->dispose();
if ( mxAutoStyles.is() )
mxAutoStyles->dispose();
if ( mxMasterStyles.is() )
mxMasterStyles->dispose();
// possible form-layer related knittings which can only be done when
// the whole document exists
if ( mxFormImport.is() )
mxFormImport->documentDone();
// The shape import helper does the z-order sorting in the dtor,
// so it must be deleted here, too.
mxShapeImport = nullptr;
if ( mpImpl->mbOwnGraphicResolver )
{
Reference<lang::XComponent> xComp(mxGraphicStorageHandler, UNO_QUERY);
xComp->dispose();
}
if ( mpImpl->mbOwnEmbeddedResolver )
{
Reference< lang::XComponent > xComp( mxEmbeddedResolver, UNO_QUERY );
xComp->dispose();
}
mpStyleMap.clear();
if ( bool ( mpXMLErrors ) )
{
mpXMLErrors->ThrowErrorAsSAXException( XMLERROR_FLAG_SEVERE );
}
}
std::optional<SvXMLNamespaceMap> SvXMLImport::processNSAttributes(
std::optional<SvXMLNamespaceMap> & rpNamespaceMap,
SvXMLImport *const pImport, // TODO???
const uno::Reference< xml::sax::XAttributeList >& xAttrList)
{
std::optional<SvXMLNamespaceMap> pRewindMap;
sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
for ( sal_Int16 i=0; i < nAttrCount; i++ )
{
const OUString aAttrName = xAttrList->getNameByIndex( i );
if (pImport && aAttrName == "office:version" && !pImport->mpImpl->mxODFVersion)
{
pImport->mpImpl->mxODFVersion = xAttrList->getValueByIndex( i );
// the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
if (pImport->mpImpl->mStreamName == "content.xml"
&& !pImport->IsODFVersionConsistent(*pImport->mpImpl->mxODFVersion))
{
throw xml::sax::SAXException(u"Inconsistent ODF versions in content.xml and manifest.xml!" _ustr,
uno::Reference< uno::XInterface >(),
uno::Any(
packages::zip::ZipIOException(u"Inconsistent ODF versions in content.xml and manifest.xml!" _ustr ) ) );
}
}
else if ( ( aAttrName.getLength() >= 5 ) &&
( aAttrName.startsWith( GetXMLToken(XML_XMLNS) ) ) &&
( aAttrName.getLength() == 5 || ':' == aAttrName[5] ) )
{
if ( !pRewindMap )
{
pRewindMap = std::move(rpNamespaceMap);
rpNamespaceMap.emplace(*pRewindMap);
}
const OUString aAttrValue = xAttrList->getValueByIndex( i );
OUString aPrefix( ( aAttrName.getLength() == 5 )
? OUString()
: aAttrName.copy( 6 ) );
// Add namespace, but only if it is known.
sal_uInt16 nKey = rpNamespaceMap->AddIfKnown( aPrefix, aAttrValue );
// If namespace is unknown, try to match a name with similar
// TC Id and version
if ( XML_NAMESPACE_UNKNOWN == nKey )
{
OUString aTestName( aAttrValue );
if ( SvXMLNamespaceMap::NormalizeURI( aTestName ) )
nKey = rpNamespaceMap->AddIfKnown( aPrefix, aTestName );
}
// If that namespace is not known, too, add it as unknown
if ( XML_NAMESPACE_UNKNOWN == nKey )
rpNamespaceMap->Add( aPrefix, aAttrValue );
}
}
return pRewindMap;
}
void SAL_CALL SvXMLImport::characters( const OUString& rChars )
{
maContexts.top()->characters( rChars );
}
void SAL_CALL SvXMLImport::processingInstruction( const OUString&,
const OUString& )
{
}
void SAL_CALL SvXMLImport::setDocumentLocator( const uno::Reference< xml::sax::XLocator >& rLocator )
{
mxLocator = rLocator;
}
// XFastContextHandler
void SAL_CALL SvXMLImport::startFastElement (sal_Int32 Element,
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
{
SAL_INFO("xmloff.core" , "startFastElement " << SvXMLImport::getNameFromToken( Element ));
if ( Attribs.is() && !mpImpl->mxODFVersion)
{
sax_fastparser::FastAttributeList& rAttribList =
sax_fastparser::castToFastAttributeList( Attribs );
auto aIter( rAttribList.find( XML_ELEMENT( OFFICE, XML_VERSION ) ) );
if ( aIter != rAttribList.end() )
{
mpImpl->mxODFVersion = aIter.toString();
// the ODF version in content.xml and manifest.xml must be the same starting from ODF1.2
if ( mpImpl->mStreamName == "content.xml" && !IsODFVersionConsistent( *mpImpl->mxODFVersion ) )
{
throw xml::sax::SAXException(u"Inconsistent ODF versions in content.xml and manifest.xml!" _ustr,
uno::Reference< uno::XInterface >(),
uno::Any(
packages::zip::ZipIOException(u"Inconsistent ODF versions in content.xml and manifest.xml!" _ustr ) ) );
}
}
}
maNamespaceAttrList->Clear();
maNamespaceHandler->addNSDeclAttributes( maNamespaceAttrList );
std::optional<SvXMLNamespaceMap> pRewindMap = processNSAttributes(mxNamespaceMap, this , maNamespaceAttrList);
SvXMLImportContextRef xContext;
const bool bRootContext = maContexts.empty();
if (!maContexts.empty())
{
const SvXMLImportContextRef & pHandler = maContexts.top();
SAL_INFO("xmloff.core" , "calling createFastChildContext on " << typeid (*pHandler.get()).name());
auto tmp = pHandler->createFastChildContext( Element, Attribs );
xContext = static_cast <SvXMLImportContext*>(tmp.get());
assert((tmp && xContext) || (!tmp && !xContext));
}
else
xContext.set( CreateFastContext( Element, Attribs ) );
SAL_INFO_IF(!xContext.is(), "xmloff.core" , "No fast context for element " << getNameFromToken(Element));
if (bRootContext && !xContext)
{
OUString aName = getNameFromToken(Element);
SetError( XMLERROR_FLAG_SEVERE | XMLERROR_UNKNOWN_ROOT,
{ aName }, "Root element " + aName + " unknown" , Reference<xml::sax::XLocator>() );
}
if ( !xContext )
xContext.set( new SvXMLImportContext( *this ) );
// Remember old namespace map.
if ( pRewindMap )
xContext->PutRewindMap(std::move(pRewindMap));
// Call a startElement at the new context.
xContext->startFastElement( Element, Attribs );
// Push context on stack.
maContexts.push(xContext);
}
void SAL_CALL SvXMLImport::startUnknownElement (const OUString & rNamespace, const OUString & rName,
const uno::Reference< xml::sax::XFastAttributeList > & Attribs)
{
SAL_INFO("xmloff.core" , "startUnknownElement " << rNamespace << " " << rName);
SvXMLImportContextRef xContext;
const bool bRootContext = maContexts.empty();
if (!maContexts.empty())
{
const SvXMLImportContextRef & pHandler = maContexts.top();
SAL_INFO("xmloff.core" , "calling createUnknownChildContext on " << typeid (*pHandler.get()).name());
auto tmp = pHandler->createUnknownChildContext( rNamespace, rName, Attribs );
xContext = static_cast <SvXMLImportContext*>(tmp.get());
assert((tmp && xContext) || (!tmp && !xContext));
}
else
xContext.set( CreateFastContext( -1, Attribs ) );
SAL_WARN_IF(!xContext.is(), "xmloff.core" , "No context for unknown-element " << rNamespace << " " << rName);
if (bRootContext && !xContext)
{
SetError( XMLERROR_FLAG_SEVERE | XMLERROR_UNKNOWN_ROOT,
{ rName }, "Root element " + rName + " unknown" , Reference<xml::sax::XLocator>() );
}
if (!xContext)
{
if (!maContexts.empty())
// This is pretty weird, but it's what the code did before I simplified it, and some parts of the
// code rely on this behaviour e.g. DocumentBuilderContext
xContext = maContexts.top();
else
xContext = new SvXMLImportContext( *this );
}
xContext->startUnknownElement( rNamespace, rName, Attribs );
maContexts.push(xContext);
}
void SAL_CALL SvXMLImport::endFastElement (sal_Int32 Element)
{
SAL_INFO("xmloff.core" , "endFastElement " << SvXMLImport::getNameFromToken( Element ));
if (maContexts.empty())
{
SAL_WARN("xmloff.core" , "SvXMLImport::endFastElement: no context left" );
assert(false );
return ;
}
SvXMLImportContextRef xContext = std::move(maContexts.top());
// Get a namespace map to rewind.
std::optional<SvXMLNamespaceMap> pRewindMap = xContext->TakeRewindMap();
maContexts.pop();
xContext->endFastElement( Element );
// Rewind a namespace map.
if (pRewindMap)
mxNamespaceMap = std::move(pRewindMap);
}
void SAL_CALL SvXMLImport::endUnknownElement (const OUString & rPrefix, const OUString & rLocalName)
{
SAL_INFO("xmloff.core" , "endUnknownElement " << rPrefix << " " << rLocalName);
if (maContexts.empty())
{
SAL_WARN("xmloff.core" , "SvXMLImport::endUnknownElement: no context left" );
assert(false );
return ;
}
SvXMLImportContextRef xContext = std::move(maContexts.top());
maContexts.pop();
xContext->endUnknownElement( rPrefix, rLocalName );
}
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
SvXMLImport::createFastChildContext (sal_Int32,
const uno::Reference< xml::sax::XFastAttributeList > &)
{
return this ;
}
uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
SvXMLImport::createUnknownChildContext (const OUString &, const OUString &,
const uno::Reference< xml::sax::XFastAttributeList > &)
{
return this ;
}
void SvXMLImport::SetStatistics(const uno::Sequence< beans::NamedValue> &)
{
GetProgressBarHelper()->SetRepeat(false );
GetProgressBarHelper()->SetReference(0);
}
// XImporter
void SAL_CALL SvXMLImport::setTargetDocument( const uno::Reference< lang::XComponent >& xDoc )
{
mxModel.set( xDoc, UNO_QUERY );
if ( !mxModel.is() )
throw lang::IllegalArgumentException();
try
{
uno::Reference<document::XStorageBasedDocument> const xSBDoc(mxModel, uno::UNO_QUERY);
uno::Reference<embed::XStorage> const xStor(xSBDoc.is() ? xSBDoc->getDocumentStorage()
: nullptr);
if (xStor.is())
{
mpImpl->mbIsOOoXML =
::comphelper::OStorageHelper::GetXStorageFormat(xStor)
< SOFFICE_FILEFORMAT_8;
}
}
catch (uno::Exception const &)
{
DBG_UNHANDLED_EXCEPTION("xmloff.core" );
}
if (!mxEventListener.is())
{
mxEventListener.set(new SvXMLImportEventListener(this ));
mxModel->addEventListener(mxEventListener);
}
SAL_WARN_IF( bool (mpNumImport), "xmloff.core" , "number format import already exists." );
mpNumImport.reset();
}
// XFilter
sal_Bool SAL_CALL SvXMLImport::filter( const uno::Sequence< beans::PropertyValue >& )
{
return false ;
}
void SAL_CALL SvXMLImport::cancel( )
{
}
// XInitialize
void SAL_CALL SvXMLImport::initialize( const uno::Sequence< uno::Any >& aArguments )
{
for ( const auto & rAny : aArguments )
{
Reference<XInterface> xValue;
rAny >>= xValue;
uno::Reference<task::XStatusIndicator> xTmpStatusIndicator(
xValue, UNO_QUERY );
if ( xTmpStatusIndicator.is() )
mxStatusIndicator = std::move(xTmpStatusIndicator);
uno::Reference<document::XGraphicStorageHandler> xGraphicStorageHandler(xValue, UNO_QUERY);
if (xGraphicStorageHandler.is())
mxGraphicStorageHandler = std::move(xGraphicStorageHandler);
uno::Reference<document::XEmbeddedObjectResolver> xTmpObjectResolver(
xValue, UNO_QUERY );
if ( xTmpObjectResolver.is() )
mxEmbeddedResolver = std::move(xTmpObjectResolver);
uno::Reference<beans::XPropertySet> xTmpPropSet( xValue, UNO_QUERY );
if ( xTmpPropSet.is() )
{
mxImportInfo = std::move(xTmpPropSet);
uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
if (xPropertySetInfo.is())
{
OUString sPropName(XML_NUMBERSTYLES);
if (xPropertySetInfo->hasPropertyByName(sPropName))
{
uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
aAny >>= mxNumberStyles;
}
sPropName = "PrivateData" ;
if (xPropertySetInfo->hasPropertyByName(sPropName))
{
Reference < XInterface > xIfc;
uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
aAny >>= xIfc;
StyleMap *pSMap = dynamic_cast <StyleMap*>( xIfc.get() );
if ( pSMap )
{
mpStyleMap = pSMap;
}
}
OUString sBaseURI;
sPropName = "BaseURI" ;
if (xPropertySetInfo->hasPropertyByName(sPropName))
{
uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
aAny >>= sBaseURI;
mpImpl->aBaseURL.SetURL( sBaseURI );
mpImpl->aDocBase.SetURL( sBaseURI );
}
OUString sRelPath;
sPropName = "StreamRelPath" ;
if ( xPropertySetInfo->hasPropertyByName(sPropName) )
{
uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
aAny >>= sRelPath;
}
OUString sName;
sPropName = "StreamName" ;
if ( xPropertySetInfo->hasPropertyByName(sPropName) )
{
uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
aAny >>= sName;
}
if ( !sBaseURI.isEmpty() && !sName.isEmpty() )
{
if ( !sRelPath.isEmpty() )
mpImpl->aBaseURL.insertName( sRelPath );
mpImpl->aBaseURL.insertName( sName );
}
mpImpl->mStreamName = sName; // Note: may be empty (XSLT)
// Retrieve property <ShapePositionInHoriL2R> (#i28749#)
sPropName = "ShapePositionInHoriL2R" ;
if ( xPropertySetInfo->hasPropertyByName(sPropName) )
{
uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
aAny >>= mpImpl->mbShapePositionInHoriL2R;
}
sPropName = "TextDocInOOoFileFormat" ;
if ( xPropertySetInfo->hasPropertyByName(sPropName) )
{
uno::Any aAny = mxImportInfo->getPropertyValue(sPropName);
aAny >>= mpImpl->mbTextDocInOOoFileFormat;
}
sPropName = "SourceStorage" ;
if ( xPropertySetInfo->hasPropertyByName(sPropName) )
mxImportInfo->getPropertyValue(sPropName) >>= mpImpl->mxSourceStorage;
}
}
}
uno::Reference<lang::XInitialization> const xInit(mxParser, uno::UNO_QUERY_THROW);
xInit->initialize( { Any(u"IgnoreMissingNSDecl" _ustr) });
}
// XServiceInfo
OUString SAL_CALL SvXMLImport::getImplementationName()
{
return mpImpl->implementationName;
}
sal_Bool SAL_CALL SvXMLImport::supportsService( const OUString& rServiceName )
{
return cppu::supportsService(this , rServiceName);
}
uno::Sequence< OUString > SAL_CALL SvXMLImport::getSupportedServiceNames( )
{
return mpImpl->maSupportedServiceNames;
}
XMLTextImportHelper* SvXMLImport::CreateTextImport()
{
return new XMLTextImportHelper( mxModel, *this );
}
XMLShapeImportHelper* SvXMLImport::CreateShapeImport()
{
return new XMLShapeImportHelper( *this , mxModel );
}
SchXMLImportHelper* SvXMLImport::CreateChartImport()
{
// WASM_CHART change
// TODO: Instead of importing the ChartModel an alternative may be
// added to convert not to Chart/OLE SdrObejct, but to GraphicObject
// with the Chart visualization. There should be a preview available
// in the imported chart data
#if !ENABLE_WASM_STRIP_CHART
return new SchXMLImportHelper();
#else
return nullptr;
#endif
}
::xmloff::OFormLayerXMLImport* SvXMLImport::CreateFormImport()
{
return new ::xmloff::OFormLayerXMLImport(*this );
}
// Get or create fill/line/lineend-style-helper
const Reference< container::XNameContainer > & SvXMLImport::GetGradientHelper()
{
if ( !mxGradientHelper.is() )
{
if ( mxModel.is() )
{
Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
if ( xServiceFact.is() )
{
try
{
mxGradientHelper.set( xServiceFact->createInstance(
u"com.sun.star.drawing.GradientTable" _ustr ), UNO_QUERY);
}
catch ( lang::ServiceNotRegisteredException& )
{}
}
}
}
return mxGradientHelper;
}
const Reference< container::XNameContainer > & SvXMLImport::GetHatchHelper()
{
if ( !mxHatchHelper.is() )
{
if ( mxModel.is() )
{
Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
if ( xServiceFact.is() )
{
try
{
mxHatchHelper.set( xServiceFact->createInstance(
u"com.sun.star.drawing.HatchTable" _ustr ), UNO_QUERY);
}
catch ( lang::ServiceNotRegisteredException& )
{}
}
}
}
return mxHatchHelper;
}
const Reference< container::XNameContainer > & SvXMLImport::GetBitmapHelper()
{
if ( !mxBitmapHelper.is() )
{
if ( mxModel.is() )
{
Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
if ( xServiceFact.is() )
{
try
{
mxBitmapHelper.set( xServiceFact->createInstance(
u"com.sun.star.drawing.BitmapTable" _ustr ), UNO_QUERY);
}
catch ( lang::ServiceNotRegisteredException& )
{}
}
}
}
return mxBitmapHelper;
}
const Reference< container::XNameContainer > & SvXMLImport::GetTransGradientHelper()
{
if ( !mxTransGradientHelper.is() )
{
if ( mxModel.is() )
{
Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
if ( xServiceFact.is() )
{
try
{
mxTransGradientHelper.set( xServiceFact->createInstance(
u"com.sun.star.drawing.TransparencyGradientTable" _ustr ), UNO_QUERY);
}
catch ( lang::ServiceNotRegisteredException& )
{}
}
}
}
return mxTransGradientHelper;
}
const Reference< container::XNameContainer > & SvXMLImport::GetMarkerHelper()
{
if ( !mxMarkerHelper.is() )
{
if ( mxModel.is() )
{
Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
if ( xServiceFact.is() )
{
try
{
mxMarkerHelper.set( xServiceFact->createInstance( u"com.sun.star.drawing.MarkerTable" _ustr ), UNO_QUERY);
}
catch ( lang::ServiceNotRegisteredException& )
{}
}
}
}
return mxMarkerHelper;
}
const Reference< container::XNameContainer > & SvXMLImport::GetDashHelper()
{
if ( !mxDashHelper.is() && mxModel.is() )
{
Reference< lang::XMultiServiceFactory > xServiceFact( mxModel, UNO_QUERY);
if ( xServiceFact.is() )
{
try
{
mxDashHelper.set( xServiceFact->createInstance( u"com.sun.star.drawing.DashTable" _ustr ), UNO_QUERY);
}
catch ( lang::ServiceNotRegisteredException& )
{}
}
}
return mxDashHelper;
}
bool SvXMLImport::IsPackageURL( std::u16string_view rURL ) const
{
// if, and only if, only parts are imported, then we're in a package
const SvXMLImportFlags nTest = SvXMLImportFlags::META|SvXMLImportFlags::STYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SETTINGS;
if ( (mnImportFlags & nTest) == nTest )
return false ;
// TODO: from this point extract to own static function
// Some quick tests: Some may rely on the package structure!
size_t nLen = rURL.size();
if ( nLen > 0 && '/' == rURL[0] )
// RFC2396 net_path or abs_path
return false ;
else if ( nLen > 1 && '.' == rURL[0] )
{
if ( '.' == rURL[1] )
// ../: We are never going up one level, so we know
// it's not an external URI
return false ;
else if ( '/' == rURL[1] )
// we are remaining on a level, so it's a package URI
return true ;
}
// Now check for a RFC2396 schema
size_t nPos = 1;
while ( nPos < nLen )
{
switch ( rURL[nPos] )
{
case '/' :
// a relative path segment
return true ;
case ':' :
// a schema
return false ;
default :
break ;
// we don't care about any other characters
}
++nPos;
}
return true ;
}
uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicByURL(OUString const & rURL,
sal_Int32 nPageNum)
{
uno::Reference<graphic::XGraphic> xGraphic;
try
{
if (mxGraphicStorageHandler.is())
{
if (IsPackageURL(rURL))
{
xGraphic = mxGraphicStorageHandler->loadGraphicAtPage(rURL, nPageNum);
}
else
{
OUString const aAbsoluteURL = GetAbsoluteReference(rURL);
GraphicExternalLink aExternalLink(aAbsoluteURL);
Graphic aGraphic(aExternalLink);
xGraphic = aGraphic.GetXGraphic();
}
}
}
catch (...)
{
bool bRepairPackage = false ;
if (auto const xStorProps{ GetSourceStorage().query<beans::XPropertySet>() })
{
try
{
xStorProps->getPropertyValue(u"RepairPackage" _ustr) >>= bRepairPackage;
}
catch (uno::Exception&)
{
}
}
if (!bRepairPackage)
throw ;
}
return xGraphic;
}
uno::Reference<graphic::XGraphic> SvXMLImport::loadGraphicFromBase64(uno::Reference<io::XOutputStream> const & rxOutputStream)
{
uno::Reference<graphic::XGraphic> xGraphic;
if (mxGraphicStorageHandler.is())
{
xGraphic = mxGraphicStorageHandler->loadGraphicFromOutputStream(rxOutputStream);
}
return xGraphic;
}
Reference< XOutputStream > SvXMLImport::GetStreamForGraphicObjectURLFromBase64() const
{
Reference< XOutputStream > xOStm;
Reference< document::XBinaryStreamResolver > xStmResolver(mxGraphicStorageHandler, UNO_QUERY);
if ( xStmResolver.is() )
xOStm = xStmResolver->createOutputStream();
return xOStm;
}
OUString SvXMLImport::ResolveEmbeddedObjectURL(
const OUString& rURL,
std::u16string_view rClassId )
{
OUString sRet;
if ( IsPackageURL( rURL ) )
{
if ( mxEmbeddedResolver.is() )
{
OUString sURL( rURL );
if ( !rClassId.empty() )
{
sURL += OUString::Concat("!" ) + rClassId;
}
sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( sURL );
}
}
else
sRet = GetAbsoluteReference( rURL );
return sRet;
}
Reference< embed::XStorage > const & SvXMLImport::GetSourceStorage() const
{
return mpImpl->mxSourceStorage;
}
Reference < XOutputStream >
SvXMLImport::GetStreamForEmbeddedObjectURLFromBase64() const
{
Reference < XOutputStream > xOLEStream;
if ( mxEmbeddedResolver.is() )
{
Reference< XNameAccess > xNA( mxEmbeddedResolver, UNO_QUERY );
if ( xNA.is() )
{
Any aAny = xNA->getByName( u"Obj12345678" _ustr );
aAny >>= xOLEStream;
}
}
return xOLEStream;
}
OUString SvXMLImport::ResolveEmbeddedObjectURLFromBase64()
{
OUString sRet;
if ( mxEmbeddedResolver.is() )
{
sRet = mxEmbeddedResolver->resolveEmbeddedObjectURL( u"Obj12345678" _ustr );
}
return sRet;
}
void SvXMLImport::AddStyleDisplayName( XmlStyleFamily nFamily,
const OUString& rName,
const OUString& rDisplayName )
{
if ( !mpStyleMap.is() )
{
mpStyleMap = new StyleMap;
if ( mxImportInfo.is() )
{
OUString sPrivateData( u"PrivateData" _ustr );
Reference< beans::XPropertySetInfo > xPropertySetInfo =
mxImportInfo->getPropertySetInfo();
if ( xPropertySetInfo.is() &&
xPropertySetInfo->hasPropertyByName(sPrivateData) )
{
Reference < XInterface > xIfc(
static_cast < css::lang::XTypeProvider *>( mpStyleMap.get() ) );
mxImportInfo->setPropertyValue( sPrivateData, Any(xIfc) );
}
}
}
StyleMap::key_type aKey( nFamily, rName );
StyleMap::value_type aValue( aKey, rDisplayName );
::std::pair<StyleMap::iterator,bool > aRes( mpStyleMap->insert( aValue ) );
SAL_WARN_IF( !aRes.second,
"xmloff.core" ,
"duplicate style name of family " << static_cast <int >(nFamily) << ": \" " << rName << " \"" );
}
OUString SvXMLImport::GetStyleDisplayName( XmlStyleFamily nFamily,
const OUString& rName ) const
{
OUString sName( rName );
if ( mpStyleMap.is() && !rName.isEmpty() )
{
StyleMap::key_type aKey( nFamily, rName );
StyleMap::const_iterator aIter = mpStyleMap->find( aKey );
if ( aIter != mpStyleMap->end() )
sName = (*aIter).second;
}
return sName;
}
void SvXMLImport::SetViewSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
{
}
void SvXMLImport::SetConfigurationSettings(const css::uno::Sequence<css::beans::PropertyValue>&)
{
}
void SvXMLImport::SetDocumentSpecificSettings(const OUString&, const uno::Sequence<beans::PropertyValue>&)
{
}
ProgressBarHelper* SvXMLImport::GetProgressBarHelper()
{
if (!mpProgressBarHelper)
{
mpProgressBarHelper = std::make_unique<ProgressBarHelper>(mxStatusIndicator, false );
if (mxImportInfo.is())
{
uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = mxImportInfo->getPropertySetInfo();
if (xPropertySetInfo.is())
{
OUString sProgressRange(XML_PROGRESSRANGE);
OUString sProgressMax(XML_PROGRESSMAX);
OUString sProgressCurrent(XML_PROGRESSCURRENT);
OUString sRepeat(XML_PROGRESSREPEAT);
if (xPropertySetInfo->hasPropertyByName(sProgressMax) &&
xPropertySetInfo->hasPropertyByName(sProgressCurrent) &&
xPropertySetInfo->hasPropertyByName(sProgressRange))
{
uno::Any aAny;
sal_Int32 nProgressMax(0);
sal_Int32 nProgressCurrent(0);
sal_Int32 nProgressRange(0);
aAny = mxImportInfo->getPropertyValue(sProgressRange);
if (aAny >>= nProgressRange)
mpProgressBarHelper->SetRange(nProgressRange);
aAny = mxImportInfo->getPropertyValue(sProgressMax);
if (aAny >>= nProgressMax)
mpProgressBarHelper->SetReference(nProgressMax);
aAny = mxImportInfo->getPropertyValue(sProgressCurrent);
if (aAny >>= nProgressCurrent)
mpProgressBarHelper->SetValue(nProgressCurrent);
}
if (xPropertySetInfo->hasPropertyByName(sRepeat))
{
uno::Any aAny = mxImportInfo->getPropertyValue(sRepeat);
if (aAny.getValueType() == cppu::UnoType<bool >::get())
mpProgressBarHelper->SetRepeat(::cppu::any2bool(aAny));
else {
SAL_WARN( "xmloff.core" , "why is it no boolean?" );
}
}
}
}
}
return mpProgressBarHelper.get();
}
void SvXMLImport::AddNumberStyle(sal_Int32 nKey, const OUString& rName)
{
if (!mxNumberStyles.is())
mxNumberStyles.set( comphelper::NameContainer_createInstance( ::cppu::UnoType<sal_Int32>::get()) );
if (mxNumberStyles.is())
{
try
{
mxNumberStyles->insertByName(rName, Any(nKey));
}
catch ( uno::Exception& )
{
DBG_UNHANDLED_EXCEPTION( "xmloff.core" , "Numberformat could not be inserted" );
}
}
else {
SAL_WARN( "xmloff.core" , "not possible to create NameContainer" );
}
}
XMLEventImportHelper& SvXMLImport::GetEventImport()
{
if (!mpEventImportHelper)
{
// construct event helper and register StarBasic handler and standard
// event tables
mpEventImportHelper = std::make_unique<XMLEventImportHelper>();
const OUString& sStarBasic(GetXMLToken(XML_STARBASIC));
mpEventImportHelper->RegisterFactory(sStarBasic,
std::make_unique<XMLStarBasicContextFactory>());
const OUString& sScript(GetXMLToken(XML_SCRIPT));
mpEventImportHelper->RegisterFactory(sScript,
std::make_unique<XMLScriptContextFactory>());
mpEventImportHelper->AddTranslationTable(aStandardEventTable);
// register StarBasic event handler with capitalized spelling
mpEventImportHelper->RegisterFactory(u"StarBasic" _ustr,
std::make_unique<XMLStarBasicContextFactory>());
}
return *mpEventImportHelper;
}
void SvXMLImport::SetFontDecls( XMLFontStylesContext *pFontDecls )
{
if (mxFontDecls.is())
mxFontDecls->dispose();
mxFontDecls = pFontDecls;
}
void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles )
{
if (mxStyles.is())
mxStyles->dispose();
mxStyles = pStyles;
}
void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
{
if (pAutoStyles && mxNumberStyles.is())
{
uno::Reference<xml::sax::XFastAttributeList> xAttrList = new sax_fastparser::FastAttributeList(nullptr);
const uno::Sequence<OUString> aStyleNames = mxNumberStyles->getElementNames();
for (const auto & name : aStyleNames)
{
uno::Any aAny(mxNumberStyles->getByName(name));
sal_Int32 nKey(0);
if (aAny >>= nKey)
{
SvXMLStyleContext* pContext = new SvXMLNumFormatContext(
*this , name, xAttrList, nKey,
GetDataStylesImport()->GetLanguageForKey(nKey), *pAutoStyles);
pAutoStyles->AddStyle(*pContext);
}
}
}
if (mxAutoStyles.is())
mxAutoStyles->dispose();
mxAutoStyles = pAutoStyles;
GetTextImport()->SetAutoStyles( pAutoStyles );
GetShapeImport()->SetAutoStylesContext( pAutoStyles );
#if !ENABLE_WASM_STRIP_CHART
GetChartImport()->SetAutoStylesContext( pAutoStyles );
#endif
GetFormImport()->setAutoStyleContext( pAutoStyles );
}
void SvXMLImport::SetMasterStyles( SvXMLStylesContext *pMasterStyles )
{
if (mxMasterStyles.is())
mxMasterStyles->dispose();
mxMasterStyles = pMasterStyles;
}
XMLFontStylesContext *SvXMLImport::GetFontDecls()
{
return mxFontDecls.get();
}
SvXMLStylesContext *SvXMLImport::GetStyles()
{
return mxStyles.get();
}
SvXMLStylesContext *SvXMLImport::GetAutoStyles()
{
return mxAutoStyles.get();
}
const XMLFontStylesContext *SvXMLImport::GetFontDecls() const
{
return mxFontDecls.get();
}
const SvXMLStylesContext *SvXMLImport::GetStyles() const
{
return mxStyles.get();
}
const SvXMLStylesContext *SvXMLImport::GetAutoStyles() const
{
return mxAutoStyles.get();
}
OUString SvXMLImport::GetAbsoluteReference(const OUString& rValue) const
{
if ( rValue.isEmpty() || rValue[0] == '#' )
return rValue;
INetURLObject aAbsURL;
if ( mpImpl->aBaseURL.GetNewAbsURL( rValue, &aAbsURL ) )
return aAbsURL.GetMainURL( INetURLObject::DecodeMechanism::ToIUri );
else
return rValue;
}
bool SvXMLImport::IsODFVersionConsistent( const OUString& aODFVersion )
{
// the check returns false only if the storage version could be retrieved
bool bResult = true ;
if ( !aODFVersion.isEmpty() && aODFVersion.compareTo( ODFVER_012_TEXT ) >= 0 )
{
// check the consistency only for the ODF1.2 and later ( according to content.xml )
// manifest.xml might have no version, it should be checked here and the correct version should be set
try
{ // don't use getDocumentStorage(), it's temporary and latest version
uno::Reference<embed::XStorage> const xStor(GetSourceStorage());
if (!xStor.is())
return bResult;
uno::Reference< beans::XPropertySet > xStorProps( xStor, uno::UNO_QUERY_THROW );
// the check should be done only for OASIS format
if (!IsOOoXML())
{
bool bRepairPackage = false ;
try
{
xStorProps->getPropertyValue( u"RepairPackage" _ustr )
>>= bRepairPackage;
} catch ( uno::Exception& )
{}
// check only if not in Repair mode
if ( !bRepairPackage )
{
OUString aStorVersion;
xStorProps->getPropertyValue( u"Version" _ustr )
>>= aStorVersion;
// if the storage version is set in manifest.xml, it must be the same as in content.xml
// if not, set it explicitly to be used further ( it will work even for readonly storage )
// This workaround is not nice, but I see no other way to handle it, since there are
// ODF1.2 documents without version in manifest.xml
if ( !aStorVersion.isEmpty() )
bResult = aODFVersion == aStorVersion;
else
xStorProps->setPropertyValue( u"Version" _ustr,
uno::Any( aODFVersion ) );
if ( bResult )
{
bool bInconsistent = false ;
xStorProps->getPropertyValue( u"IsInconsistent" _ustr )
>>= bInconsistent;
bResult = !bInconsistent;
}
}
}
}
catch ( uno::Exception& )
{}
}
return bResult;
}
void SvXMLImport::CreateNumberFormatsSupplier_()
{
SAL_WARN_IF( mxNumberFormatsSupplier.is(), "xmloff.core" , "number formats supplier already exists!" );
if (mxModel.is())
mxNumberFormatsSupplier =
uno::Reference< util::XNumberFormatsSupplier> (mxModel, uno::UNO_QUERY);
}
void SvXMLImport::CreateDataStylesImport_()
{
SAL_WARN_IF( bool (mpNumImport), "xmloff.core" , "data styles import already exists!" );
uno::Reference<util::XNumberFormatsSupplier> xNum =
GetNumberFormatsSupplier();
if ( xNum.is() )
mpNumImport = std::make_unique<SvXMLNumFmtHelper>(xNum);
}
sal_Unicode SvXMLImport::ConvStarBatsCharToStarSymbol( sal_Unicode c )
{
sal_Unicode cNew = c;
if ( !mpImpl->hBatsFontConv )
{
mpImpl->hBatsFontConv = CreateFontToSubsFontConverter( u"StarBats" ,
FontToSubsFontFlags::IMPORT );
SAL_WARN_IF( !mpImpl->hBatsFontConv, "xmloff.core" , "Got no symbol font converter" );
}
if ( mpImpl->hBatsFontConv )
{
cNew = ConvertFontToSubsFontChar( mpImpl->hBatsFontConv, c );
}
return cNew;
}
sal_Unicode SvXMLImport::ConvStarMathCharToStarSymbol( sal_Unicode c )
{
sal_Unicode cNew = c;
if ( !mpImpl->hMathFontConv )
{
mpImpl->hMathFontConv = CreateFontToSubsFontConverter( u"StarMath" ,
FontToSubsFontFlags::IMPORT );
SAL_WARN_IF( !mpImpl->hMathFontConv, "xmloff.core" , "Got no symbol font converter" );
}
if ( mpImpl->hMathFontConv )
{
cNew = ConvertFontToSubsFontChar( mpImpl->hMathFontConv, c );
}
return cNew;
}
void SvXMLImport::SetError(
sal_Int32 nId,
const Sequence<OUString>& rMsgParams,
const OUString& rExceptionMessage,
const Reference<xml::sax::XLocator>& rLocator )
{
// create error list on demand
if ( !mpXMLErrors )
mpXMLErrors = std::make_unique<XMLErrors>(nullptr);
// save error information
// use document locator (if none supplied)
mpXMLErrors->AddRecord( nId, rMsgParams, rExceptionMessage,
rLocator.is() ? rLocator : mxLocator );
}
void SvXMLImport::SetError(
sal_Int32 nId,
const Sequence<OUString>& rMsgParams)
{
SetError( nId, rMsgParams, u"" _ustr, nullptr );
}
void SvXMLImport::SetError(
sal_Int32 nId,
const OUString& rMsg1)
{
Sequence<OUString> aSeq { rMsg1 };
SetError( nId, aSeq );
}
void SvXMLImport::DisposingModel()
{
if ( mxFontDecls.is() )
mxFontDecls->dispose();
if ( mxStyles.is() )
mxStyles->dispose();
if ( mxAutoStyles.is() )
mxAutoStyles->dispose();
if ( mxMasterStyles.is() )
mxMasterStyles->dispose();
mxModel.clear();
mxEventListener.clear();
}
::comphelper::UnoInterfaceToUniqueIdentifierMapper& SvXMLImport::getInterfaceToIdentifierMapper()
{
return mpImpl->maInterfaceToIdentifierMapper;
}
uno::Reference< uno::XComponentContext > const &
SvXMLImport::GetComponentContext() const
{
return mpImpl->mxComponentContext;
}
OUString SvXMLImport::GetBaseURL() const
{
return mpImpl->aBaseURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
}
OUString SvXMLImport::GetDocumentBase() const
{
return mpImpl->aDocBase.GetMainURL( INetURLObject::DecodeMechanism::NONE );
}
// Convert drawing object positions from OOo file format to OASIS (#i28749#)
bool SvXMLImport::IsShapePositionInHoriL2R() const
{
return mpImpl->mbShapePositionInHoriL2R;
}
bool SvXMLImport::IsTextDocInOOoFileFormat() const
{
return mpImpl->mbTextDocInOOoFileFormat;
}
void SvXMLImport::initXForms()
{
// dummy method; to be implemented by derived classes supporting XForms
}
bool SvXMLImport::getBuildIds( sal_Int32& rUPD, sal_Int32& rBuild ) const
{
bool bRet = false ;
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5 C=94 H=97 G=95
¤ Dauer der Verarbeitung: 0.21 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland
2026-04-02