tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / filter / xml / xmlimprt.cxx
blobd992fd2c5f843a123eb02e8a58129ab4fe39fb28
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
22 #include <osl/diagnose.h>
24 #include <svl/numformat.hxx>
26 #include <xmloff/namespacemap.hxx>
27 #include <xmloff/xmlnamespace.hxx>
28 #include <xmloff/xmlictxt.hxx>
29 #include <xmloff/xmlmetai.hxx>
30 #include <sfx2/objsh.hxx>
31 #include <unotools/streamwrap.hxx>
32 #include <unotools/tempfile.hxx>
33 #include <xmloff/xmlscripti.hxx>
34 #include <xmloff/XMLFontStylesContext.hxx>
35 #include <xmloff/DocumentSettingsContext.hxx>
36 #include <xmloff/xmluconv.hxx>
37 #include <xmloff/numehelp.hxx>
38 #include <xmloff/xmltoken.hxx>
39 #include <xmloff/xmlerror.hxx>
40 #include <xmloff/ProgressBarHelper.hxx>
41 #include <svx/svdpage.hxx>
43 #include <svl/languageoptions.hxx>
44 #include <editeng/editstat.hxx>
45 #include <formula/errorcodes.hxx>
46 #include <vcl/svapp.hxx>
48 #include <appluno.hxx>
49 #include "xmlimprt.hxx"
50 #include "importcontext.hxx"
51 #include <document.hxx>
52 #include <docsh.hxx>
53 #include <docuno.hxx>
54 #include "xmlbodyi.hxx"
55 #include "xmlstyli.hxx"
56 #include <ViewSettingsSequenceDefines.hxx>
57 #include <userdat.hxx>
59 #include <compiler.hxx>
61 #include "XMLConverter.hxx"
62 #include "XMLDetectiveContext.hxx"
63 #include "XMLTableShapeImportHelper.hxx"
64 #include "XMLChangeTrackingImportHelper.hxx"
65 #include <chgviset.hxx>
66 #include "XMLStylesImportHelper.hxx"
67 #include <sheetdata.hxx>
68 #include <rangeutl.hxx>
69 #include <formulaparserpool.hxx>
70 #include <externalrefmgr.hxx>
71 #include <editutil.hxx>
72 #include "editattributemap.hxx"
73 #include <documentimport.hxx>
74 #include "pivotsource.hxx"
75 #include <unonames.hxx>
76 #include <numformat.hxx>
77 #include <sizedev.hxx>
78 #include <scdll.hxx>
79 #include "xmlstyle.hxx"
81 #include <comphelper/base64.hxx>
82 #include <comphelper/extract.hxx>
83 #include <comphelper/propertysequence.hxx>
84 #include <comphelper/processfactory.hxx>
86 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
87 #include <com/sun/star/document/XExporter.hpp>
88 #include <com/sun/star/frame/XModel.hpp>
89 #include <com/sun/star/io/IOException.hpp>
90 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
91 #include <com/sun/star/document/XActionLockable.hpp>
92 #include <com/sun/star/util/MalformedNumberFormatException.hpp>
93 #include <com/sun/star/util/NumberFormat.hpp>
94 #include <com/sun/star/util/XNumberFormatTypes.hpp>
95 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
96 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
97 #include <com/sun/star/sheet/XLabelRanges.hpp>
98 #include <com/sun/star/io/XSeekable.hpp>
99 #include <com/sun/star/beans/XPropertySet.hpp>
100 #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
101 #include <cellsuno.hxx>
103 #include <memory>
104 #include <utility>
106 constexpr OUString SC_LOCALE = u"Locale"_ustr;
107 constexpr OUStringLiteral SC_CURRENCYSYMBOL = u"CurrencySymbol";
108 constexpr OUStringLiteral SC_REPEAT_ROW = u"repeat-row";
109 constexpr OUStringLiteral SC_FILTER = u"filter";
110 constexpr OUStringLiteral SC_PRINT_RANGE = u"print-range";
111 constexpr OUStringLiteral SC_HIDDEN = u"hidden";
113 using namespace com::sun::star;
114 using namespace ::xmloff::token;
115 using namespace ::formula;
117 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
118 Calc_XMLOasisImporter_get_implementation(
119 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
121 return cppu::acquire(
122 new ScXMLImport(
123 context,
124 u"com.sun.star.comp.Calc.XMLOasisImporter"_ustr,
125 SvXMLImportFlags::ALL,
126 { u"com.sun.star.comp.Calc.XMLOasisImporter"_ustr } ));
129 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
130 Calc_XMLOasisMetaImporter_get_implementation(
131 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
133 return cppu::acquire(
134 new ScXMLImport(
135 context,
136 u"com.sun.star.comp.Calc.XMLOasisMetaImporter"_ustr,
137 SvXMLImportFlags::META,
138 { u"com.sun.star.comp.Calc.XMLOasisMetaImporter"_ustr } ));
141 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
142 Calc_XMLOasisStylesImporter_get_implementation(
143 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
145 return cppu::acquire(
146 new ScXMLImport(
147 context,
148 u"com.sun.star.comp.Calc.XMLOasisStylesImporter"_ustr,
149 SvXMLImportFlags::STYLES|SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::MASTERSTYLES|SvXMLImportFlags::FONTDECLS,
150 { u"com.sun.star.comp.Calc.XMLOasisStylesImporter"_ustr } ));
153 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
154 Calc_XMLOasisContentImporter_get_implementation(
155 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
157 return cppu::acquire(new ScXMLImport(
158 context,
159 u"com.sun.star.comp.Calc.XMLOasisContentImporter"_ustr,
160 SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SCRIPTS|SvXMLImportFlags::FONTDECLS,
161 uno::Sequence< OUString > { u"com.sun.star.comp.Calc.XMLOasisContentImporter"_ustr }));
165 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
166 Calc_XMLOasisSettingsImporter_get_implementation(
167 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
169 return cppu::acquire(
170 new ScXMLImport(
171 context,
172 u"com.sun.star.comp.Calc.XMLOasisSettingsImporter"_ustr,
173 SvXMLImportFlags::SETTINGS,
174 { u"com.sun.star.comp.Calc.XMLOasisSettingsImporter"_ustr } ));
177 namespace {
179 // NB: virtually inherit so we can multiply inherit properly
180 // in ScXMLFlatDocContext_Impl
181 class ScXMLDocContext_Impl : public virtual SvXMLImportContext
183 protected:
184 ScXMLImport& GetScImport() { return static_cast<ScXMLImport&>(GetImport()); }
186 public:
187 ScXMLDocContext_Impl( ScXMLImport& rImport );
189 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
190 createFastChildContext( sal_Int32 nElement,
191 const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
196 ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport ) :
197 SvXMLImportContext( rImport )
201 namespace {
203 // context for flat file xml format
204 class ScXMLFlatDocContext_Impl
205 : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext
207 public:
209 ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
210 const uno::Reference<document::XDocumentProperties>& i_xDocProps);
212 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
213 createFastChildContext( sal_Int32 nElement,
214 const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
219 ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
220 const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
221 SvXMLImportContext(i_rImport),
222 ScXMLDocContext_Impl(i_rImport),
223 SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
227 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
228 ScXMLFlatDocContext_Impl::createFastChildContext( sal_Int32 nElement,
229 const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
231 if ( nElement == XML_ELEMENT( OFFICE, XML_META ) )
232 return SvXMLMetaDocumentContext::createFastChildContext( nElement, xAttrList );
233 else
234 return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList );
237 namespace {
239 class ScXMLBodyContext_Impl : public ScXMLImportContext
241 public:
242 ScXMLBodyContext_Impl( ScXMLImport& rImport );
244 virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
245 createFastChildContext( sal_Int32 nElement,
246 const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
251 ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport ) :
252 ScXMLImportContext( rImport )
256 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
257 ScXMLBodyContext_Impl::createFastChildContext( sal_Int32 /*nElement*/,
258 const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
260 sax_fastparser::FastAttributeList *pAttribList =
261 &sax_fastparser::castToFastAttributeList( xAttrList );
262 return GetScImport().CreateBodyContext( pAttribList );
265 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
266 ScXMLDocContext_Impl::createFastChildContext( sal_Int32 nElement,
267 const uno::Reference< xml::sax::XFastAttributeList > & /*xAttrList*/ )
269 SvXMLImportContext *pContext(nullptr);
271 switch( nElement )
273 case XML_ELEMENT( OFFICE, XML_BODY ):
274 if (GetScImport().getImportFlags() & SvXMLImportFlags::CONTENT)
275 pContext = new ScXMLBodyContext_Impl( GetScImport() );
276 break;
277 case XML_ELEMENT( OFFICE, XML_SCRIPTS ):
278 if (GetScImport().getImportFlags() & SvXMLImportFlags::SCRIPTS)
279 pContext = GetScImport().CreateScriptContext();
280 break;
281 case XML_ELEMENT( OFFICE, XML_SETTINGS ):
282 if (GetScImport().getImportFlags() & SvXMLImportFlags::SETTINGS)
283 pContext = new XMLDocumentSettingsContext(GetScImport());
284 break;
285 case XML_ELEMENT(OFFICE, XML_STYLES):
286 if (GetScImport().getImportFlags() & SvXMLImportFlags::STYLES)
287 pContext = GetScImport().CreateStylesContext( false);
288 break;
289 case XML_ELEMENT(OFFICE, XML_AUTOMATIC_STYLES):
290 if (GetScImport().getImportFlags() & SvXMLImportFlags::AUTOSTYLES)
291 pContext = GetScImport().CreateStylesContext( true);
292 break;
293 case XML_ELEMENT(OFFICE, XML_FONT_FACE_DECLS):
294 if (GetScImport().getImportFlags() & SvXMLImportFlags::FONTDECLS)
295 pContext = GetScImport().CreateFontDeclsContext();
296 break;
297 case XML_ELEMENT(OFFICE, XML_MASTER_STYLES):
298 if (GetScImport().getImportFlags() & SvXMLImportFlags::MASTERSTYLES)
299 pContext = new ScXMLMasterStylesContext( GetImport() );
300 break;
301 case XML_ELEMENT(OFFICE, XML_META):
302 SAL_INFO("sc", "XML_ELEMENT(OFFICE, XML_META): should not have come here, maybe document is invalid?");
303 break;
306 return pContext;
310 void ScXMLImport::SetPostProcessData( sc::ImportPostProcessData* p )
312 mpPostProcessData = p;
315 sc::PivotTableSources& ScXMLImport::GetPivotTableSources()
317 if (!mpPivotSources)
318 mpPivotSources.reset(new sc::PivotTableSources);
320 return *mpPivotSources;
323 SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement,
324 const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
326 SvXMLImportContext *pContext = nullptr;
328 switch( nElement )
330 case XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ):
331 case XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ):
332 case XML_ELEMENT( OFFICE, XML_DOCUMENT_SETTINGS ):
333 pContext = new ScXMLDocContext_Impl( *this );
334 break;
336 case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
337 pContext = CreateMetaContext(nElement);
338 break;
340 case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
342 // flat OpenDocument file format
343 pContext = new ScXMLFlatDocContext_Impl( *this, GetScModel()->getDocumentProperties());
344 break;
349 return pContext;
352 ScXMLImport::ScXMLImport(
353 const css::uno::Reference< css::uno::XComponentContext >& rContext,
354 OUString const & implementationName, SvXMLImportFlags nImportFlag,
355 const css::uno::Sequence< OUString > & sSupportedServiceNames)
356 : SvXMLImport( rContext, implementationName, nImportFlag, sSupportedServiceNames ),
357 mpDoc( nullptr ),
358 mpPostProcessData(nullptr),
359 aTables(*this),
360 nSolarMutexLocked(0),
361 nProgressCount(0),
362 nPrevCellType(0),
363 bLoadDoc( true ),
364 bNullDateSetted(false),
365 bSelfImportingXMLSet(false),
366 mbLockSolarMutex(true),
367 mbImportStyles(true),
368 mbHasNewCondFormatData(false)
370 pStylesImportHelper.reset(new ScMyStylesImportHelper(*this));
372 xScPropHdlFactory = new XMLScPropHdlFactory;
373 xCellStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScCellStylesProperties, xScPropHdlFactory, false);
374 xColumnStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScColumnStylesProperties, xScPropHdlFactory, false);
375 xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScRowStylesImportProperties, xScPropHdlFactory, false);
376 xTableStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScTableStylesImportProperties, xScPropHdlFactory, false);
378 // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
379 GetNamespaceMap().Add(
380 GetXMLToken( XML_NP_PRESENTATION ),
381 GetXMLToken( XML_N_PRESENTATION ),
382 XML_NAMESPACE_PRESENTATION );
385 ScXMLImport::~ScXMLImport() noexcept
387 pChangeTrackingImportHelper.reset();
388 pNumberFormatAttributesExportHelper.reset();
389 pStyleNumberFormats.reset();
390 pStylesImportHelper.reset();
392 m_aMyNamedExpressions.clear();
393 maMyLabelRanges.clear();
394 maValidations.clear();
395 pDetectiveOpArray.reset();
397 //call SvXMLImport dtor contents before deleting pSolarMutexGuard
398 cleanup();
400 moSolarMutexGuard.reset();
403 void ScXMLImport::initialize( const css::uno::Sequence<css::uno::Any>& aArguments )
405 SvXMLImport::initialize(aArguments);
407 uno::Reference<beans::XPropertySet> xInfoSet = getImportInfo();
408 if (!xInfoSet.is())
409 return;
411 uno::Reference<beans::XPropertySetInfo> xInfoSetInfo = xInfoSet->getPropertySetInfo();
412 if (!xInfoSetInfo.is())
413 return;
415 if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_LOCK_SOLAR_MUTEX))
416 xInfoSet->getPropertyValue(SC_UNO_ODS_LOCK_SOLAR_MUTEX) >>= mbLockSolarMutex;
418 if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_IMPORT_STYLES))
419 xInfoSet->getPropertyValue(SC_UNO_ODS_IMPORT_STYLES) >>= mbImportStyles;
422 SvXMLImportContext *ScXMLImport::CreateFontDeclsContext()
424 XMLFontStylesContext *pFSContext = new XMLFontStylesContext(
425 *this, osl_getThreadTextEncoding());
426 SetFontDecls(pFSContext);
427 SvXMLImportContext* pContext = pFSContext;
428 return pContext;
431 SvXMLImportContext *ScXMLImport::CreateStylesContext( bool bIsAutoStyle )
433 SvXMLImportContext* pContext = new XMLTableStylesContext(
434 *this, bIsAutoStyle);
436 if (bIsAutoStyle)
437 SetAutoStyles(static_cast<SvXMLStylesContext*>(pContext));
438 else
439 SetStyles(static_cast<SvXMLStylesContext*>(pContext));
441 return pContext;
444 SvXMLImportContext *ScXMLImport::CreateBodyContext(const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList)
446 return new ScXMLBodyContext(*this, rAttrList);
449 SvXMLImportContext *ScXMLImport::CreateMetaContext(
450 const sal_Int32 /*nElement*/ )
452 SvXMLImportContext* pContext = nullptr;
454 if (getImportFlags() & SvXMLImportFlags::META)
456 uno::Reference<document::XDocumentProperties> const xDocProps(
457 (IsStylesOnlyMode()) ? nullptr : GetScModel()->getDocumentProperties());
458 pContext = new SvXMLMetaDocumentContext(*this, xDocProps);
461 return pContext;
464 SvXMLImportContext *ScXMLImport::CreateScriptContext()
466 SvXMLImportContext* pContext = nullptr;
468 if( !(IsStylesOnlyMode()) )
470 pContext = new XMLScriptContext( *this, GetModel() );
473 return pContext;
476 void ScXMLImport::SetStatistics(const uno::Sequence<beans::NamedValue> & i_rStats)
478 static const char* s_stats[] =
479 { "TableCount", "CellCount", "ObjectCount", nullptr };
481 SvXMLImport::SetStatistics(i_rStats);
483 sal_uInt64 nCount(0);
484 for (const auto& rStat : i_rStats) {
485 for (const char** pStat = s_stats; *pStat != nullptr; ++pStat) {
486 if (rStat.Name.equalsAscii(*pStat)) {
487 sal_Int32 val = 0;
488 if (rStat.Value >>= val) {
489 nCount += val;
490 } else {
491 OSL_FAIL("ScXMLImport::SetStatistics: invalid entry");
497 if (nCount)
499 GetProgressBarHelper()->SetReference(nCount);
500 GetProgressBarHelper()->SetValue(0);
504 ScDocumentImport& ScXMLImport::GetDoc()
506 return *mpDocImport;
509 sal_Int16 ScXMLImport::GetCellType(const char* rStrValue, const sal_Int32 nStrLength)
511 sal_Int16 nCellType = util::NumberFormat::UNDEFINED;
512 if (rStrValue != nullptr)
514 switch (rStrValue[0])
516 case 'b':
517 if (nStrLength == 7 && !strcmp(rStrValue, "boolean"))
518 nCellType = util::NumberFormat::LOGICAL;
519 break;
520 case 'c':
521 if (nStrLength == 8 && !strcmp(rStrValue, "currency"))
522 nCellType = util::NumberFormat::CURRENCY;
523 break;
524 case 'd':
525 if (nStrLength == 4 && !strcmp(rStrValue, "date"))
526 nCellType = util::NumberFormat::DATETIME;
527 break;
528 case 'f':
529 if (nStrLength == 5 && !strcmp(rStrValue, "float"))
530 nCellType = util::NumberFormat::NUMBER;
531 break;
532 case 'p':
533 if (nStrLength == 10 && !strcmp(rStrValue, "percentage"))
534 nCellType = util::NumberFormat::PERCENT;
535 break;
536 case 's':
537 if (nStrLength == 6 && !strcmp(rStrValue, "string"))
538 nCellType = util::NumberFormat::TEXT;
539 break;
540 case 't':
541 if (nStrLength == 4 && !strcmp(rStrValue, "time"))
542 nCellType = util::NumberFormat::TIME;
543 break;
547 return nCellType;
550 XMLShapeImportHelper* ScXMLImport::CreateShapeImport()
552 return new XMLTableShapeImportHelper(*this);
555 bool ScXMLImport::GetValidation(const OUString& sName, ScMyImportValidation& aValidation)
557 auto aItr = std::find_if(maValidations.begin(), maValidations.end(),
558 [&sName](const ScMyImportValidation& rValidation) { return rValidation.sName == sName; });
559 if (aItr != maValidations.end())
561 // source position must be set as string,
562 // so sBaseCellAddress no longer has to be converted here
563 aValidation = *aItr;
564 return true;
566 return false;
569 void ScXMLImport::AddNamedExpression(SCTAB nTab, ScMyNamedExpression aNamedExp)
571 SheetNamedExpMap::iterator itr = m_SheetNamedExpressions.find(nTab);
572 if (itr == m_SheetNamedExpressions.end())
574 // No chain exists for this sheet. Create one.
575 ::std::pair<SheetNamedExpMap::iterator, bool> r =
576 m_SheetNamedExpressions.insert(std::make_pair(nTab, ScMyNamedExpressions()));
577 if (!r.second)
578 // insertion failed.
579 return;
581 itr = r.first;
583 ScMyNamedExpressions& r = itr->second;
584 r.push_back(std::move(aNamedExp));
587 ScXMLChangeTrackingImportHelper* ScXMLImport::GetChangeTrackingImportHelper()
589 if (!pChangeTrackingImportHelper)
590 pChangeTrackingImportHelper.reset(new ScXMLChangeTrackingImportHelper());
591 return pChangeTrackingImportHelper.get();
594 void ScXMLImport::InsertStyles()
596 GetStyles()->CopyStylesToDoc(true);
598 // if content is going to be loaded with the same import, set bLatinDefaultStyle flag now
599 if ( getImportFlags() & SvXMLImportFlags::CONTENT )
600 ExamineDefaultStyle();
603 void ScXMLImport::ExamineDefaultStyle()
605 if (mpDoc)
607 // #i62435# after inserting the styles, check if the default style has a latin-script-only
608 // number format (then, value cells can be pre-initialized with western script type)
610 const ScPatternAttr& rDefPattern(mpDoc->getCellAttributeHelper().getDefaultCellAttribute());
611 if (sc::NumFmtUtil::isLatinScript(rDefPattern, *mpDoc))
612 mpDocImport->setDefaultNumericScript(SvtScriptType::LATIN);
616 void ScXMLImport::SetChangeTrackingViewSettings(const css::uno::Sequence<css::beans::PropertyValue>& rChangeProps)
618 if (!mpDoc)
619 return;
621 if (!rChangeProps.hasElements())
622 return;
624 ScXMLImport::MutexGuard aGuard(*this);
625 sal_Int16 nTemp16(0);
626 ScChangeViewSettings aViewSettings;
627 for (const auto& rChangeProp : rChangeProps)
629 OUString sName(rChangeProp.Name);
630 if (sName == "ShowChanges")
631 aViewSettings.SetShowChanges(::cppu::any2bool(rChangeProp.Value));
632 else if (sName == "ShowAcceptedChanges")
633 aViewSettings.SetShowAccepted(::cppu::any2bool(rChangeProp.Value));
634 else if (sName == "ShowRejectedChanges")
635 aViewSettings.SetShowRejected(::cppu::any2bool(rChangeProp.Value));
636 else if (sName == "ShowChangesByDatetime")
637 aViewSettings.SetHasDate(::cppu::any2bool(rChangeProp.Value));
638 else if (sName == "ShowChangesByDatetimeMode")
640 if (rChangeProp.Value >>= nTemp16)
641 aViewSettings.SetTheDateMode(static_cast<SvxRedlinDateMode>(nTemp16));
643 else if (sName == "ShowChangesByDatetimeFirstDatetime")
645 util::DateTime aDateTime;
646 if (rChangeProp.Value >>= aDateTime)
648 aViewSettings.SetTheFirstDateTime(::DateTime(aDateTime));
651 else if (sName == "ShowChangesByDatetimeSecondDatetime")
653 util::DateTime aDateTime;
654 if (rChangeProp.Value >>= aDateTime)
656 aViewSettings.SetTheLastDateTime(::DateTime(aDateTime));
659 else if (sName == "ShowChangesByAuthor")
660 aViewSettings.SetHasAuthor(::cppu::any2bool(rChangeProp.Value));
661 else if (sName == "ShowChangesByAuthorName")
663 OUString sOUName;
664 if (rChangeProp.Value >>= sOUName)
666 aViewSettings.SetTheAuthorToShow(sOUName);
669 else if (sName == "ShowChangesByComment")
670 aViewSettings.SetHasComment(::cppu::any2bool(rChangeProp.Value));
671 else if (sName == "ShowChangesByCommentText")
673 OUString sOUComment;
674 if (rChangeProp.Value >>= sOUComment)
676 aViewSettings.SetTheComment(sOUComment);
679 else if (sName == "ShowChangesByRanges")
680 aViewSettings.SetHasRange(::cppu::any2bool(rChangeProp.Value));
681 else if (sName == "ShowChangesByRangesList")
683 OUString sRanges;
684 if ((rChangeProp.Value >>= sRanges) && !sRanges.isEmpty())
686 ScRangeList aRangeList;
687 ScRangeStringConverter::GetRangeListFromString(
688 aRangeList, sRanges, *mpDoc, FormulaGrammar::CONV_OOO);
689 aViewSettings.SetTheRangeList(aRangeList);
693 mpDoc->SetChangeViewSettings(aViewSettings);
696 void ScXMLImport::SetViewSettings(const uno::Sequence<beans::PropertyValue>& aViewProps)
698 sal_Int32 nHeight(0);
699 sal_Int32 nLeft(0);
700 sal_Int32 nTop(0);
701 sal_Int32 nWidth(0);
702 for (const auto& rViewProp : aViewProps)
704 OUString sName(rViewProp.Name);
705 if (sName == "VisibleAreaHeight")
706 rViewProp.Value >>= nHeight;
707 else if (sName == "VisibleAreaLeft")
708 rViewProp.Value >>= nLeft;
709 else if (sName == "VisibleAreaTop")
710 rViewProp.Value >>= nTop;
711 else if (sName == "VisibleAreaWidth")
712 rViewProp.Value >>= nWidth;
713 else if (sName == "TrackedChangesViewSettings")
715 uno::Sequence<beans::PropertyValue> aChangeProps;
716 if(rViewProp.Value >>= aChangeProps)
717 SetChangeTrackingViewSettings(aChangeProps);
720 if (!(nHeight && nWidth && GetModel().is()))
721 return;
723 ScModelObj* pDocObj( GetScModel() );
724 if (!pDocObj)
725 return;
727 SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
728 if (pEmbeddedObj)
730 tools::Rectangle aRect{ nLeft, nTop };
731 aRect.setWidth( nWidth );
732 aRect.setHeight( nHeight );
733 pEmbeddedObj->SetVisArea(aRect);
737 void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyValue>& aConfigProps)
739 rtl::Reference<ScModelObj> xMultiServiceFactory(GetScModel());
740 if (!xMultiServiceFactory.is())
741 return;
743 sal_Int32 nCount(aConfigProps.getLength());
744 css::uno::Sequence<css::beans::PropertyValue> aFilteredProps(nCount);
745 auto pFilteredProps = aFilteredProps.getArray();
746 sal_Int32 nFilteredPropsLen = 0;
747 for (sal_Int32 i = nCount - 1; i >= 0; --i)
749 if (aConfigProps[i].Name == "TrackedChangesProtectionKey")
751 OUString sKey;
752 if (aConfigProps[i].Value >>= sKey)
754 uno::Sequence<sal_Int8> aPass;
755 ::comphelper::Base64::decode(aPass, sKey);
756 if (mpDoc && aPass.hasElements())
758 if (mpDoc->GetChangeTrack())
759 mpDoc->GetChangeTrack()->SetProtection(aPass);
760 else
762 std::set<OUString> aUsers;
763 std::unique_ptr<ScChangeTrack> pTrack( new ScChangeTrack(*mpDoc, std::move(aUsers)) );
764 pTrack->SetProtection(aPass);
765 mpDoc->SetChangeTrack(std::move(pTrack));
770 // store the following items for later use (after document is loaded)
771 else if ((aConfigProps[i].Name == "VBACompatibilityMode") || (aConfigProps[i].Name == "ScriptConfiguration"))
773 uno::Reference< beans::XPropertySet > xImportInfo = getImportInfo();
774 if (xImportInfo.is())
776 uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo();
777 if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName(aConfigProps[i].Name))
778 xImportInfo->setPropertyValue( aConfigProps[i].Name, aConfigProps[i].Value );
781 if (aConfigProps[i].Name != "LinkUpdateMode")
783 pFilteredProps[nFilteredPropsLen++] = aConfigProps[i];
786 aFilteredProps.realloc(nFilteredPropsLen);
787 uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance(u"com.sun.star.comp.SpreadsheetSettings"_ustr);
788 uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY);
789 if (xProperties.is())
790 SvXMLUnitConverter::convertPropertySet(xProperties, aFilteredProps);
793 sal_Int32 ScXMLImport::SetCurrencySymbol(const sal_Int32 nKey, std::u16string_view rCurrency)
795 uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
796 if (xNumberFormatsSupplier.is())
798 uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
799 if (xLocalNumberFormats.is())
801 OUString sFormatString;
804 uno::Reference <beans::XPropertySet> xProperties(xLocalNumberFormats->getByKey(nKey));
805 if (xProperties.is())
807 lang::Locale aLocale;
808 if (xProperties->getPropertyValue(SC_LOCALE) >>= aLocale)
811 ScXMLImport::MutexGuard aGuard(*this);
812 LocaleDataWrapper aLocaleData( comphelper::getProcessComponentContext(), LanguageTag( aLocale) );
813 sFormatString = "#" +
814 aLocaleData.getNumThousandSep() +
815 "##0" +
816 aLocaleData.getNumDecimalSep() +
817 "00 [$" +
818 rCurrency +
819 "]";
821 sal_Int32 nNewKey = xLocalNumberFormats->queryKey(sFormatString, aLocale, true);
822 if (nNewKey == -1)
823 nNewKey = xLocalNumberFormats->addNew(sFormatString, aLocale);
824 return nNewKey;
828 catch ( const util::MalformedNumberFormatException& rException )
830 OUString sErrorMessage ="Error in Formatstring " +
831 sFormatString + " at position " +
832 OUString::number(rException.CheckPos);
833 uno::Sequence<OUString> aSeq { sErrorMessage };
834 uno::Reference<xml::sax::XLocator> xLocator;
835 SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rException.Message, xLocator);
839 return nKey;
842 bool ScXMLImport::IsCurrencySymbol(const sal_Int32 nNumberFormat, std::u16string_view sCurrentCurrency, std::u16string_view sBankSymbol)
844 uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
845 if (xNumberFormatsSupplier.is())
847 uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
848 if (xLocalNumberFormats.is())
852 uno::Reference <beans::XPropertySet> xNumberPropertySet(xLocalNumberFormats->getByKey(nNumberFormat));
853 if (xNumberPropertySet.is())
855 OUString sTemp;
856 if ( xNumberPropertySet->getPropertyValue(SC_CURRENCYSYMBOL) >>= sTemp)
858 if (sCurrentCurrency == sTemp)
859 return true;
860 // A release that saved an unknown currency may have
861 // saved the currency symbol of the number format
862 // instead of an ISO code bank symbol. In another
863 // release we may have a match for that. In this case
864 // sCurrentCurrency is the ISO code obtained through
865 // XMLNumberFormatAttributesExportHelper::GetCellType()
866 // and sBankSymbol is the currency symbol.
867 if (sCurrentCurrency.size() == 3 && sBankSymbol == sTemp)
868 return true;
869 // #i61657# This may be a legacy currency symbol that changed in the meantime.
870 if (SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sCurrentCurrency, sBankSymbol) != nullptr)
871 return true;
872 // In the rare case that sCurrentCurrency is not the
873 // currency symbol, but a matching ISO code
874 // abbreviation instead that was obtained through
875 // XMLNumberFormatAttributesExportHelper::GetCellType(),
876 // check with the number format's symbol. This happens,
877 // for example, in the es_BO locale, where a legacy
878 // B$,BOB matched B$->BOP, which leads to
879 // sCurrentCurrency being BOP, and the previous call
880 // with BOP,BOB didn't find an entry, but B$,BOB will.
881 return SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sTemp, sBankSymbol) != nullptr;
885 catch ( uno::Exception& )
887 OSL_FAIL("Numberformat not found");
891 return false;
894 void ScXMLImport::SetType(const uno::Reference <beans::XPropertySet>& rProperties,
895 sal_Int32& rNumberFormat,
896 const sal_Int16 nCellType,
897 std::u16string_view rCurrency)
899 if (!mbImportStyles)
900 return;
902 if ((nCellType == util::NumberFormat::TEXT) || (nCellType == util::NumberFormat::UNDEFINED))
903 return;
905 if (rNumberFormat == -1)
906 rProperties->getPropertyValue( SC_UNONAME_NUMFMT ) >>= rNumberFormat;
907 OSL_ENSURE(rNumberFormat != -1, "no NumberFormat");
908 bool bIsStandard;
909 // sCurrentCurrency may be the ISO code abbreviation if the currency
910 // symbol matches such, or if no match found the symbol itself!
911 OUString sCurrentCurrency;
912 sal_Int32 nCurrentCellType(
913 GetNumberFormatAttributesExportHelper()->GetCellType(
914 rNumberFormat, sCurrentCurrency, bIsStandard) & ~util::NumberFormat::DEFINED);
915 // If the (numeric) cell type (number, currency, date, time, boolean)
916 // is different from the format type then for some combinations we may
917 // have to apply a format, e.g. in case the generator deduced format
918 // from type and did not apply a format but we don't keep a dedicated
919 // type internally. Specifically this is necessary if the cell type is
920 // not number but the format type is (i.e. General). Currency cells
921 // need extra attention, see calls of ScXMLImport::IsCurrencySymbol()
922 // and description within there and ScXMLImport::SetCurrencySymbol().
923 if ((nCellType != nCurrentCellType) &&
924 (nCellType != util::NumberFormat::NUMBER) &&
925 (bIsStandard || (nCellType == util::NumberFormat::CURRENCY)))
927 if (!xNumberFormats.is())
929 uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
930 if (xNumberFormatsSupplier.is())
931 xNumberFormats.set(xNumberFormatsSupplier->getNumberFormats());
933 if (xNumberFormats.is())
937 uno::Reference < beans::XPropertySet> xNumberFormatProperties(xNumberFormats->getByKey(rNumberFormat));
938 if (xNumberFormatProperties.is())
940 if (nCellType != util::NumberFormat::CURRENCY)
942 lang::Locale aLocale;
943 if ( xNumberFormatProperties->getPropertyValue(SC_LOCALE) >>= aLocale )
945 if (!xNumberFormatTypes.is())
946 xNumberFormatTypes.set(uno::Reference <util::XNumberFormatTypes>(xNumberFormats, uno::UNO_QUERY));
947 rProperties->setPropertyValue( SC_UNONAME_NUMFMT, uno::Any(xNumberFormatTypes->getStandardFormat(nCellType, aLocale)) );
950 else if (!rCurrency.empty() && !sCurrentCurrency.isEmpty())
952 if (sCurrentCurrency != rCurrency)
953 if (!IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
954 rProperties->setPropertyValue( SC_UNONAME_NUMFMT, uno::Any(SetCurrencySymbol(rNumberFormat, rCurrency)));
958 catch ( uno::Exception& )
960 OSL_FAIL("Numberformat not found");
964 else
966 if ((nCellType == util::NumberFormat::CURRENCY) && !rCurrency.empty() && !sCurrentCurrency.isEmpty() &&
967 sCurrentCurrency != rCurrency && !IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
968 rProperties->setPropertyValue( SC_UNONAME_NUMFMT, uno::Any(SetCurrencySymbol(rNumberFormat, rCurrency)));
972 void ScXMLImport::SetStyleToRanges()
974 if (!mbImportStyles)
975 return;
977 if (!sPrevStyleName.isEmpty())
979 uno::Reference <beans::XPropertySet> xProperties (mxSheetCellRanges);
980 if (xProperties.is())
982 XMLTableStylesContext *pStyles(static_cast<XMLTableStylesContext *>(GetAutoStyles()));
983 XMLTableStyleContext* pStyle = nullptr;
984 if ( pStyles )
985 pStyle = const_cast<XMLTableStyleContext*>(static_cast<const XMLTableStyleContext *>(pStyles->FindStyleChildContext(
986 XmlStyleFamily::TABLE_CELL, sPrevStyleName, true)));
987 if (pStyle)
989 pStyle->FillPropertySet(xProperties);
990 // here needs to be the cond format import method
991 sal_Int32 nNumberFormat(pStyle->GetNumberFormat());
992 SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
994 css::uno::Any aAny = xProperties->getPropertyValue(u"FormatID"_ustr);
995 sal_uInt64 nKey = 0;
996 if ((aAny >>= nKey) && nKey)
998 ScFormatSaveData* pFormatSaveData = GetScModel()->GetFormatSaveData();
999 pFormatSaveData->maIDToName.insert(std::pair<sal_uInt64, OUString>(nKey, sPrevStyleName));
1002 // store first cell of first range for each style, once per sheet
1003 uno::Sequence<table::CellRangeAddress> aAddresses(mxSheetCellRanges->getRangeAddresses());
1004 pStyle->ApplyCondFormat(aAddresses);
1005 if ( aAddresses.hasElements() )
1007 const table::CellRangeAddress& rRange = aAddresses[0];
1008 if ( rRange.Sheet != pStyle->GetLastSheet() )
1010 ScSheetSaveData* pSheetData = GetScModel()->GetSheetSaveData();
1011 pSheetData->AddCellStyle( sPrevStyleName,
1012 ScAddress( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), static_cast<SCTAB>(rRange.Sheet) ) );
1013 pStyle->SetLastSheet(rRange.Sheet);
1017 else
1019 xProperties->setPropertyValue(SC_UNONAME_CELLSTYL, uno::Any(GetStyleDisplayName( XmlStyleFamily::TABLE_CELL, sPrevStyleName )));
1020 sal_Int32 nNumberFormat(GetStyleNumberFormats()->GetStyleNumberFormat(sPrevStyleName));
1021 bool bInsert(nNumberFormat == -1);
1022 SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
1023 if (bInsert)
1024 GetStyleNumberFormats()->AddStyleNumberFormat(sPrevStyleName, nNumberFormat);
1028 if (GetModel().is())
1030 rtl::Reference<ScModelObj> xMultiServiceFactory(GetScModel());
1031 mxSheetCellRanges = &dynamic_cast<ScCellRangesObj&>(
1032 *xMultiServiceFactory->createInstance(u"com.sun.star.sheet.SheetCellRanges"_ustr));
1034 OSL_ENSURE(mxSheetCellRanges.is(), "didn't get SheetCellRanges");
1037 void ScXMLImport::SetStyleToRanges(const ScRangeList& rRanges, const OUString* pStyleName,
1038 const sal_Int16 nCellType, const OUString* pCurrency)
1040 if (!mbImportStyles)
1041 return;
1043 if (sPrevStyleName.isEmpty())
1045 nPrevCellType = nCellType;
1046 if (pStyleName)
1047 sPrevStyleName = *pStyleName;
1048 if (pCurrency)
1049 sPrevCurrency = *pCurrency;
1050 else if (!sPrevCurrency.isEmpty())
1051 sPrevCurrency.clear();
1053 else if ((nCellType != nPrevCellType) ||
1054 ((pStyleName && *pStyleName != sPrevStyleName) ||
1055 (!pStyleName && !sPrevStyleName.isEmpty())) ||
1056 ((pCurrency && *pCurrency != sPrevCurrency) ||
1057 (!pCurrency && !sPrevCurrency.isEmpty())))
1059 SetStyleToRanges();
1060 nPrevCellType = nCellType;
1061 if (pStyleName)
1062 sPrevStyleName = *pStyleName;
1063 else if(!sPrevStyleName.isEmpty())
1064 sPrevStyleName.clear();
1065 if (pCurrency)
1066 sPrevCurrency = *pCurrency;
1067 else if(!sPrevCurrency.isEmpty())
1068 sPrevCurrency.clear();
1071 if (!mxSheetCellRanges.is() && GetModel().is())
1073 rtl::Reference<ScModelObj> xMultiServiceFactory(GetScModel());
1074 mxSheetCellRanges = &dynamic_cast<ScCellRangesObj&>(*xMultiServiceFactory->createInstance(u"com.sun.star.sheet.SheetCellRanges"_ustr));
1075 OSL_ENSURE(mxSheetCellRanges.is(), "didn't get SheetCellRanges");
1077 mxSheetCellRanges->SetNewRanges(rRanges);
1080 bool ScXMLImport::SetNullDateOnUnitConverter()
1082 if (!bNullDateSetted)
1083 bNullDateSetted = GetMM100UnitConverter().setNullDate(GetModel());
1084 OSL_ENSURE(bNullDateSetted, "could not set the null date");
1085 return bNullDateSetted;
1088 XMLNumberFormatAttributesExportHelper* ScXMLImport::GetNumberFormatAttributesExportHelper()
1090 if (!pNumberFormatAttributesExportHelper)
1091 pNumberFormatAttributesExportHelper.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier()));
1092 return pNumberFormatAttributesExportHelper.get();
1095 ScMyStyleNumberFormats* ScXMLImport::GetStyleNumberFormats()
1097 if (!pStyleNumberFormats)
1098 pStyleNumberFormats.reset(new ScMyStyleNumberFormats);
1099 return pStyleNumberFormats.get();
1102 void ScXMLImport::SetStylesToRangesFinished()
1104 SetStyleToRanges();
1105 sPrevStyleName.clear();
1108 // XImporter
1109 void SAL_CALL ScXMLImport::setTargetDocument( const css::uno::Reference< css::lang::XComponent >& xDoc )
1111 ScXMLImport::MutexGuard aGuard(*this);
1112 SvXMLImport::setTargetDocument( xDoc );
1114 uno::Reference<frame::XModel> xModel(xDoc, uno::UNO_QUERY);
1115 mpDoc = ScXMLConverter::GetScDocument( xModel );
1116 OSL_ENSURE( mpDoc, "ScXMLImport::setTargetDocument - no ScDocument!" );
1117 if (!mpDoc)
1118 throw lang::IllegalArgumentException();
1120 if (ScDocShell* mpDocSh = mpDoc->GetDocumentShell())
1121 mpDocSh->SetInitialLinkUpdate( mpDocSh->GetMedium());
1123 mpDocImport.reset(new ScDocumentImport(*mpDoc));
1124 mpComp.reset(new ScCompiler(*mpDoc, ScAddress(), formula::FormulaGrammar::GRAM_ODFF));
1126 uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
1127 if (xActionLockable.is())
1128 xActionLockable->addActionLock();
1131 // css::xml::sax::XDocumentHandler
1132 void SAL_CALL ScXMLImport::startDocument()
1134 ScXMLImport::MutexGuard aGuard(*this);
1135 SvXMLImport::startDocument();
1136 if (mpDoc && !mpDoc->IsImportingXML())
1138 GetScModel()->BeforeXMLLoading();
1139 bSelfImportingXMLSet = true;
1142 // if content and styles are loaded with separate imports,
1143 // set bLatinDefaultStyle flag at the start of the content import
1144 SvXMLImportFlags nFlags = getImportFlags();
1145 if ( ( nFlags & SvXMLImportFlags::CONTENT ) && !( nFlags & SvXMLImportFlags::STYLES ) )
1146 ExamineDefaultStyle();
1148 if (getImportFlags() & SvXMLImportFlags::CONTENT)
1150 if (GetModel().is())
1152 // store initial namespaces, to find the ones that were added from the file later
1153 ScSheetSaveData* pSheetData = GetScModel()->GetSheetSaveData();
1154 const SvXMLNamespaceMap& rNamespaces = GetNamespaceMap();
1155 pSheetData->StoreInitialNamespaces(rNamespaces);
1159 uno::Reference< beans::XPropertySet > const xImportInfo( getImportInfo() );
1160 uno::Reference< beans::XPropertySetInfo > const xPropertySetInfo(
1161 xImportInfo.is() ? xImportInfo->getPropertySetInfo() : nullptr);
1162 if (xPropertySetInfo.is())
1164 static constexpr OUString sOrganizerMode(u"OrganizerMode"_ustr);
1165 if (xPropertySetInfo->hasPropertyByName(sOrganizerMode))
1167 bool bStyleOnly(false);
1168 if (xImportInfo->getPropertyValue(sOrganizerMode) >>= bStyleOnly)
1170 bLoadDoc = !bStyleOnly;
1175 UnlockSolarMutex();
1178 sal_Int32 ScXMLImport::GetRangeType(std::u16string_view sRangeType)
1180 sal_Int32 nRangeType(0);
1181 OUStringBuffer sBuffer;
1182 size_t i = 0;
1183 while (i <= sRangeType.size())
1185 if ((i == sRangeType.size()) || (sRangeType[i] == ' '))
1187 OUString sTemp = sBuffer.makeStringAndClear();
1188 if (sTemp == "repeat-column")
1189 nRangeType |= sheet::NamedRangeFlag::COLUMN_HEADER;
1190 else if (sTemp == SC_REPEAT_ROW)
1191 nRangeType |= sheet::NamedRangeFlag::ROW_HEADER;
1192 else if (sTemp == SC_FILTER)
1193 nRangeType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
1194 else if (sTemp == SC_PRINT_RANGE)
1195 nRangeType |= sheet::NamedRangeFlag::PRINT_AREA;
1196 else if (sTemp == SC_HIDDEN)
1197 nRangeType |= sheet::NamedRangeFlag::HIDDEN;
1199 else if (i < sRangeType.size())
1200 sBuffer.append(sRangeType[i]);
1201 ++i;
1203 return nRangeType;
1206 void ScXMLImport::SetLabelRanges()
1208 if (maMyLabelRanges.empty())
1209 return;
1211 if (!mpDoc)
1212 return;
1214 rtl::Reference<ScModelObj> xPropertySet (GetScModel());
1215 if (!xPropertySet.is())
1216 return;
1218 uno::Any aColAny = xPropertySet->getPropertyValue(SC_UNO_COLLABELRNG);
1219 uno::Any aRowAny = xPropertySet->getPropertyValue(SC_UNO_ROWLABELRNG);
1221 uno::Reference< sheet::XLabelRanges > xColRanges;
1222 uno::Reference< sheet::XLabelRanges > xRowRanges;
1224 if ( !(( aColAny >>= xColRanges ) && ( aRowAny >>= xRowRanges )) )
1225 return;
1227 table::CellRangeAddress aLabelRange;
1228 table::CellRangeAddress aDataRange;
1230 for (const auto& rLabelRange : maMyLabelRanges)
1232 sal_Int32 nOffset1(0);
1233 sal_Int32 nOffset2(0);
1234 FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO;
1236 if (ScRangeStringConverter::GetRangeFromString( aLabelRange, rLabelRange.sLabelRangeStr, *mpDoc, eConv, nOffset1 ) &&
1237 ScRangeStringConverter::GetRangeFromString( aDataRange, rLabelRange.sDataRangeStr, *mpDoc, eConv, nOffset2 ))
1239 if ( rLabelRange.bColumnOrientation )
1240 xColRanges->addNew( aLabelRange, aDataRange );
1241 else
1242 xRowRanges->addNew( aLabelRange, aDataRange );
1246 maMyLabelRanges.clear();
1249 namespace {
1251 class RangeNameInserter
1253 ScDocument& mrDoc;
1254 ScRangeName& mrRangeName;
1255 SCTAB mnTab;
1257 public:
1258 RangeNameInserter(ScDocument& rDoc, ScRangeName& rRangeName, SCTAB nTab) :
1259 mrDoc(rDoc), mrRangeName(rRangeName), mnTab(nTab) {}
1261 void operator() (const ScMyNamedExpression& p) const
1263 using namespace formula;
1265 const OUString& aType = p.sRangeType;
1266 sal_uInt32 nUnoType = ScXMLImport::GetRangeType(aType);
1268 ScRangeData::Type nNewType = ScRangeData::Type::Name;
1269 if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA ) nNewType |= ScRangeData::Type::Criteria;
1270 if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA ) nNewType |= ScRangeData::Type::PrintArea;
1271 if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER ) nNewType |= ScRangeData::Type::ColHeader;
1272 if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER ) nNewType |= ScRangeData::Type::RowHeader;
1273 if ( nUnoType & sheet::NamedRangeFlag::HIDDEN ) nNewType |= ScRangeData::Type::Hidden;
1275 // Insert a new name.
1276 ScAddress aPos;
1277 sal_Int32 nOffset = 0;
1278 bool bSuccess = ScRangeStringConverter::GetAddressFromString(
1279 aPos, p.sBaseCellAddress, mrDoc, FormulaGrammar::CONV_OOO, nOffset);
1281 if (!bSuccess)
1283 SAL_WARN("sc.filter", "No conversion from table:base-cell-address '" << p.sBaseCellAddress
1284 << "' for name '" << p.sName << "' on sheet " << mnTab);
1285 // Do not lose the defined name. Relative addressing in
1286 // content/expression, if any, will be broken though.
1287 // May had happened due to tdf#150312.
1288 aPos.SetTab(mnTab < 0 ? 0 : mnTab);
1289 bSuccess = true;
1292 if (bSuccess)
1294 OUString aContent = p.sContent;
1295 if (!p.bIsExpression)
1296 ScXMLConverter::ConvertCellRangeAddress(aContent);
1298 ScRangeData* pData = new ScRangeData(
1299 mrDoc, p.sName, aContent, aPos, nNewType, p.eGrammar);
1300 mrRangeName.insert(pData);
1307 void ScXMLImport::SetNamedRanges()
1309 if (m_aMyNamedExpressions.empty())
1310 return;
1312 if (!mpDoc)
1313 return;
1315 // Insert the namedRanges
1316 ScRangeName* pRangeNames = mpDoc->GetRangeName();
1317 ::std::for_each(m_aMyNamedExpressions.begin(), m_aMyNamedExpressions.end(),
1318 RangeNameInserter(*mpDoc, *pRangeNames, -1));
1321 void ScXMLImport::SetSheetNamedRanges()
1323 if (!mpDoc)
1324 return;
1326 for (auto const& itr : m_SheetNamedExpressions)
1328 const SCTAB nTab = itr.first;
1329 ScRangeName* pRangeNames = mpDoc->GetRangeName(nTab);
1330 if (!pRangeNames)
1331 continue;
1333 const ScMyNamedExpressions& rNames = itr.second;
1334 ::std::for_each(rNames.begin(), rNames.end(), RangeNameInserter(*mpDoc, *pRangeNames, nTab));
1338 void ScXMLImport::SetStringRefSyntaxIfMissing()
1340 if (!mpDoc)
1341 return;
1343 ScCalcConfig aCalcConfig = mpDoc->GetCalcConfig();
1345 // Has any string ref syntax been imported?
1346 // If not, we need to take action
1347 if ( !aCalcConfig.mbHasStringRefSyntax )
1349 aCalcConfig.meStringRefAddressSyntax = formula::FormulaGrammar::CONV_A1_XL_A1;
1350 mpDoc->SetCalcConfig(aCalcConfig);
1354 void SAL_CALL ScXMLImport::endDocument()
1356 ScXMLImport::MutexGuard aGuard(*this);
1357 if (getImportFlags() & SvXMLImportFlags::CONTENT)
1359 if (GetModel().is())
1361 mpDocImport->finalize();
1363 rtl::Reference<ScModelObj> xViewDataSupplier(GetScModel());
1364 uno::Reference<container::XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData());
1365 if (xIndexAccess.is() && xIndexAccess->getCount() > 0)
1367 uno::Sequence< beans::PropertyValue > aSeq;
1368 if (xIndexAccess->getByIndex(0) >>= aSeq)
1370 for (const auto& rProp : aSeq)
1372 OUString sName(rProp.Name);
1373 if (sName == SC_ACTIVETABLE)
1375 OUString sTabName;
1376 if(rProp.Value >>= sTabName)
1378 SCTAB nTab(0);
1379 if (mpDoc && mpDoc->GetTable(sTabName, nTab))
1381 mpDoc->SetVisibleTab(nTab);
1382 break;
1389 SetLabelRanges();
1390 SetNamedRanges();
1391 SetSheetNamedRanges();
1392 SetStringRefSyntaxIfMissing();
1393 if (mpPivotSources)
1394 // Process pivot table sources after the named ranges have been set.
1395 mpPivotSources->process();
1397 GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
1398 if (mpDoc)
1400 mpDoc->CompileXML();
1402 // After CompileXML, links must be completely changed to the new URLs.
1403 // Otherwise, hasExternalFile for API wouldn't work (#i116940#),
1404 // and typing a new formula would create a second link with the same "real" file name.
1405 if (mpDoc->HasExternalRefManager())
1406 mpDoc->GetExternalRefManager()->updateAbsAfterLoad();
1409 // If the stream contains cells outside of the current limits, the styles can't be re-created,
1410 // so stream copying is disabled then.
1411 if (mpDoc && GetModel().is() && !mpDoc->HasRangeOverflow())
1413 // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
1414 // in UpdateRowHeights can already clear the flags again)
1415 ScSheetSaveData* pSheetData = GetScModel()->GetSheetSaveData();
1417 SCTAB nTabCount = mpDoc->GetTableCount();
1418 for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
1420 mpDoc->SetDrawPageSize(nTab);
1421 if (!pSheetData->IsSheetBlocked( nTab ))
1422 mpDoc->SetStreamValid( nTab, true );
1426 // There are rows with optimal height which need to be updated
1427 if (mpDoc && !maRecalcRowRanges.empty() && mpDoc->GetDocumentShell()
1428 && mpDoc->GetDocumentShell()->GetRecalcRowHeightsMode())
1430 bool bLockHeight = mpDoc->IsAdjustHeightLocked();
1431 if (bLockHeight)
1433 mpDoc->UnlockAdjustHeight();
1436 ScSizeDeviceProvider aProv(mpDoc->GetDocumentShell());
1437 ScDocRowHeightUpdater aUpdater(*mpDoc, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &maRecalcRowRanges);
1438 aUpdater.update();
1440 if (bLockHeight)
1442 mpDoc->LockAdjustHeight();
1446 // Initialize and set position and size of objects
1447 if (mpDoc && mpDoc->GetDrawLayer())
1449 ScDrawLayer* pDrawLayer = mpDoc->GetDrawLayer();
1450 SCTAB nTabCount = mpDoc->GetTableCount();
1451 for (SCTAB nTab = 0; nTab < nTabCount; ++nTab)
1453 const SdrPage* pPage = pDrawLayer->GetPage(nTab);
1454 if (!pPage)
1455 continue;
1456 bool bNegativePage = mpDoc->IsNegativePage(nTab);
1457 for (const rtl::Reference<SdrObject>& pObj : *pPage)
1459 ScDrawObjData* pData
1460 = ScDrawLayer::GetObjDataTab(pObj.get(), nTab);
1461 // Existence of pData means, that it is a cell anchored object
1462 if (pData)
1464 // Finish and correct import based on full size (no hidden row/col) and LTR
1465 pDrawLayer->InitializeCellAnchoredObj(pObj.get(), *pData);
1466 // Adapt object to hidden row/col and RTL
1467 pDrawLayer->RecalcPos(pObj.get(), *pData, bNegativePage,
1468 true /*bUpdateNoteCaptionPos*/);
1474 aTables.FixupOLEs();
1476 if (GetScModel())
1478 GetScModel()->removeActionLock();
1480 SvXMLImport::endDocument();
1482 if (mpDoc)
1484 mpDoc->BroadcastUno(SfxHint(SfxHintId::ScClearCache));
1487 if(mpDoc && bSelfImportingXMLSet)
1488 GetScModel()->AfterXMLLoading();
1491 // XEventListener
1492 void ScXMLImport::DisposingModel()
1494 SvXMLImport::DisposingModel();
1495 mpDoc = nullptr;
1498 ScXMLImport::MutexGuard::MutexGuard(ScXMLImport& rImport) :
1499 mrImport(rImport)
1501 mrImport.LockSolarMutex();
1504 ScXMLImport::MutexGuard::~MutexGuard()
1506 mrImport.UnlockSolarMutex();
1509 void ScXMLImport::LockSolarMutex()
1511 // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked,
1512 // so there's no need to allocate (and later delete) the SolarMutexGuard.
1513 if (!mbLockSolarMutex)
1515 DBG_TESTSOLARMUTEX();
1516 return;
1519 if (nSolarMutexLocked == 0)
1521 OSL_ENSURE(!moSolarMutexGuard, "Solar Mutex is locked");
1522 moSolarMutexGuard.emplace();
1524 ++nSolarMutexLocked;
1527 void ScXMLImport::UnlockSolarMutex()
1529 if (nSolarMutexLocked > 0)
1531 nSolarMutexLocked--;
1532 if (nSolarMutexLocked == 0)
1534 OSL_ENSURE(moSolarMutexGuard, "Solar Mutex is always unlocked");
1535 moSolarMutexGuard.reset();
1540 sal_Int64 ScXMLImport::GetByteOffset() const
1542 sal_Int64 nOffset = -1;
1543 uno::Reference<xml::sax::XLocator> xLocator = GetLocator();
1544 uno::Reference<io::XSeekable> xSeek( xLocator, uno::UNO_QUERY ); //! should use different interface
1545 if ( xSeek.is() )
1546 nOffset = xSeek->getPosition();
1547 return nOffset;
1550 void ScXMLImport::SetRangeOverflowType(ErrCode nType)
1552 // #i31130# Overflow is stored in the document, because the ScXMLImport object
1553 // isn't available in ScXMLImportWrapper::ImportFromComponent when using the
1554 // OOo->Oasis transformation.
1556 if ( mpDoc )
1557 mpDoc->SetRangeOverflowType( nType );
1560 void ScXMLImport::ProgressBarIncrement()
1562 nProgressCount++;
1563 if (nProgressCount > 100)
1565 GetProgressBarHelper()->Increment(nProgressCount);
1566 nProgressCount = 0;
1570 void ScXMLImport::ExtractFormulaNamespaceGrammar(
1571 OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
1572 const OUString& rAttrValue, bool bRestrictToExternalNmsp ) const
1574 // parse the attribute value, extract namespace ID, literal namespace, and formula string
1575 rFormulaNmsp.clear();
1576 sal_uInt16 nNsId = GetNamespaceMap().GetKeyByQName(rAttrValue, nullptr, &rFormula, &rFormulaNmsp, SvXMLNamespaceMap::QNameMode::AttrValue);
1578 // check if we have an ODF formula namespace
1579 if( !bRestrictToExternalNmsp ) switch( nNsId )
1581 case XML_NAMESPACE_OOOC:
1582 rFormulaNmsp.clear(); // remove namespace string for built-in grammar
1583 reGrammar = FormulaGrammar::GRAM_PODF;
1584 return;
1585 case XML_NAMESPACE_OF:
1586 rFormulaNmsp.clear(); // remove namespace string for built-in grammar
1587 reGrammar = FormulaGrammar::GRAM_ODFF;
1588 return;
1591 if (!mpDoc)
1592 return;
1594 /* Find default grammar for formulas without namespace. There may be
1595 documents in the wild that stored no namespace in ODF 1.0/1.1. Use
1596 GRAM_PODF then (old style ODF 1.0/1.1 formulas). The default for ODF
1597 1.2 and later without namespace is GRAM_ODFF (OpenFormula). */
1598 FormulaGrammar::Grammar eDefaultGrammar =
1599 (mpDoc->GetStorageGrammar() == FormulaGrammar::GRAM_PODF) ?
1600 FormulaGrammar::GRAM_PODF : FormulaGrammar::GRAM_ODFF;
1602 /* Check if we have no namespace at all. The value XML_NAMESPACE_NONE
1603 indicates that there is no colon. If the first character of the
1604 attribute value is the equality sign, the value XML_NAMESPACE_UNKNOWN
1605 indicates that there is a colon somewhere in the formula string. */
1606 if( (nNsId == XML_NAMESPACE_NONE) || ((nNsId == XML_NAMESPACE_UNKNOWN) && (rAttrValue.toChar() == '=')) )
1608 rFormula = rAttrValue; // return entire string as formula
1609 reGrammar = eDefaultGrammar;
1610 return;
1613 /* Check if a namespace URL could be resolved from the attribute value.
1614 Use that namespace only, if the Calc document knows an associated
1615 external formula parser. This prevents that the range operator in
1616 conjunction with defined names is confused as namespaces prefix, e.g.
1617 in the expression 'table:A1' where 'table' is a named reference. */
1618 if( ((nNsId & XML_NAMESPACE_UNKNOWN_FLAG) != 0) && !rFormulaNmsp.isEmpty() &&
1619 mpDoc->GetFormulaParserPool().hasFormulaParser( rFormulaNmsp ) )
1621 reGrammar = FormulaGrammar::GRAM_EXTERNAL;
1622 return;
1625 /* All attempts failed (e.g. no namespace and no leading equality sign, or
1626 an invalid namespace prefix), continue with the entire attribute value. */
1627 rFormula = rAttrValue;
1628 rFormulaNmsp.clear(); // remove any namespace string
1629 reGrammar = eDefaultGrammar;
1632 FormulaError ScXMLImport::GetFormulaErrorConstant( const OUString& rStr ) const
1634 if (!mpComp)
1635 return FormulaError::NONE;
1637 return mpComp->GetErrorConstant(rStr);
1640 ScEditEngineDefaulter* ScXMLImport::GetEditEngine()
1642 if (!mpEditEngine && mpDoc)
1644 mpEditEngine.reset(new ScEditEngineDefaulter(mpDoc->GetEnginePool()));
1645 mpEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
1646 mpEditEngine->SetEditTextObjectPool(mpDoc->GetEditPool());
1647 mpEditEngine->SetUpdateLayout(false);
1648 mpEditEngine->EnableUndo(false);
1649 mpEditEngine->SetControlWord(mpEditEngine->GetControlWord() & ~EEControlBits::ALLOWBIGOBJS);
1651 return mpEditEngine.get();
1654 const ScXMLEditAttributeMap& ScXMLImport::GetEditAttributeMap() const
1656 if (!mpEditAttrMap)
1657 mpEditAttrMap.reset(new ScXMLEditAttributeMap);
1658 return *mpEditAttrMap;
1661 void ScXMLImport::NotifyContainsEmbeddedFont()
1663 if (mpDoc)
1664 mpDoc->SetEmbedFonts(true);
1667 ScMyImpDetectiveOpArray* ScXMLImport::GetDetectiveOpArray()
1669 if (!pDetectiveOpArray)
1670 pDetectiveOpArray.reset(new ScMyImpDetectiveOpArray());
1671 return pDetectiveOpArray.get();
1674 ScModelObj* ScXMLImport::GetScModel() const
1676 return static_cast<ScModelObj*>(GetModel().get());
1679 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportFODS(SvStream &rStream)
1681 ScDLL::Init();
1683 SfxObjectShellLock xDocSh(new ScDocShell);
1684 xDocSh->DoInitNew();
1685 uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
1687 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1688 uno::Reference<io::XInputStream> xStream(new ::utl::OSeekableInputStreamWrapper(rStream));
1689 uno::Reference<uno::XInterface> xInterface(xMultiServiceFactory->createInstance(u"com.sun.star.comp.Writer.XmlFilterAdaptor"_ustr), uno::UNO_SET_THROW);
1691 css::uno::Sequence<OUString> aUserData
1693 u"com.sun.star.comp.filter.OdfFlatXml"_ustr,
1694 u""_ustr,
1695 u"com.sun.star.comp.Calc.XMLOasisImporter"_ustr,
1696 u"com.sun.star.comp.Calc.XMLOasisExporter"_ustr,
1697 u""_ustr,
1698 u""_ustr,
1699 u"true"_ustr
1701 uno::Sequence<beans::PropertyValue> aAdaptorArgs(comphelper::InitPropertySequence(
1703 { "UserData", uno::Any(aUserData) },
1704 }));
1705 css::uno::Sequence<uno::Any> aOuterArgs{ uno::Any(aAdaptorArgs) };
1707 uno::Reference<lang::XInitialization> xInit(xInterface, uno::UNO_QUERY_THROW);
1708 xInit->initialize(aOuterArgs);
1710 uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY_THROW);
1711 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1713 { "InputStream", uno::Any(xStream) },
1714 { "URL", uno::Any(u"private:stream"_ustr) },
1715 }));
1716 xImporter->setTargetDocument(xModel);
1718 uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW);
1719 //SetLoading hack because the document properties will be re-initted
1720 //by the xml filter and during the init, while it's considered uninitialized,
1721 //setting a property will inform the document it's modified, which attempts
1722 //to update the properties, which throws cause the properties are uninitialized
1723 xDocSh->SetLoading(SfxLoadedFlags::NONE);
1724 bool ret = xFilter->filter(aArgs);
1725 xDocSh->SetLoading(SfxLoadedFlags::ALL);
1727 xDocSh->DoClose();
1729 return ret;
1732 extern "C" SAL_DLLPUBLIC_EXPORT bool TestFODSExportXLS(SvStream &rStream)
1734 ScDLL::Init();
1736 SfxObjectShellLock xDocSh(new ScDocShell);
1737 xDocSh->DoInitNew();
1738 uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
1740 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1741 uno::Reference<io::XInputStream> xStream(new ::utl::OSeekableInputStreamWrapper(rStream));
1742 uno::Reference<uno::XInterface> xInterface(xMultiServiceFactory->createInstance(u"com.sun.star.comp.Writer.XmlFilterAdaptor"_ustr), uno::UNO_SET_THROW);
1744 css::uno::Sequence<OUString> aUserData
1746 u"com.sun.star.comp.filter.OdfFlatXml"_ustr,
1747 u""_ustr,
1748 u"com.sun.star.comp.Calc.XMLOasisImporter"_ustr,
1749 u"com.sun.star.comp.Calc.XMLOasisExporter"_ustr,
1750 u""_ustr,
1751 u""_ustr,
1752 u"true"_ustr
1754 uno::Sequence<beans::PropertyValue> aAdaptorArgs(comphelper::InitPropertySequence(
1756 { "UserData", uno::Any(aUserData) },
1757 }));
1758 css::uno::Sequence<uno::Any> aOuterArgs{ uno::Any(aAdaptorArgs) };
1760 uno::Reference<lang::XInitialization> xInit(xInterface, uno::UNO_QUERY_THROW);
1761 xInit->initialize(aOuterArgs);
1763 uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY_THROW);
1764 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1766 { "InputStream", uno::Any(xStream) },
1767 { "URL", uno::Any(u"private:stream"_ustr) },
1768 }));
1769 xImporter->setTargetDocument(xModel);
1771 uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW);
1772 //SetLoading hack because the document properties will be re-initted
1773 //by the xml filter and during the init, while it's considered uninitialized,
1774 //setting a property will inform the document it's modified, which attempts
1775 //to update the properties, which throws cause the properties are uninitialized
1776 xDocSh->SetLoading(SfxLoadedFlags::NONE);
1777 bool ret = xFilter->filter(aArgs);
1778 xDocSh->SetLoading(SfxLoadedFlags::ALL);
1780 if (ret)
1782 utl::TempFileFast aTempFile;
1784 uno::Reference<document::XFilter> xXLSFilter(
1785 xMultiServiceFactory->createInstance(u"com.sun.star.comp.oox.xls.ExcelFilter"_ustr), uno::UNO_QUERY);
1786 uno::Reference<document::XExporter> xExporter(xXLSFilter, uno::UNO_QUERY);
1787 xExporter->setSourceDocument(xModel);
1789 uno::Reference<io::XOutputStream> xOutputStream(new utl::OStreamWrapper(*aTempFile.GetStream(StreamMode::READWRITE)));
1791 uno::Sequence<beans::PropertyValue> aFilterData(comphelper::InitPropertySequence({
1792 }));
1793 uno::Sequence<beans::PropertyValue> aDescriptor(comphelper::InitPropertySequence({
1794 { "FilterName", uno::Any(u"Excel 2007–365"_ustr) },
1795 { "OutputStream", uno::Any(xOutputStream) },
1796 { "FilterData", uno::Any(aFilterData) }
1797 }));
1798 xXLSFilter->filter(aDescriptor);
1801 xDocSh->DoClose();
1803 return ret;
1806 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportXLSX(SvStream &rStream)
1808 ScDLL::Init();
1810 SfxObjectShellLock xDocSh(new ScDocShell);
1811 xDocSh->DoInitNew();
1812 uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
1814 uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1815 uno::Reference<io::XInputStream> xStream(new utl::OSeekableInputStreamWrapper(rStream));
1817 uno::Reference<document::XFilter> xFilter(xMultiServiceFactory->createInstance(u"com.sun.star.comp.oox.xls.ExcelFilter"_ustr), uno::UNO_QUERY_THROW);
1819 uno::Reference<document::XImporter> xImporter(xFilter, uno::UNO_QUERY_THROW);
1820 uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
1822 { "InputStream", uno::Any(xStream) },
1823 { "InputMode", uno::Any(true) },
1824 }));
1825 xImporter->setTargetDocument(xModel);
1827 //SetLoading hack because the document properties will be re-initted
1828 //by the xml filter and during the init, while it's considered uninitialized,
1829 //setting a property will inform the document it's modified, which attempts
1830 //to update the properties, which throws cause the properties are uninitialized
1831 xDocSh->SetLoading(SfxLoadedFlags::NONE);
1832 bool ret = false;
1835 SolarMutexGuard aGuard;
1836 ret = xFilter->filter(aArgs);
1838 catch (const css::io::IOException&)
1841 catch (const css::lang::WrappedTargetRuntimeException&)
1844 xDocSh->SetLoading(SfxLoadedFlags::ALL);
1846 xDocSh->DoClose();
1848 return ret;
1851 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */