summaryrefslogtreecommitdiffstats
path: root/sc/source/filter/xml/xmlimprt.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/filter/xml/xmlimprt.cxx')
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx1766
1 files changed, 1766 insertions, 0 deletions
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
new file mode 100644
index 000000000..b72cf35ff
--- /dev/null
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -0,0 +1,1766 @@
+/* -*- 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 <sal/config.h>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+
+#include <svl/numformat.hxx>
+
+#include <xmloff/namespacemap.hxx>
+#include <xmloff/xmlnamespace.hxx>
+#include <xmloff/xmlictxt.hxx>
+#include <xmloff/xmlmetai.hxx>
+#include <sfx2/objsh.hxx>
+#include <unotools/streamwrap.hxx>
+#include <xmloff/xmlscripti.hxx>
+#include <xmloff/XMLFontStylesContext.hxx>
+#include <xmloff/DocumentSettingsContext.hxx>
+#include <xmloff/xmluconv.hxx>
+#include <xmloff/numehelp.hxx>
+#include <xmloff/xmltoken.hxx>
+#include <xmloff/xmlerror.hxx>
+#include <xmloff/ProgressBarHelper.hxx>
+#include <svx/svdpage.hxx>
+
+#include <svl/languageoptions.hxx>
+#include <editeng/editstat.hxx>
+#include <formula/errorcodes.hxx>
+#include <vcl/svapp.hxx>
+
+#include <appluno.hxx>
+#include "xmlimprt.hxx"
+#include "importcontext.hxx"
+#include <document.hxx>
+#include <docsh.hxx>
+#include <docuno.hxx>
+#include "xmlbodyi.hxx"
+#include "xmlstyli.hxx"
+#include <ViewSettingsSequenceDefines.hxx>
+#include <userdat.hxx>
+
+#include <compiler.hxx>
+
+#include "XMLConverter.hxx"
+#include "XMLDetectiveContext.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "XMLChangeTrackingImportHelper.hxx"
+#include <chgviset.hxx>
+#include "XMLStylesImportHelper.hxx"
+#include <sheetdata.hxx>
+#include <rangeutl.hxx>
+#include <formulaparserpool.hxx>
+#include <externalrefmgr.hxx>
+#include <editutil.hxx>
+#include "editattributemap.hxx"
+#include <documentimport.hxx>
+#include "pivotsource.hxx"
+#include <unonames.hxx>
+#include <numformat.hxx>
+#include <sizedev.hxx>
+#include <scdll.hxx>
+#include "xmlstyle.hxx"
+
+#include <comphelper/base64.hxx>
+#include <comphelper/extract.hxx>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/processfactory.hxx>
+
+#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
+#include <com/sun/star/frame/XModel.hpp>
+#include <com/sun/star/io/IOException.hpp>
+#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
+#include <com/sun/star/document/XActionLockable.hpp>
+#include <com/sun/star/util/MalformedNumberFormatException.hpp>
+#include <com/sun/star/util/NumberFormat.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/sheet/NamedRangeFlag.hpp>
+#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
+#include <cellsuno.hxx>
+
+#include <memory>
+#include <utility>
+
+constexpr OUStringLiteral SC_LOCALE = u"Locale";
+constexpr OUStringLiteral SC_CURRENCYSYMBOL = u"CurrencySymbol";
+constexpr OUStringLiteral SC_REPEAT_ROW = u"repeat-row";
+constexpr OUStringLiteral SC_FILTER = u"filter";
+constexpr OUStringLiteral SC_PRINT_RANGE = u"print-range";
+
+using namespace com::sun::star;
+using namespace ::xmloff::token;
+using namespace ::formula;
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_XMLOasisImporter_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
+{
+ return cppu::acquire(
+ new ScXMLImport(
+ context,
+ "com.sun.star.comp.Calc.XMLOasisImporter",
+ SvXMLImportFlags::ALL,
+ { "com.sun.star.comp.Calc.XMLOasisImporter" } ));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_XMLOasisMetaImporter_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
+{
+ return cppu::acquire(
+ new ScXMLImport(
+ context,
+ "com.sun.star.comp.Calc.XMLOasisMetaImporter",
+ SvXMLImportFlags::META,
+ { "com.sun.star.comp.Calc.XMLOasisMetaImporter" } ));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_XMLOasisStylesImporter_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
+{
+ return cppu::acquire(
+ new ScXMLImport(
+ context,
+ "com.sun.star.comp.Calc.XMLOasisStylesImporter",
+ SvXMLImportFlags::STYLES|SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::MASTERSTYLES|SvXMLImportFlags::FONTDECLS,
+ { "com.sun.star.comp.Calc.XMLOasisStylesImporter" } ));
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_XMLOasisContentImporter_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
+{
+ return cppu::acquire(new ScXMLImport(
+ context,
+ "com.sun.star.comp.Calc.XMLOasisContentImporter",
+ SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SCRIPTS|SvXMLImportFlags::FONTDECLS,
+ uno::Sequence< OUString > { "com.sun.star.comp.Calc.XMLOasisContentImporter" }));
+}
+
+
+extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
+Calc_XMLOasisSettingsImporter_get_implementation(
+ css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
+{
+ return cppu::acquire(
+ new ScXMLImport(
+ context,
+ "com.sun.star.comp.Calc.XMLOasisSettingsImporter",
+ SvXMLImportFlags::SETTINGS,
+ { "com.sun.star.comp.Calc.XMLOasisSettingsImporter" } ));
+}
+
+namespace {
+
+// NB: virtually inherit so we can multiply inherit properly
+// in ScXMLFlatDocContext_Impl
+class ScXMLDocContext_Impl : public virtual SvXMLImportContext
+{
+protected:
+ ScXMLImport& GetScImport() { return static_cast<ScXMLImport&>(GetImport()); }
+
+public:
+ ScXMLDocContext_Impl( ScXMLImport& rImport );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
+};
+
+}
+
+ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport ) :
+SvXMLImportContext( rImport )
+{
+}
+
+namespace {
+
+// context for flat file xml format
+class ScXMLFlatDocContext_Impl
+ : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext
+{
+public:
+
+ ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps);
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
+};
+
+}
+
+ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
+ const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
+SvXMLImportContext(i_rImport),
+ScXMLDocContext_Impl(i_rImport),
+SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+ ScXMLFlatDocContext_Impl::createFastChildContext( sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+{
+ if ( nElement == XML_ELEMENT( OFFICE, XML_META ) )
+ return SvXMLMetaDocumentContext::createFastChildContext( nElement, xAttrList );
+ else
+ return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList );
+}
+
+namespace {
+
+class ScXMLBodyContext_Impl : public ScXMLImportContext
+{
+public:
+ ScXMLBodyContext_Impl( ScXMLImport& rImport );
+
+ virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
+ createFastChildContext( sal_Int32 nElement,
+ const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
+};
+
+}
+
+ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport ) :
+ScXMLImportContext( rImport )
+{
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+ ScXMLBodyContext_Impl::createFastChildContext( sal_Int32 /*nElement*/,
+ const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
+{
+ sax_fastparser::FastAttributeList *pAttribList =
+ &sax_fastparser::castToFastAttributeList( xAttrList );
+ return GetScImport().CreateBodyContext( pAttribList );
+}
+
+uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
+ ScXMLDocContext_Impl::createFastChildContext( sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList > & /*xAttrList*/ )
+{
+ SvXMLImportContext *pContext(nullptr);
+
+ switch( nElement )
+ {
+ case XML_ELEMENT( OFFICE, XML_BODY ):
+ if (GetScImport().getImportFlags() & SvXMLImportFlags::CONTENT)
+ pContext = new ScXMLBodyContext_Impl( GetScImport() );
+ break;
+ case XML_ELEMENT( OFFICE, XML_SCRIPTS ):
+ if (GetScImport().getImportFlags() & SvXMLImportFlags::SCRIPTS)
+ pContext = GetScImport().CreateScriptContext();
+ break;
+ case XML_ELEMENT( OFFICE, XML_SETTINGS ):
+ if (GetScImport().getImportFlags() & SvXMLImportFlags::SETTINGS)
+ pContext = new XMLDocumentSettingsContext(GetScImport());
+ break;
+ case XML_ELEMENT(OFFICE, XML_STYLES):
+ if (GetScImport().getImportFlags() & SvXMLImportFlags::STYLES)
+ pContext = GetScImport().CreateStylesContext( false);
+ break;
+ case XML_ELEMENT(OFFICE, XML_AUTOMATIC_STYLES):
+ if (GetScImport().getImportFlags() & SvXMLImportFlags::AUTOSTYLES)
+ pContext = GetScImport().CreateStylesContext( true);
+ break;
+ case XML_ELEMENT(OFFICE, XML_FONT_FACE_DECLS):
+ if (GetScImport().getImportFlags() & SvXMLImportFlags::FONTDECLS)
+ pContext = GetScImport().CreateFontDeclsContext();
+ break;
+ case XML_ELEMENT(OFFICE, XML_MASTER_STYLES):
+ if (GetScImport().getImportFlags() & SvXMLImportFlags::MASTERSTYLES)
+ pContext = new ScXMLMasterStylesContext( GetImport() );
+ break;
+ case XML_ELEMENT(OFFICE, XML_META):
+ SAL_INFO("sc", "XML_ELEMENT(OFFICE, XML_META): should not have come here, maybe document is invalid?");
+ break;
+ }
+
+ return pContext;
+}
+
+
+void ScXMLImport::SetPostProcessData( sc::ImportPostProcessData* p )
+{
+ mpPostProcessData = p;
+}
+
+sc::PivotTableSources& ScXMLImport::GetPivotTableSources()
+{
+ if (!mpPivotSources)
+ mpPivotSources.reset(new sc::PivotTableSources);
+
+ return *mpPivotSources;
+}
+
+SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement,
+ const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
+{
+ SvXMLImportContext *pContext = nullptr;
+
+ switch( nElement )
+ {
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ):
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ):
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_SETTINGS ):
+ pContext = new ScXMLDocContext_Impl( *this );
+ break;
+
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
+ pContext = CreateMetaContext(nElement);
+ break;
+
+ case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
+ {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ // flat OpenDocument file format
+ pContext = new ScXMLFlatDocContext_Impl( *this,
+ xDPS->getDocumentProperties());
+ break;
+ }
+
+ }
+
+ return pContext;
+}
+
+ScXMLImport::ScXMLImport(
+ const css::uno::Reference< css::uno::XComponentContext >& rContext,
+ OUString const & implementationName, SvXMLImportFlags nImportFlag,
+ const css::uno::Sequence< OUString > & sSupportedServiceNames)
+: SvXMLImport( rContext, implementationName, nImportFlag, sSupportedServiceNames ),
+ pDoc( nullptr ),
+ mpPostProcessData(nullptr),
+ aTables(*this),
+ nSolarMutexLocked(0),
+ nProgressCount(0),
+ nPrevCellType(0),
+ bLoadDoc( true ),
+ bNullDateSetted(false),
+ bSelfImportingXMLSet(false),
+ mbLockSolarMutex(true),
+ mbImportStyles(true),
+ mbHasNewCondFormatData(false)
+{
+ pStylesImportHelper.reset(new ScMyStylesImportHelper(*this));
+
+ xScPropHdlFactory = new XMLScPropHdlFactory;
+ xCellStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScCellStylesProperties, xScPropHdlFactory, false);
+ xColumnStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScColumnStylesProperties, xScPropHdlFactory, false);
+ xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScRowStylesImportProperties, xScPropHdlFactory, false);
+ xTableStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScTableStylesImportProperties, xScPropHdlFactory, false);
+
+ // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
+ GetNamespaceMap().Add(
+ GetXMLToken( XML_NP_PRESENTATION ),
+ GetXMLToken( XML_N_PRESENTATION ),
+ XML_NAMESPACE_PRESENTATION );
+}
+
+ScXMLImport::~ScXMLImport() noexcept
+{
+ pChangeTrackingImportHelper.reset();
+ pNumberFormatAttributesExportHelper.reset();
+ pStyleNumberFormats.reset();
+ pStylesImportHelper.reset();
+
+ m_aMyNamedExpressions.clear();
+ maMyLabelRanges.clear();
+ maValidations.clear();
+ pDetectiveOpArray.reset();
+
+ //call SvXMLImport dtor contents before deleting pSolarMutexGuard
+ cleanup();
+
+ pSolarMutexGuard.reset();
+}
+
+void ScXMLImport::initialize( const css::uno::Sequence<css::uno::Any>& aArguments )
+{
+ SvXMLImport::initialize(aArguments);
+
+ uno::Reference<beans::XPropertySet> xInfoSet = getImportInfo();
+ if (!xInfoSet.is())
+ return;
+
+ uno::Reference<beans::XPropertySetInfo> xInfoSetInfo = xInfoSet->getPropertySetInfo();
+ if (!xInfoSetInfo.is())
+ return;
+
+ if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_LOCK_SOLAR_MUTEX))
+ xInfoSet->getPropertyValue(SC_UNO_ODS_LOCK_SOLAR_MUTEX) >>= mbLockSolarMutex;
+
+ if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_IMPORT_STYLES))
+ xInfoSet->getPropertyValue(SC_UNO_ODS_IMPORT_STYLES) >>= mbImportStyles;
+}
+
+SvXMLImportContext *ScXMLImport::CreateFontDeclsContext()
+{
+ XMLFontStylesContext *pFSContext = new XMLFontStylesContext(
+ *this, osl_getThreadTextEncoding());
+ SetFontDecls(pFSContext);
+ SvXMLImportContext* pContext = pFSContext;
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateStylesContext( bool bIsAutoStyle )
+{
+ SvXMLImportContext* pContext = new XMLTableStylesContext(
+ *this, bIsAutoStyle);
+
+ if (bIsAutoStyle)
+ SetAutoStyles(static_cast<SvXMLStylesContext*>(pContext));
+ else
+ SetStyles(static_cast<SvXMLStylesContext*>(pContext));
+
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateBodyContext(const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList)
+{
+ return new ScXMLBodyContext(*this, rAttrList);
+}
+
+SvXMLImportContext *ScXMLImport::CreateMetaContext(
+ const sal_Int32 /*nElement*/ )
+{
+ SvXMLImportContext* pContext = nullptr;
+
+ if (getImportFlags() & SvXMLImportFlags::META)
+ {
+ uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
+ GetModel(), uno::UNO_QUERY_THROW);
+ uno::Reference<document::XDocumentProperties> const xDocProps(
+ (IsStylesOnlyMode()) ? nullptr : xDPS->getDocumentProperties());
+ pContext = new SvXMLMetaDocumentContext(*this, xDocProps);
+ }
+
+ return pContext;
+}
+
+SvXMLImportContext *ScXMLImport::CreateScriptContext()
+{
+ SvXMLImportContext* pContext = nullptr;
+
+ if( !(IsStylesOnlyMode()) )
+ {
+ pContext = new XMLScriptContext( *this, GetModel() );
+ }
+
+ return pContext;
+}
+
+void ScXMLImport::SetStatistics(const uno::Sequence<beans::NamedValue> & i_rStats)
+{
+ static const char* s_stats[] =
+ { "TableCount", "CellCount", "ObjectCount", nullptr };
+
+ SvXMLImport::SetStatistics(i_rStats);
+
+ sal_uInt64 nCount(0);
+ for (const auto& rStat : i_rStats) {
+ for (const char** pStat = s_stats; *pStat != nullptr; ++pStat) {
+ if (rStat.Name.equalsAscii(*pStat)) {
+ sal_Int32 val = 0;
+ if (rStat.Value >>= val) {
+ nCount += val;
+ } else {
+ OSL_FAIL("ScXMLImport::SetStatistics: invalid entry");
+ }
+ }
+ }
+ }
+
+ if (nCount)
+ {
+ GetProgressBarHelper()->SetReference(nCount);
+ GetProgressBarHelper()->SetValue(0);
+ }
+}
+
+ScDocumentImport& ScXMLImport::GetDoc()
+{
+ return *mpDocImport;
+}
+
+sal_Int16 ScXMLImport::GetCellType(const char* rStrValue, const sal_Int32 nStrLength)
+{
+ sal_Int16 nCellType = util::NumberFormat::UNDEFINED;
+ if (rStrValue != nullptr)
+ {
+ switch (rStrValue[0])
+ {
+ case 'b':
+ if (nStrLength == 7 && !strcmp(rStrValue, "boolean"))
+ nCellType = util::NumberFormat::LOGICAL;
+ break;
+ case 'c':
+ if (nStrLength == 8 && !strcmp(rStrValue, "currency"))
+ nCellType = util::NumberFormat::CURRENCY;
+ break;
+ case 'd':
+ if (nStrLength == 4 && !strcmp(rStrValue, "date"))
+ nCellType = util::NumberFormat::DATETIME;
+ break;
+ case 'f':
+ if (nStrLength == 5 && !strcmp(rStrValue, "float"))
+ nCellType = util::NumberFormat::NUMBER;
+ break;
+ case 'p':
+ if (nStrLength == 10 && !strcmp(rStrValue, "percentage"))
+ nCellType = util::NumberFormat::PERCENT;
+ break;
+ case 's':
+ if (nStrLength == 6 && !strcmp(rStrValue, "string"))
+ nCellType = util::NumberFormat::TEXT;
+ break;
+ case 't':
+ if (nStrLength == 4 && !strcmp(rStrValue, "time"))
+ nCellType = util::NumberFormat::TIME;
+ break;
+ }
+ }
+
+ return nCellType;
+}
+
+XMLShapeImportHelper* ScXMLImport::CreateShapeImport()
+{
+ return new XMLTableShapeImportHelper(*this);
+}
+
+bool ScXMLImport::GetValidation(const OUString& sName, ScMyImportValidation& aValidation)
+{
+ auto aItr = std::find_if(maValidations.begin(), maValidations.end(),
+ [&sName](const ScMyImportValidation& rValidation) { return rValidation.sName == sName; });
+ if (aItr != maValidations.end())
+ {
+ // source position must be set as string,
+ // so sBaseCellAddress no longer has to be converted here
+ aValidation = *aItr;
+ return true;
+ }
+ return false;
+}
+
+void ScXMLImport::AddNamedExpression(SCTAB nTab, ScMyNamedExpression aNamedExp)
+{
+ SheetNamedExpMap::iterator itr = m_SheetNamedExpressions.find(nTab);
+ if (itr == m_SheetNamedExpressions.end())
+ {
+ // No chain exists for this sheet. Create one.
+ ::std::pair<SheetNamedExpMap::iterator, bool> r =
+ m_SheetNamedExpressions.insert(std::make_pair(nTab, ScMyNamedExpressions()));
+ if (!r.second)
+ // insertion failed.
+ return;
+
+ itr = r.first;
+ }
+ ScMyNamedExpressions& r = itr->second;
+ r.push_back(std::move(aNamedExp));
+}
+
+ScXMLChangeTrackingImportHelper* ScXMLImport::GetChangeTrackingImportHelper()
+{
+ if (!pChangeTrackingImportHelper)
+ pChangeTrackingImportHelper.reset(new ScXMLChangeTrackingImportHelper());
+ return pChangeTrackingImportHelper.get();
+}
+
+void ScXMLImport::InsertStyles()
+{
+ GetStyles()->CopyStylesToDoc(true);
+
+ // if content is going to be loaded with the same import, set bLatinDefaultStyle flag now
+ if ( getImportFlags() & SvXMLImportFlags::CONTENT )
+ ExamineDefaultStyle();
+}
+
+void ScXMLImport::ExamineDefaultStyle()
+{
+ if (pDoc)
+ {
+ // #i62435# after inserting the styles, check if the default style has a latin-script-only
+ // number format (then, value cells can be pre-initialized with western script type)
+
+ const ScPatternAttr* pDefPattern = pDoc->GetDefPattern();
+ if (pDefPattern && sc::NumFmtUtil::isLatinScript(*pDefPattern, *pDoc))
+ mpDocImport->setDefaultNumericScript(SvtScriptType::LATIN);
+ }
+}
+
+void ScXMLImport::SetChangeTrackingViewSettings(const css::uno::Sequence<css::beans::PropertyValue>& rChangeProps)
+{
+ if (!pDoc)
+ return;
+
+ if (!rChangeProps.hasElements())
+ return;
+
+ ScXMLImport::MutexGuard aGuard(*this);
+ sal_Int16 nTemp16(0);
+ ScChangeViewSettings aViewSettings;
+ for (const auto& rChangeProp : rChangeProps)
+ {
+ OUString sName(rChangeProp.Name);
+ if (sName == "ShowChanges")
+ aViewSettings.SetShowChanges(::cppu::any2bool(rChangeProp.Value));
+ else if (sName == "ShowAcceptedChanges")
+ aViewSettings.SetShowAccepted(::cppu::any2bool(rChangeProp.Value));
+ else if (sName == "ShowRejectedChanges")
+ aViewSettings.SetShowRejected(::cppu::any2bool(rChangeProp.Value));
+ else if (sName == "ShowChangesByDatetime")
+ aViewSettings.SetHasDate(::cppu::any2bool(rChangeProp.Value));
+ else if (sName == "ShowChangesByDatetimeMode")
+ {
+ if (rChangeProp.Value >>= nTemp16)
+ aViewSettings.SetTheDateMode(static_cast<SvxRedlinDateMode>(nTemp16));
+ }
+ else if (sName == "ShowChangesByDatetimeFirstDatetime")
+ {
+ util::DateTime aDateTime;
+ if (rChangeProp.Value >>= aDateTime)
+ {
+ aViewSettings.SetTheFirstDateTime(::DateTime(aDateTime));
+ }
+ }
+ else if (sName == "ShowChangesByDatetimeSecondDatetime")
+ {
+ util::DateTime aDateTime;
+ if (rChangeProp.Value >>= aDateTime)
+ {
+ aViewSettings.SetTheLastDateTime(::DateTime(aDateTime));
+ }
+ }
+ else if (sName == "ShowChangesByAuthor")
+ aViewSettings.SetHasAuthor(::cppu::any2bool(rChangeProp.Value));
+ else if (sName == "ShowChangesByAuthorName")
+ {
+ OUString sOUName;
+ if (rChangeProp.Value >>= sOUName)
+ {
+ aViewSettings.SetTheAuthorToShow(sOUName);
+ }
+ }
+ else if (sName == "ShowChangesByComment")
+ aViewSettings.SetHasComment(::cppu::any2bool(rChangeProp.Value));
+ else if (sName == "ShowChangesByCommentText")
+ {
+ OUString sOUComment;
+ if (rChangeProp.Value >>= sOUComment)
+ {
+ aViewSettings.SetTheComment(sOUComment);
+ }
+ }
+ else if (sName == "ShowChangesByRanges")
+ aViewSettings.SetHasRange(::cppu::any2bool(rChangeProp.Value));
+ else if (sName == "ShowChangesByRangesList")
+ {
+ OUString sRanges;
+ if ((rChangeProp.Value >>= sRanges) && !sRanges.isEmpty())
+ {
+ ScRangeList aRangeList;
+ ScRangeStringConverter::GetRangeListFromString(
+ aRangeList, sRanges, *pDoc, FormulaGrammar::CONV_OOO);
+ aViewSettings.SetTheRangeList(aRangeList);
+ }
+ }
+ }
+ pDoc->SetChangeViewSettings(aViewSettings);
+}
+
+void ScXMLImport::SetViewSettings(const uno::Sequence<beans::PropertyValue>& aViewProps)
+{
+ sal_Int32 nHeight(0);
+ sal_Int32 nLeft(0);
+ sal_Int32 nTop(0);
+ sal_Int32 nWidth(0);
+ for (const auto& rViewProp : aViewProps)
+ {
+ OUString sName(rViewProp.Name);
+ if (sName == "VisibleAreaHeight")
+ rViewProp.Value >>= nHeight;
+ else if (sName == "VisibleAreaLeft")
+ rViewProp.Value >>= nLeft;
+ else if (sName == "VisibleAreaTop")
+ rViewProp.Value >>= nTop;
+ else if (sName == "VisibleAreaWidth")
+ rViewProp.Value >>= nWidth;
+ else if (sName == "TrackedChangesViewSettings")
+ {
+ uno::Sequence<beans::PropertyValue> aChangeProps;
+ if(rViewProp.Value >>= aChangeProps)
+ SetChangeTrackingViewSettings(aChangeProps);
+ }
+ }
+ if (!(nHeight && nWidth && GetModel().is()))
+ return;
+
+ ScModelObj* pDocObj(comphelper::getFromUnoTunnel<ScModelObj>( GetModel() ));
+ if (!pDocObj)
+ return;
+
+ SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
+ if (pEmbeddedObj)
+ {
+ tools::Rectangle aRect{ nLeft, nTop };
+ aRect.setWidth( nWidth );
+ aRect.setHeight( nHeight );
+ pEmbeddedObj->SetVisArea(aRect);
+ }
+}
+
+void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyValue>& aConfigProps)
+{
+ if (!GetModel().is())
+ return;
+
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (!xMultiServiceFactory.is())
+ return;
+
+ sal_Int32 nCount(aConfigProps.getLength());
+ css::uno::Sequence<css::beans::PropertyValue> aFilteredProps(nCount);
+ auto pFilteredProps = aFilteredProps.getArray();
+ sal_Int32 nFilteredPropsLen = 0;
+ for (sal_Int32 i = nCount - 1; i >= 0; --i)
+ {
+ if (aConfigProps[i].Name == "TrackedChangesProtectionKey")
+ {
+ OUString sKey;
+ if (aConfigProps[i].Value >>= sKey)
+ {
+ uno::Sequence<sal_Int8> aPass;
+ ::comphelper::Base64::decode(aPass, sKey);
+ if (aPass.hasElements())
+ {
+ if (pDoc->GetChangeTrack())
+ pDoc->GetChangeTrack()->SetProtection(aPass);
+ else
+ {
+ std::set<OUString> aUsers;
+ std::unique_ptr<ScChangeTrack> pTrack( new ScChangeTrack(*pDoc, std::move(aUsers)) );
+ pTrack->SetProtection(aPass);
+ pDoc->SetChangeTrack(std::move(pTrack));
+ }
+ }
+ }
+ }
+ // store the following items for later use (after document is loaded)
+ else if ((aConfigProps[i].Name == "VBACompatibilityMode") || (aConfigProps[i].Name == "ScriptConfiguration"))
+ {
+ uno::Reference< beans::XPropertySet > xImportInfo = getImportInfo();
+ if (xImportInfo.is())
+ {
+ uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo();
+ if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName(aConfigProps[i].Name))
+ xImportInfo->setPropertyValue( aConfigProps[i].Name, aConfigProps[i].Value );
+ }
+ }
+ if (aConfigProps[i].Name != "LinkUpdateMode")
+ {
+ pFilteredProps[nFilteredPropsLen++] = aConfigProps[i];
+ }
+ }
+ aFilteredProps.realloc(nFilteredPropsLen);
+ uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance("com.sun.star.comp.SpreadsheetSettings");
+ uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY);
+ if (xProperties.is())
+ SvXMLUnitConverter::convertPropertySet(xProperties, aFilteredProps);
+}
+
+sal_Int32 ScXMLImport::SetCurrencySymbol(const sal_Int32 nKey, std::u16string_view rCurrency)
+{
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ {
+ uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
+ if (xLocalNumberFormats.is())
+ {
+ OUString sFormatString;
+ try
+ {
+ uno::Reference <beans::XPropertySet> xProperties(xLocalNumberFormats->getByKey(nKey));
+ if (xProperties.is())
+ {
+ lang::Locale aLocale;
+ if (GetDocument() && (xProperties->getPropertyValue(SC_LOCALE) >>= aLocale))
+ {
+ {
+ ScXMLImport::MutexGuard aGuard(*this);
+ LocaleDataWrapper aLocaleData( comphelper::getProcessComponentContext(), LanguageTag( aLocale) );
+ sFormatString = "#" +
+ aLocaleData.getNumThousandSep() +
+ "##0" +
+ aLocaleData.getNumDecimalSep() +
+ "00 [$" +
+ rCurrency +
+ "]";
+ }
+ sal_Int32 nNewKey = xLocalNumberFormats->queryKey(sFormatString, aLocale, true);
+ if (nNewKey == -1)
+ nNewKey = xLocalNumberFormats->addNew(sFormatString, aLocale);
+ return nNewKey;
+ }
+ }
+ }
+ catch ( const util::MalformedNumberFormatException& rException )
+ {
+ OUString sErrorMessage ="Error in Formatstring " +
+ sFormatString + " at position " +
+ OUString::number(rException.CheckPos);
+ uno::Sequence<OUString> aSeq { sErrorMessage };
+ uno::Reference<xml::sax::XLocator> xLocator;
+ SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rException.Message, xLocator);
+ }
+ }
+ }
+ return nKey;
+}
+
+bool ScXMLImport::IsCurrencySymbol(const sal_Int32 nNumberFormat, const OUString& sCurrentCurrency, std::u16string_view sBankSymbol)
+{
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ {
+ uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
+ if (xLocalNumberFormats.is())
+ {
+ try
+ {
+ uno::Reference <beans::XPropertySet> xNumberPropertySet(xLocalNumberFormats->getByKey(nNumberFormat));
+ if (xNumberPropertySet.is())
+ {
+ OUString sTemp;
+ if ( xNumberPropertySet->getPropertyValue(SC_CURRENCYSYMBOL) >>= sTemp)
+ {
+ if (sCurrentCurrency == sTemp)
+ return true;
+ // A release that saved an unknown currency may have
+ // saved the currency symbol of the number format
+ // instead of an ISO code bank symbol. In another
+ // release we may have a match for that. In this case
+ // sCurrentCurrency is the ISO code obtained through
+ // XMLNumberFormatAttributesExportHelper::GetCellType()
+ // and sBankSymbol is the currency symbol.
+ if (sCurrentCurrency.getLength() == 3 && sBankSymbol == sTemp)
+ return true;
+ // #i61657# This may be a legacy currency symbol that changed in the meantime.
+ if (SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sCurrentCurrency, sBankSymbol) != nullptr)
+ return true;
+ // In the rare case that sCurrentCurrency is not the
+ // currency symbol, but a matching ISO code
+ // abbreviation instead that was obtained through
+ // XMLNumberFormatAttributesExportHelper::GetCellType(),
+ // check with the number format's symbol. This happens,
+ // for example, in the es_BO locale, where a legacy
+ // B$,BOB matched B$->BOP, which leads to
+ // sCurrentCurrency being BOP, and the previous call
+ // with BOP,BOB didn't find an entry, but B$,BOB will.
+ return SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sTemp, sBankSymbol) != nullptr;
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL("Numberformat not found");
+ }
+ }
+ }
+ return false;
+}
+
+void ScXMLImport::SetType(const uno::Reference <beans::XPropertySet>& rProperties,
+ sal_Int32& rNumberFormat,
+ const sal_Int16 nCellType,
+ std::u16string_view rCurrency)
+{
+ if (!mbImportStyles)
+ return;
+
+ if ((nCellType == util::NumberFormat::TEXT) || (nCellType == util::NumberFormat::UNDEFINED))
+ return;
+
+ if (rNumberFormat == -1)
+ rProperties->getPropertyValue( SC_UNONAME_NUMFMT ) >>= rNumberFormat;
+ OSL_ENSURE(rNumberFormat != -1, "no NumberFormat");
+ bool bIsStandard;
+ // sCurrentCurrency may be the ISO code abbreviation if the currency
+ // symbol matches such, or if no match found the symbol itself!
+ OUString sCurrentCurrency;
+ sal_Int32 nCurrentCellType(
+ GetNumberFormatAttributesExportHelper()->GetCellType(
+ rNumberFormat, sCurrentCurrency, bIsStandard) & ~util::NumberFormat::DEFINED);
+ // If the (numeric) cell type (number, currency, date, time, boolean)
+ // is different from the format type then for some combinations we may
+ // have to apply a format, e.g. in case the generator deduced format
+ // from type and did not apply a format but we don't keep a dedicated
+ // type internally. Specifically this is necessary if the cell type is
+ // not number but the format type is (i.e. General). Currency cells
+ // need extra attention, see calls of ScXMLImport::IsCurrencySymbol()
+ // and description within there and ScXMLImport::SetCurrencySymbol().
+ if ((nCellType != nCurrentCellType) &&
+ (nCellType != util::NumberFormat::NUMBER) &&
+ (bIsStandard || (nCellType == util::NumberFormat::CURRENCY)))
+ {
+ if (!xNumberFormats.is())
+ {
+ uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
+ if (xNumberFormatsSupplier.is())
+ xNumberFormats.set(xNumberFormatsSupplier->getNumberFormats());
+ }
+ if (xNumberFormats.is())
+ {
+ try
+ {
+ uno::Reference < beans::XPropertySet> xNumberFormatProperties(xNumberFormats->getByKey(rNumberFormat));
+ if (xNumberFormatProperties.is())
+ {
+ if (nCellType != util::NumberFormat::CURRENCY)
+ {
+ lang::Locale aLocale;
+ if ( xNumberFormatProperties->getPropertyValue(SC_LOCALE) >>= aLocale )
+ {
+ if (!xNumberFormatTypes.is())
+ xNumberFormatTypes.set(uno::Reference <util::XNumberFormatTypes>(xNumberFormats, uno::UNO_QUERY));
+ rProperties->setPropertyValue( SC_UNONAME_NUMFMT, uno::Any(xNumberFormatTypes->getStandardFormat(nCellType, aLocale)) );
+ }
+ }
+ else if (!rCurrency.empty() && !sCurrentCurrency.isEmpty())
+ {
+ if (sCurrentCurrency != rCurrency)
+ if (!IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
+ rProperties->setPropertyValue( SC_UNONAME_NUMFMT, uno::Any(SetCurrencySymbol(rNumberFormat, rCurrency)));
+ }
+ }
+ }
+ catch ( uno::Exception& )
+ {
+ OSL_FAIL("Numberformat not found");
+ }
+ }
+ }
+ else
+ {
+ if ((nCellType == util::NumberFormat::CURRENCY) && !rCurrency.empty() && !sCurrentCurrency.isEmpty() &&
+ sCurrentCurrency != rCurrency && !IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
+ rProperties->setPropertyValue( SC_UNONAME_NUMFMT, uno::Any(SetCurrencySymbol(rNumberFormat, rCurrency)));
+ }
+}
+
+void ScXMLImport::SetStyleToRanges()
+{
+ if (!mbImportStyles)
+ return;
+
+ if (!sPrevStyleName.isEmpty())
+ {
+ uno::Reference <beans::XPropertySet> xProperties (xSheetCellRanges, uno::UNO_QUERY);
+ if (xProperties.is())
+ {
+ XMLTableStylesContext *pStyles(static_cast<XMLTableStylesContext *>(GetAutoStyles()));
+ XMLTableStyleContext* pStyle = nullptr;
+ if ( pStyles )
+ pStyle = const_cast<XMLTableStyleContext*>(static_cast<const XMLTableStyleContext *>(pStyles->FindStyleChildContext(
+ XmlStyleFamily::TABLE_CELL, sPrevStyleName, true)));
+ if (pStyle)
+ {
+ pStyle->FillPropertySet(xProperties);
+ // here needs to be the cond format import method
+ sal_Int32 nNumberFormat(pStyle->GetNumberFormat());
+ SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
+
+ css::uno::Any aAny = xProperties->getPropertyValue("FormatID");
+ sal_uInt64 nKey = 0;
+ if ((aAny >>= nKey) && nKey)
+ {
+ ScFormatSaveData* pFormatSaveData = comphelper::getFromUnoTunnel<ScModelObj>(GetModel())->GetFormatSaveData();
+ pFormatSaveData->maIDToName.insert(std::pair<sal_uInt64, OUString>(nKey, sPrevStyleName));
+ }
+
+ // store first cell of first range for each style, once per sheet
+ uno::Sequence<table::CellRangeAddress> aAddresses(xSheetCellRanges->getRangeAddresses());
+ pStyle->ApplyCondFormat(aAddresses);
+ if ( aAddresses.hasElements() )
+ {
+ const table::CellRangeAddress& rRange = aAddresses[0];
+ if ( rRange.Sheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = comphelper::getFromUnoTunnel<ScModelObj>(GetModel())->GetSheetSaveData();
+ pSheetData->AddCellStyle( sPrevStyleName,
+ ScAddress( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), static_cast<SCTAB>(rRange.Sheet) ) );
+ pStyle->SetLastSheet(rRange.Sheet);
+ }
+ }
+ }
+ else
+ {
+ xProperties->setPropertyValue(SC_UNONAME_CELLSTYL, uno::Any(GetStyleDisplayName( XmlStyleFamily::TABLE_CELL, sPrevStyleName )));
+ sal_Int32 nNumberFormat(GetStyleNumberFormats()->GetStyleNumberFormat(sPrevStyleName));
+ bool bInsert(nNumberFormat == -1);
+ SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
+ if (bInsert)
+ GetStyleNumberFormats()->AddStyleNumberFormat(sPrevStyleName, nNumberFormat);
+ }
+ }
+ }
+ if (GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(
+ xMultiServiceFactory->createInstance("com.sun.star.sheet.SheetCellRanges"),
+ uno::UNO_QUERY));
+ }
+ OSL_ENSURE(xSheetCellRanges.is(), "didn't get SheetCellRanges");
+}
+
+void ScXMLImport::SetStyleToRanges(const ScRangeList& rRanges, const OUString* pStyleName,
+ const sal_Int16 nCellType, const OUString* pCurrency)
+{
+ if (!mbImportStyles)
+ return;
+
+ if (sPrevStyleName.isEmpty())
+ {
+ nPrevCellType = nCellType;
+ if (pStyleName)
+ sPrevStyleName = *pStyleName;
+ if (pCurrency)
+ sPrevCurrency = *pCurrency;
+ else if (!sPrevCurrency.isEmpty())
+ sPrevCurrency.clear();
+ }
+ else if ((nCellType != nPrevCellType) ||
+ ((pStyleName && *pStyleName != sPrevStyleName) ||
+ (!pStyleName && !sPrevStyleName.isEmpty())) ||
+ ((pCurrency && *pCurrency != sPrevCurrency) ||
+ (!pCurrency && !sPrevCurrency.isEmpty())))
+ {
+ SetStyleToRanges();
+ nPrevCellType = nCellType;
+ if (pStyleName)
+ sPrevStyleName = *pStyleName;
+ else if(!sPrevStyleName.isEmpty())
+ sPrevStyleName.clear();
+ if (pCurrency)
+ sPrevCurrency = *pCurrency;
+ else if(!sPrevCurrency.isEmpty())
+ sPrevCurrency.clear();
+ }
+
+ if (!xSheetCellRanges.is() && GetModel().is())
+ {
+ uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
+ if (xMultiServiceFactory.is())
+ xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(xMultiServiceFactory->createInstance("com.sun.star.sheet.SheetCellRanges"), uno::UNO_QUERY));
+ OSL_ENSURE(xSheetCellRanges.is(), "didn't get SheetCellRanges");
+
+ }
+ static_cast<ScCellRangesObj*>(xSheetCellRanges.get())->SetNewRanges(rRanges);
+}
+
+bool ScXMLImport::SetNullDateOnUnitConverter()
+{
+ if (!bNullDateSetted)
+ bNullDateSetted = GetMM100UnitConverter().setNullDate(GetModel());
+ OSL_ENSURE(bNullDateSetted, "could not set the null date");
+ return bNullDateSetted;
+}
+
+XMLNumberFormatAttributesExportHelper* ScXMLImport::GetNumberFormatAttributesExportHelper()
+{
+ if (!pNumberFormatAttributesExportHelper)
+ pNumberFormatAttributesExportHelper.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier()));
+ return pNumberFormatAttributesExportHelper.get();
+}
+
+ScMyStyleNumberFormats* ScXMLImport::GetStyleNumberFormats()
+{
+ if (!pStyleNumberFormats)
+ pStyleNumberFormats.reset(new ScMyStyleNumberFormats);
+ return pStyleNumberFormats.get();
+}
+
+void ScXMLImport::SetStylesToRangesFinished()
+{
+ SetStyleToRanges();
+ sPrevStyleName.clear();
+}
+
+// XImporter
+void SAL_CALL ScXMLImport::setTargetDocument( const css::uno::Reference< css::lang::XComponent >& xDoc )
+{
+ ScXMLImport::MutexGuard aGuard(*this);
+ SvXMLImport::setTargetDocument( xDoc );
+
+ uno::Reference<frame::XModel> xModel(xDoc, uno::UNO_QUERY);
+ pDoc = ScXMLConverter::GetScDocument( xModel );
+ OSL_ENSURE( pDoc, "ScXMLImport::setTargetDocument - no ScDocument!" );
+ if (!pDoc)
+ throw lang::IllegalArgumentException();
+
+ if (ScDocShell* pDocSh = static_cast<ScDocShell*>(pDoc->GetDocumentShell()))
+ pDocSh->SetInitialLinkUpdate( pDocSh->GetMedium());
+
+ mpDocImport.reset(new ScDocumentImport(*pDoc));
+ mpComp.reset(new ScCompiler(*pDoc, ScAddress(), formula::FormulaGrammar::GRAM_ODFF));
+
+ uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
+ if (xActionLockable.is())
+ xActionLockable->addActionLock();
+}
+
+// css::xml::sax::XDocumentHandler
+void SAL_CALL ScXMLImport::startDocument()
+{
+ ScXMLImport::MutexGuard aGuard(*this);
+ SvXMLImport::startDocument();
+ if (pDoc && !pDoc->IsImportingXML())
+ {
+ comphelper::getFromUnoTunnel<ScModelObj>(GetModel())->BeforeXMLLoading();
+ bSelfImportingXMLSet = true;
+ }
+
+ // if content and styles are loaded with separate imports,
+ // set bLatinDefaultStyle flag at the start of the content import
+ SvXMLImportFlags nFlags = getImportFlags();
+ if ( ( nFlags & SvXMLImportFlags::CONTENT ) && !( nFlags & SvXMLImportFlags::STYLES ) )
+ ExamineDefaultStyle();
+
+ if (getImportFlags() & SvXMLImportFlags::CONTENT)
+ {
+ if (GetModel().is())
+ {
+ // store initial namespaces, to find the ones that were added from the file later
+ ScSheetSaveData* pSheetData = comphelper::getFromUnoTunnel<ScModelObj>(GetModel())->GetSheetSaveData();
+ const SvXMLNamespaceMap& rNamespaces = GetNamespaceMap();
+ pSheetData->StoreInitialNamespaces(rNamespaces);
+ }
+ }
+
+ uno::Reference< beans::XPropertySet > const xImportInfo( getImportInfo() );
+ uno::Reference< beans::XPropertySetInfo > const xPropertySetInfo(
+ xImportInfo.is() ? xImportInfo->getPropertySetInfo() : nullptr);
+ if (xPropertySetInfo.is())
+ {
+ OUString const sOrganizerMode(
+ "OrganizerMode");
+ if (xPropertySetInfo->hasPropertyByName(sOrganizerMode))
+ {
+ bool bStyleOnly(false);
+ if (xImportInfo->getPropertyValue(sOrganizerMode) >>= bStyleOnly)
+ {
+ bLoadDoc = !bStyleOnly;
+ }
+ }
+ }
+
+ UnlockSolarMutex();
+}
+
+sal_Int32 ScXMLImport::GetRangeType(const OUString& sRangeType)
+{
+ sal_Int32 nRangeType(0);
+ OUStringBuffer sBuffer;
+ sal_Int32 i = 0;
+ while (i <= sRangeType.getLength())
+ {
+ if ((i == sRangeType.getLength()) || (sRangeType[i] == ' '))
+ {
+ OUString sTemp = sBuffer.makeStringAndClear();
+ if (sTemp == "repeat-column")
+ nRangeType |= sheet::NamedRangeFlag::COLUMN_HEADER;
+ else if (sTemp == SC_REPEAT_ROW)
+ nRangeType |= sheet::NamedRangeFlag::ROW_HEADER;
+ else if (sTemp == SC_FILTER)
+ nRangeType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
+ else if (sTemp == SC_PRINT_RANGE)
+ nRangeType |= sheet::NamedRangeFlag::PRINT_AREA;
+ }
+ else if (i < sRangeType.getLength())
+ sBuffer.append(sRangeType[i]);
+ ++i;
+ }
+ return nRangeType;
+}
+
+void ScXMLImport::SetLabelRanges()
+{
+ if (maMyLabelRanges.empty())
+ return;
+
+ uno::Reference <beans::XPropertySet> xPropertySet (GetModel(), uno::UNO_QUERY);
+ if (!xPropertySet.is())
+ return;
+
+ uno::Any aColAny = xPropertySet->getPropertyValue(SC_UNO_COLLABELRNG);
+ uno::Any aRowAny = xPropertySet->getPropertyValue(SC_UNO_ROWLABELRNG);
+
+ uno::Reference< sheet::XLabelRanges > xColRanges;
+ uno::Reference< sheet::XLabelRanges > xRowRanges;
+
+ if ( !(( aColAny >>= xColRanges ) && ( aRowAny >>= xRowRanges )) )
+ return;
+
+ table::CellRangeAddress aLabelRange;
+ table::CellRangeAddress aDataRange;
+
+ for (const auto& rLabelRange : maMyLabelRanges)
+ {
+ sal_Int32 nOffset1(0);
+ sal_Int32 nOffset2(0);
+ FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO;
+
+ assert(pDoc);
+ if (ScRangeStringConverter::GetRangeFromString( aLabelRange, rLabelRange.sLabelRangeStr, *pDoc, eConv, nOffset1 ) &&
+ ScRangeStringConverter::GetRangeFromString( aDataRange, rLabelRange.sDataRangeStr, *pDoc, eConv, nOffset2 ))
+ {
+ if ( rLabelRange.bColumnOrientation )
+ xColRanges->addNew( aLabelRange, aDataRange );
+ else
+ xRowRanges->addNew( aLabelRange, aDataRange );
+ }
+ }
+
+ maMyLabelRanges.clear();
+}
+
+namespace {
+
+class RangeNameInserter
+{
+ ScDocument& mrDoc;
+ ScRangeName& mrRangeName;
+
+public:
+ RangeNameInserter(ScDocument& rDoc, ScRangeName& rRangeName) :
+ mrDoc(rDoc), mrRangeName(rRangeName) {}
+
+ void operator() (const ScMyNamedExpression& p) const
+ {
+ using namespace formula;
+
+ const OUString& aType = p.sRangeType;
+ sal_uInt32 nUnoType = ScXMLImport::GetRangeType(aType);
+
+ ScRangeData::Type nNewType = ScRangeData::Type::Name;
+ if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= ScRangeData::Type::Criteria;
+ if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= ScRangeData::Type::PrintArea;
+ if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= ScRangeData::Type::ColHeader;
+ if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= ScRangeData::Type::RowHeader;
+
+ // Insert a new name.
+ ScAddress aPos;
+ sal_Int32 nOffset = 0;
+ bool bSuccess = ScRangeStringConverter::GetAddressFromString(
+ aPos, p.sBaseCellAddress, mrDoc, FormulaGrammar::CONV_OOO, nOffset);
+
+ if (bSuccess)
+ {
+ OUString aContent = p.sContent;
+ if (!p.bIsExpression)
+ ScXMLConverter::ConvertCellRangeAddress(aContent);
+
+ ScRangeData* pData = new ScRangeData(
+ mrDoc, p.sName, aContent, aPos, nNewType, p.eGrammar);
+ mrRangeName.insert(pData);
+ }
+ }
+};
+
+}
+
+void ScXMLImport::SetNamedRanges()
+{
+ if (m_aMyNamedExpressions.empty())
+ return;
+
+ if (!pDoc)
+ return;
+
+ // Insert the namedRanges
+ ScRangeName* pRangeNames = pDoc->GetRangeName();
+ ::std::for_each(m_aMyNamedExpressions.begin(), m_aMyNamedExpressions.end(), RangeNameInserter(*pDoc, *pRangeNames));
+}
+
+void ScXMLImport::SetSheetNamedRanges()
+{
+ if (!pDoc)
+ return;
+
+ for (auto const& itr : m_SheetNamedExpressions)
+ {
+ const SCTAB nTab = itr.first;
+ ScRangeName* pRangeNames = pDoc->GetRangeName(nTab);
+ if (!pRangeNames)
+ continue;
+
+ const ScMyNamedExpressions& rNames = itr.second;
+ ::std::for_each(rNames.begin(), rNames.end(), RangeNameInserter(*pDoc, *pRangeNames));
+ }
+}
+
+void ScXMLImport::SetStringRefSyntaxIfMissing()
+{
+ if (!pDoc)
+ return;
+
+ ScCalcConfig aCalcConfig = pDoc->GetCalcConfig();
+
+ // Has any string ref syntax been imported?
+ // If not, we need to take action
+ if ( !aCalcConfig.mbHasStringRefSyntax )
+ {
+ aCalcConfig.meStringRefAddressSyntax = formula::FormulaGrammar::CONV_A1_XL_A1;
+ pDoc->SetCalcConfig(aCalcConfig);
+ }
+}
+
+void SAL_CALL ScXMLImport::endDocument()
+{
+ ScXMLImport::MutexGuard aGuard(*this);
+ if (getImportFlags() & SvXMLImportFlags::CONTENT)
+ {
+ if (GetModel().is())
+ {
+ mpDocImport->finalize();
+
+ uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
+ if (xViewDataSupplier.is())
+ {
+ uno::Reference<container::XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData());
+ if (xIndexAccess.is() && xIndexAccess->getCount() > 0)
+ {
+ uno::Sequence< beans::PropertyValue > aSeq;
+ if (xIndexAccess->getByIndex(0) >>= aSeq)
+ {
+ for (const auto& rProp : std::as_const(aSeq))
+ {
+ OUString sName(rProp.Name);
+ if (sName == SC_ACTIVETABLE)
+ {
+ OUString sTabName;
+ if(rProp.Value >>= sTabName)
+ {
+ SCTAB nTab(0);
+ if (pDoc->GetTable(sTabName, nTab))
+ {
+ pDoc->SetVisibleTab(nTab);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ SetLabelRanges();
+ SetNamedRanges();
+ SetSheetNamedRanges();
+ SetStringRefSyntaxIfMissing();
+ if (mpPivotSources)
+ // Process pivot table sources after the named ranges have been set.
+ mpPivotSources->process();
+ }
+ GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
+ if (pDoc)
+ {
+ pDoc->CompileXML();
+
+ // After CompileXML, links must be completely changed to the new URLs.
+ // Otherwise, hasExternalFile for API wouldn't work (#i116940#),
+ // and typing a new formula would create a second link with the same "real" file name.
+ if (pDoc->HasExternalRefManager())
+ pDoc->GetExternalRefManager()->updateAbsAfterLoad();
+ }
+
+ // If the stream contains cells outside of the current limits, the styles can't be re-created,
+ // so stream copying is disabled then.
+ if (pDoc && GetModel().is() && !pDoc->HasRangeOverflow())
+ {
+ // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
+ // in UpdateRowHeights can already clear the flags again)
+ ScSheetSaveData* pSheetData = comphelper::getFromUnoTunnel<ScModelObj>(GetModel())->GetSheetSaveData();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ {
+ pDoc->SetDrawPageSize(nTab);
+ if (!pSheetData->IsSheetBlocked( nTab ))
+ pDoc->SetStreamValid( nTab, true );
+ }
+ }
+
+ // There are rows with optimal height which need to be updated
+ if (pDoc && !maRecalcRowRanges.empty())
+ {
+ bool bLockHeight = pDoc->IsAdjustHeightLocked();
+ if (bLockHeight)
+ {
+ pDoc->UnlockAdjustHeight();
+ }
+
+ ScSizeDeviceProvider aProv(static_cast<ScDocShell*>(pDoc->GetDocumentShell()));
+ ScDocRowHeightUpdater aUpdater(*pDoc, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &maRecalcRowRanges);
+ aUpdater.update();
+
+ if (bLockHeight)
+ {
+ pDoc->LockAdjustHeight();
+ }
+ }
+
+ // Initialize and set position and size of objects
+ if (pDoc && pDoc->GetDrawLayer())
+ {
+ ScDrawLayer* pDrawLayer = pDoc->GetDrawLayer();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
+ {
+ const SdrPage* pPage = pDrawLayer->GetPage(nTab);
+ if (!pPage)
+ continue;
+ bool bNegativePage = pDoc->IsNegativePage(nTab);
+ const size_t nCount = pPage->GetObjCount();
+ for (size_t i = 0; i < nCount; ++i)
+ {
+ SdrObject* pObj = pPage->GetObj(i);
+ ScDrawObjData* pData
+ = ScDrawLayer::GetObjDataTab(pObj, nTab);
+ // Existence of pData means, that it is a cell anchored object
+ if (pData)
+ {
+ // Finish and correct import based on full size (no hidden row/col) and LTR
+ pDrawLayer->InitializeCellAnchoredObj(pObj, *pData);
+ // Adapt object to hidden row/col and RTL
+ pDrawLayer->RecalcPos(pObj, *pData, bNegativePage,
+ true /*bUpdateNoteCaptionPos*/);
+ }
+ }
+ }
+ }
+
+ aTables.FixupOLEs();
+ }
+ if (GetModel().is())
+ {
+ uno::Reference<document::XActionLockable> xActionLockable(GetModel(), uno::UNO_QUERY);
+ if (xActionLockable.is())
+ xActionLockable->removeActionLock();
+ }
+ SvXMLImport::endDocument();
+
+ if (pDoc)
+ {
+ pDoc->BroadcastUno(SfxHint(SfxHintId::ScClearCache));
+ }
+
+ if(pDoc && bSelfImportingXMLSet)
+ comphelper::getFromUnoTunnel<ScModelObj>(GetModel())->AfterXMLLoading();
+}
+
+// XEventListener
+void ScXMLImport::DisposingModel()
+{
+ SvXMLImport::DisposingModel();
+ pDoc = nullptr;
+}
+
+ScXMLImport::MutexGuard::MutexGuard(ScXMLImport& rImport) :
+ mrImport(rImport)
+{
+ mrImport.LockSolarMutex();
+}
+
+ScXMLImport::MutexGuard::~MutexGuard()
+{
+ mrImport.UnlockSolarMutex();
+}
+
+void ScXMLImport::LockSolarMutex()
+{
+ // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked,
+ // so there's no need to allocate (and later delete) the SolarMutexGuard.
+ if (!mbLockSolarMutex)
+ {
+ DBG_TESTSOLARMUTEX();
+ return;
+ }
+
+ if (nSolarMutexLocked == 0)
+ {
+ OSL_ENSURE(!pSolarMutexGuard, "Solar Mutex is locked");
+ pSolarMutexGuard.reset(new SolarMutexGuard());
+ }
+ ++nSolarMutexLocked;
+}
+
+void ScXMLImport::UnlockSolarMutex()
+{
+ if (nSolarMutexLocked > 0)
+ {
+ nSolarMutexLocked--;
+ if (nSolarMutexLocked == 0)
+ {
+ OSL_ENSURE(pSolarMutexGuard, "Solar Mutex is always unlocked");
+ pSolarMutexGuard.reset();
+ }
+ }
+}
+
+sal_Int32 ScXMLImport::GetByteOffset() const
+{
+ sal_Int32 nOffset = -1;
+ uno::Reference<xml::sax::XLocator> xLocator = GetLocator();
+ uno::Reference<io::XSeekable> xSeek( xLocator, uno::UNO_QUERY ); //! should use different interface
+ if ( xSeek.is() )
+ nOffset = static_cast<sal_Int32>(xSeek->getPosition());
+ return nOffset;
+}
+
+void ScXMLImport::SetRangeOverflowType(ErrCode nType)
+{
+ // #i31130# Overflow is stored in the document, because the ScXMLImport object
+ // isn't available in ScXMLImportWrapper::ImportFromComponent when using the
+ // OOo->Oasis transformation.
+
+ if ( pDoc )
+ pDoc->SetRangeOverflowType( nType );
+}
+
+void ScXMLImport::ProgressBarIncrement()
+{
+ nProgressCount++;
+ if (nProgressCount > 100)
+ {
+ GetProgressBarHelper()->Increment(nProgressCount);
+ nProgressCount = 0;
+ }
+}
+
+void ScXMLImport::ExtractFormulaNamespaceGrammar(
+ OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
+ const OUString& rAttrValue, bool bRestrictToExternalNmsp ) const
+{
+ // parse the attribute value, extract namespace ID, literal namespace, and formula string
+ rFormulaNmsp.clear();
+ sal_uInt16 nNsId = GetNamespaceMap().GetKeyByQName(rAttrValue, nullptr, &rFormula, &rFormulaNmsp, SvXMLNamespaceMap::QNameMode::AttrValue);
+
+ // check if we have an ODF formula namespace
+ if( !bRestrictToExternalNmsp ) switch( nNsId )
+ {
+ case XML_NAMESPACE_OOOC:
+ rFormulaNmsp.clear(); // remove namespace string for built-in grammar
+ reGrammar = FormulaGrammar::GRAM_PODF;
+ return;
+ case XML_NAMESPACE_OF:
+ rFormulaNmsp.clear(); // remove namespace string for built-in grammar
+ reGrammar = FormulaGrammar::GRAM_ODFF;
+ return;
+ }
+
+ /* Find default grammar for formulas without namespace. There may be
+ documents in the wild that stored no namespace in ODF 1.0/1.1. Use
+ GRAM_PODF then (old style ODF 1.0/1.1 formulas). The default for ODF
+ 1.2 and later without namespace is GRAM_ODFF (OpenFormula). */
+ FormulaGrammar::Grammar eDefaultGrammar =
+ (GetDocument()->GetStorageGrammar() == FormulaGrammar::GRAM_PODF) ?
+ FormulaGrammar::GRAM_PODF : FormulaGrammar::GRAM_ODFF;
+
+ /* Check if we have no namespace at all. The value XML_NAMESPACE_NONE
+ indicates that there is no colon. If the first character of the
+ attribute value is the equality sign, the value XML_NAMESPACE_UNKNOWN
+ indicates that there is a colon somewhere in the formula string. */
+ if( (nNsId == XML_NAMESPACE_NONE) || ((nNsId == XML_NAMESPACE_UNKNOWN) && (rAttrValue.toChar() == '=')) )
+ {
+ rFormula = rAttrValue; // return entire string as formula
+ reGrammar = eDefaultGrammar;
+ return;
+ }
+
+ /* Check if a namespace URL could be resolved from the attribute value.
+ Use that namespace only, if the Calc document knows an associated
+ external formula parser. This prevents that the range operator in
+ conjunction with defined names is confused as namespaces prefix, e.g.
+ in the expression 'table:A1' where 'table' is a named reference. */
+ if( ((nNsId & XML_NAMESPACE_UNKNOWN_FLAG) != 0) && !rFormulaNmsp.isEmpty() &&
+ GetDocument()->GetFormulaParserPool().hasFormulaParser( rFormulaNmsp ) )
+ {
+ reGrammar = FormulaGrammar::GRAM_EXTERNAL;
+ return;
+ }
+
+ /* All attempts failed (e.g. no namespace and no leading equality sign, or
+ an invalid namespace prefix), continue with the entire attribute value. */
+ rFormula = rAttrValue;
+ rFormulaNmsp.clear(); // remove any namespace string
+ reGrammar = eDefaultGrammar;
+}
+
+FormulaError ScXMLImport::GetFormulaErrorConstant( const OUString& rStr ) const
+{
+ if (!mpComp)
+ return FormulaError::NONE;
+
+ return mpComp->GetErrorConstant(rStr);
+}
+
+ScEditEngineDefaulter* ScXMLImport::GetEditEngine()
+{
+ if (!mpEditEngine)
+ {
+ mpEditEngine.reset(new ScEditEngineDefaulter(pDoc->GetEnginePool()));
+ mpEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
+ mpEditEngine->SetEditTextObjectPool(pDoc->GetEditPool());
+ mpEditEngine->SetUpdateLayout(false);
+ mpEditEngine->EnableUndo(false);
+ mpEditEngine->SetControlWord(mpEditEngine->GetControlWord() & ~EEControlBits::ALLOWBIGOBJS);
+ }
+ return mpEditEngine.get();
+}
+
+const ScXMLEditAttributeMap& ScXMLImport::GetEditAttributeMap() const
+{
+ if (!mpEditAttrMap)
+ mpEditAttrMap.reset(new ScXMLEditAttributeMap);
+ return *mpEditAttrMap;
+}
+
+void ScXMLImport::NotifyContainsEmbeddedFont()
+{
+ if (pDoc)
+ pDoc->SetEmbedFonts(true);
+}
+
+ScMyImpDetectiveOpArray* ScXMLImport::GetDetectiveOpArray()
+{
+ if (!pDetectiveOpArray)
+ pDetectiveOpArray.reset(new ScMyImpDetectiveOpArray());
+ return pDetectiveOpArray.get();
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportFODS(SvStream &rStream)
+{
+ ScDLL::Init();
+
+ SfxObjectShellLock xDocSh(new ScDocShell);
+ xDocSh->DoInitNew();
+ uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
+
+ uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
+ uno::Reference<io::XInputStream> xStream(new ::utl::OSeekableInputStreamWrapper(rStream));
+ uno::Reference<uno::XInterface> xInterface(xMultiServiceFactory->createInstance("com.sun.star.comp.Writer.XmlFilterAdaptor"), uno::UNO_SET_THROW);
+
+ css::uno::Sequence<OUString> aUserData
+ {
+ "com.sun.star.comp.filter.OdfFlatXml",
+ "",
+ "com.sun.star.comp.Calc.XMLOasisImporter",
+ "com.sun.star.comp.Calc.XMLOasisExporter",
+ "",
+ "",
+ "true"
+ };
+ uno::Sequence<beans::PropertyValue> aAdaptorArgs(comphelper::InitPropertySequence(
+ {
+ { "UserData", uno::Any(aUserData) },
+ }));
+ css::uno::Sequence<uno::Any> aOuterArgs{ uno::Any(aAdaptorArgs) };
+
+ uno::Reference<lang::XInitialization> xInit(xInterface, uno::UNO_QUERY_THROW);
+ xInit->initialize(aOuterArgs);
+
+ uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
+ {
+ { "InputStream", uno::Any(xStream) },
+ { "URL", uno::Any(OUString("private:stream")) },
+ }));
+ xImporter->setTargetDocument(xModel);
+
+ uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW);
+ //SetLoading hack because the document properties will be re-initted
+ //by the xml filter and during the init, while it's considered uninitialized,
+ //setting a property will inform the document it's modified, which attempts
+ //to update the properties, which throws cause the properties are uninitialized
+ xDocSh->SetLoading(SfxLoadedFlags::NONE);
+ bool ret = xFilter->filter(aArgs);
+ xDocSh->SetLoading(SfxLoadedFlags::ALL);
+
+ xDocSh->DoClose();
+
+ return ret;
+}
+
+extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportXLSX(SvStream &rStream)
+{
+ ScDLL::Init();
+
+ SfxObjectShellLock xDocSh(new ScDocShell);
+ xDocSh->DoInitNew();
+ uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
+
+ uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
+ uno::Reference<io::XInputStream> xStream(new utl::OSeekableInputStreamWrapper(rStream));
+
+ uno::Reference<document::XFilter> xFilter(xMultiServiceFactory->createInstance("com.sun.star.comp.oox.xls.ExcelFilter"), uno::UNO_QUERY_THROW);
+
+ uno::Reference<document::XImporter> xImporter(xFilter, uno::UNO_QUERY_THROW);
+ uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
+ {
+ { "InputStream", uno::Any(xStream) },
+ { "InputMode", uno::Any(true) },
+ }));
+ xImporter->setTargetDocument(xModel);
+
+ //SetLoading hack because the document properties will be re-initted
+ //by the xml filter and during the init, while it's considered uninitialized,
+ //setting a property will inform the document it's modified, which attempts
+ //to update the properties, which throws cause the properties are uninitialized
+ xDocSh->SetLoading(SfxLoadedFlags::NONE);
+ bool ret = false;
+ try
+ {
+ ret = xFilter->filter(aArgs);
+ }
+ catch (const css::io::IOException&)
+ {
+ }
+ catch (const css::lang::WrappedTargetRuntimeException&)
+ {
+ }
+ xDocSh->SetLoading(SfxLoadedFlags::ALL);
+
+ xDocSh->DoClose();
+
+ return ret;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */