1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
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 <xmloff/xmlscripti.hxx>
33 #include <xmloff/XMLFontStylesContext.hxx>
34 #include <xmloff/DocumentSettingsContext.hxx>
35 #include <xmloff/xmluconv.hxx>
36 #include <xmloff/numehelp.hxx>
37 #include <xmloff/xmltoken.hxx>
38 #include <xmloff/xmlerror.hxx>
39 #include <xmloff/ProgressBarHelper.hxx>
40 #include <svx/svdpage.hxx>
42 #include <svl/languageoptions.hxx>
43 #include <editeng/editstat.hxx>
44 #include <formula/errorcodes.hxx>
45 #include <vcl/svapp.hxx>
47 #include <appluno.hxx>
48 #include "xmlimprt.hxx"
49 #include "importcontext.hxx"
50 #include <document.hxx>
53 #include "xmlbodyi.hxx"
54 #include "xmlstyli.hxx"
55 #include <ViewSettingsSequenceDefines.hxx>
56 #include <userdat.hxx>
58 #include <compiler.hxx>
60 #include "XMLConverter.hxx"
61 #include "XMLDetectiveContext.hxx"
62 #include "XMLTableShapeImportHelper.hxx"
63 #include "XMLChangeTrackingImportHelper.hxx"
64 #include <chgviset.hxx>
65 #include "XMLStylesImportHelper.hxx"
66 #include <sheetdata.hxx>
67 #include <rangeutl.hxx>
68 #include <formulaparserpool.hxx>
69 #include <externalrefmgr.hxx>
70 #include <editutil.hxx>
71 #include "editattributemap.hxx"
72 #include <documentimport.hxx>
73 #include "pivotsource.hxx"
74 #include <unonames.hxx>
75 #include <numformat.hxx>
76 #include <sizedev.hxx>
78 #include "xmlstyle.hxx"
80 #include <comphelper/base64.hxx>
81 #include <comphelper/extract.hxx>
82 #include <comphelper/propertysequence.hxx>
83 #include <comphelper/processfactory.hxx>
85 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
86 #include <com/sun/star/frame/XModel.hpp>
87 #include <com/sun/star/io/IOException.hpp>
88 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
89 #include <com/sun/star/document/XActionLockable.hpp>
90 #include <com/sun/star/util/MalformedNumberFormatException.hpp>
91 #include <com/sun/star/util/NumberFormat.hpp>
92 #include <com/sun/star/util/XNumberFormatTypes.hpp>
93 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
94 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
95 #include <com/sun/star/sheet/XLabelRanges.hpp>
96 #include <com/sun/star/io/XSeekable.hpp>
97 #include <com/sun/star/beans/XPropertySet.hpp>
98 #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
99 #include <cellsuno.hxx>
104 constexpr OUStringLiteral SC_LOCALE
= u
"Locale";
105 constexpr OUStringLiteral SC_CURRENCYSYMBOL
= u
"CurrencySymbol";
106 constexpr OUStringLiteral SC_REPEAT_ROW
= u
"repeat-row";
107 constexpr OUStringLiteral SC_FILTER
= u
"filter";
108 constexpr OUStringLiteral SC_PRINT_RANGE
= u
"print-range";
110 using namespace com::sun::star
;
111 using namespace ::xmloff::token
;
112 using namespace ::formula
;
114 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
115 Calc_XMLOasisImporter_get_implementation(
116 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
118 return cppu::acquire(
121 "com.sun.star.comp.Calc.XMLOasisImporter",
122 SvXMLImportFlags::ALL
,
123 { "com.sun.star.comp.Calc.XMLOasisImporter" } ));
126 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
127 Calc_XMLOasisMetaImporter_get_implementation(
128 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
130 return cppu::acquire(
133 "com.sun.star.comp.Calc.XMLOasisMetaImporter",
134 SvXMLImportFlags::META
,
135 { "com.sun.star.comp.Calc.XMLOasisMetaImporter" } ));
138 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
139 Calc_XMLOasisStylesImporter_get_implementation(
140 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
142 return cppu::acquire(
145 "com.sun.star.comp.Calc.XMLOasisStylesImporter",
146 SvXMLImportFlags::STYLES
|SvXMLImportFlags::AUTOSTYLES
|SvXMLImportFlags::MASTERSTYLES
|SvXMLImportFlags::FONTDECLS
,
147 { "com.sun.star.comp.Calc.XMLOasisStylesImporter" } ));
150 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
151 Calc_XMLOasisContentImporter_get_implementation(
152 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
154 return cppu::acquire(new ScXMLImport(
156 "com.sun.star.comp.Calc.XMLOasisContentImporter",
157 SvXMLImportFlags::AUTOSTYLES
|SvXMLImportFlags::CONTENT
|SvXMLImportFlags::SCRIPTS
|SvXMLImportFlags::FONTDECLS
,
158 uno::Sequence
< OUString
> { "com.sun.star.comp.Calc.XMLOasisContentImporter" }));
162 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
163 Calc_XMLOasisSettingsImporter_get_implementation(
164 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const& )
166 return cppu::acquire(
169 "com.sun.star.comp.Calc.XMLOasisSettingsImporter",
170 SvXMLImportFlags::SETTINGS
,
171 { "com.sun.star.comp.Calc.XMLOasisSettingsImporter" } ));
176 // NB: virtually inherit so we can multiply inherit properly
177 // in ScXMLFlatDocContext_Impl
178 class ScXMLDocContext_Impl
: public virtual SvXMLImportContext
181 ScXMLImport
& GetScImport() { return static_cast<ScXMLImport
&>(GetImport()); }
184 ScXMLDocContext_Impl( ScXMLImport
& rImport
);
186 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
187 createFastChildContext( sal_Int32 nElement
,
188 const css::uno::Reference
<css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
193 ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport
& rImport
) :
194 SvXMLImportContext( rImport
)
200 // context for flat file xml format
201 class ScXMLFlatDocContext_Impl
202 : public ScXMLDocContext_Impl
, public SvXMLMetaDocumentContext
206 ScXMLFlatDocContext_Impl( ScXMLImport
& i_rImport
,
207 const uno::Reference
<document::XDocumentProperties
>& i_xDocProps
);
209 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
210 createFastChildContext( sal_Int32 nElement
,
211 const css::uno::Reference
<css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
216 ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport
& i_rImport
,
217 const uno::Reference
<document::XDocumentProperties
>& i_xDocProps
) :
218 SvXMLImportContext(i_rImport
),
219 ScXMLDocContext_Impl(i_rImport
),
220 SvXMLMetaDocumentContext(i_rImport
, i_xDocProps
)
224 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
225 ScXMLFlatDocContext_Impl::createFastChildContext( sal_Int32 nElement
,
226 const uno::Reference
< xml::sax::XFastAttributeList
> & xAttrList
)
228 if ( nElement
== XML_ELEMENT( OFFICE
, XML_META
) )
229 return SvXMLMetaDocumentContext::createFastChildContext( nElement
, xAttrList
);
231 return ScXMLDocContext_Impl::createFastChildContext( nElement
, xAttrList
);
236 class ScXMLBodyContext_Impl
: public ScXMLImportContext
239 ScXMLBodyContext_Impl( ScXMLImport
& rImport
);
241 virtual css::uno::Reference
< css::xml::sax::XFastContextHandler
> SAL_CALL
242 createFastChildContext( sal_Int32 nElement
,
243 const css::uno::Reference
<css::xml::sax::XFastAttributeList
>& xAttrList
) override
;
248 ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport
& rImport
) :
249 ScXMLImportContext( rImport
)
253 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
254 ScXMLBodyContext_Impl::createFastChildContext( sal_Int32
/*nElement*/,
255 const uno::Reference
< xml::sax::XFastAttributeList
> & xAttrList
)
257 sax_fastparser::FastAttributeList
*pAttribList
=
258 &sax_fastparser::castToFastAttributeList( xAttrList
);
259 return GetScImport().CreateBodyContext( pAttribList
);
262 uno::Reference
< xml::sax::XFastContextHandler
> SAL_CALL
263 ScXMLDocContext_Impl::createFastChildContext( sal_Int32 nElement
,
264 const uno::Reference
< xml::sax::XFastAttributeList
> & /*xAttrList*/ )
266 SvXMLImportContext
*pContext(nullptr);
270 case XML_ELEMENT( OFFICE
, XML_BODY
):
271 if (GetScImport().getImportFlags() & SvXMLImportFlags::CONTENT
)
272 pContext
= new ScXMLBodyContext_Impl( GetScImport() );
274 case XML_ELEMENT( OFFICE
, XML_SCRIPTS
):
275 if (GetScImport().getImportFlags() & SvXMLImportFlags::SCRIPTS
)
276 pContext
= GetScImport().CreateScriptContext();
278 case XML_ELEMENT( OFFICE
, XML_SETTINGS
):
279 if (GetScImport().getImportFlags() & SvXMLImportFlags::SETTINGS
)
280 pContext
= new XMLDocumentSettingsContext(GetScImport());
282 case XML_ELEMENT(OFFICE
, XML_STYLES
):
283 if (GetScImport().getImportFlags() & SvXMLImportFlags::STYLES
)
284 pContext
= GetScImport().CreateStylesContext( false);
286 case XML_ELEMENT(OFFICE
, XML_AUTOMATIC_STYLES
):
287 if (GetScImport().getImportFlags() & SvXMLImportFlags::AUTOSTYLES
)
288 pContext
= GetScImport().CreateStylesContext( true);
290 case XML_ELEMENT(OFFICE
, XML_FONT_FACE_DECLS
):
291 if (GetScImport().getImportFlags() & SvXMLImportFlags::FONTDECLS
)
292 pContext
= GetScImport().CreateFontDeclsContext();
294 case XML_ELEMENT(OFFICE
, XML_MASTER_STYLES
):
295 if (GetScImport().getImportFlags() & SvXMLImportFlags::MASTERSTYLES
)
296 pContext
= new ScXMLMasterStylesContext( GetImport() );
298 case XML_ELEMENT(OFFICE
, XML_META
):
299 SAL_INFO("sc", "XML_ELEMENT(OFFICE, XML_META): should not have come here, maybe document is invalid?");
307 void ScXMLImport::SetPostProcessData( sc::ImportPostProcessData
* p
)
309 mpPostProcessData
= p
;
312 sc::PivotTableSources
& ScXMLImport::GetPivotTableSources()
315 mpPivotSources
.reset(new sc::PivotTableSources
);
317 return *mpPivotSources
;
320 SvXMLImportContext
*ScXMLImport::CreateFastContext( sal_Int32 nElement
,
321 const uno::Reference
< xml::sax::XFastAttributeList
>& /*xAttrList*/ )
323 SvXMLImportContext
*pContext
= nullptr;
327 case XML_ELEMENT( OFFICE
, XML_DOCUMENT_STYLES
):
328 case XML_ELEMENT( OFFICE
, XML_DOCUMENT_CONTENT
):
329 case XML_ELEMENT( OFFICE
, XML_DOCUMENT_SETTINGS
):
330 pContext
= new ScXMLDocContext_Impl( *this );
333 case XML_ELEMENT( OFFICE
, XML_DOCUMENT_META
):
334 pContext
= CreateMetaContext(nElement
);
337 case XML_ELEMENT( OFFICE
, XML_DOCUMENT
):
339 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
340 GetModel(), uno::UNO_QUERY_THROW
);
341 // flat OpenDocument file format
342 pContext
= new ScXMLFlatDocContext_Impl( *this,
343 xDPS
->getDocumentProperties());
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
),
358 mpPostProcessData(nullptr),
360 nSolarMutexLocked(0),
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
400 pSolarMutexGuard
.reset();
403 void ScXMLImport::initialize( const css::uno::Sequence
<css::uno::Any
>& aArguments
)
405 SvXMLImport::initialize(aArguments
);
407 uno::Reference
<beans::XPropertySet
> xInfoSet
= getImportInfo();
411 uno::Reference
<beans::XPropertySetInfo
> xInfoSetInfo
= xInfoSet
->getPropertySetInfo();
412 if (!xInfoSetInfo
.is())
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
;
431 SvXMLImportContext
*ScXMLImport::CreateStylesContext( bool bIsAutoStyle
)
433 SvXMLImportContext
* pContext
= new XMLTableStylesContext(
434 *this, bIsAutoStyle
);
437 SetAutoStyles(static_cast<SvXMLStylesContext
*>(pContext
));
439 SetStyles(static_cast<SvXMLStylesContext
*>(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::XDocumentPropertiesSupplier
> xDPS(
457 GetModel(), uno::UNO_QUERY_THROW
);
458 uno::Reference
<document::XDocumentProperties
> const xDocProps(
459 (IsStylesOnlyMode()) ? nullptr : xDPS
->getDocumentProperties());
460 pContext
= new SvXMLMetaDocumentContext(*this, xDocProps
);
466 SvXMLImportContext
*ScXMLImport::CreateScriptContext()
468 SvXMLImportContext
* pContext
= nullptr;
470 if( !(IsStylesOnlyMode()) )
472 pContext
= new XMLScriptContext( *this, GetModel() );
478 void ScXMLImport::SetStatistics(const uno::Sequence
<beans::NamedValue
> & i_rStats
)
480 static const char* s_stats
[] =
481 { "TableCount", "CellCount", "ObjectCount", nullptr };
483 SvXMLImport::SetStatistics(i_rStats
);
485 sal_uInt64
nCount(0);
486 for (const auto& rStat
: i_rStats
) {
487 for (const char** pStat
= s_stats
; *pStat
!= nullptr; ++pStat
) {
488 if (rStat
.Name
.equalsAscii(*pStat
)) {
490 if (rStat
.Value
>>= val
) {
493 OSL_FAIL("ScXMLImport::SetStatistics: invalid entry");
501 GetProgressBarHelper()->SetReference(nCount
);
502 GetProgressBarHelper()->SetValue(0);
506 ScDocumentImport
& ScXMLImport::GetDoc()
511 sal_Int16
ScXMLImport::GetCellType(const char* rStrValue
, const sal_Int32 nStrLength
)
513 sal_Int16 nCellType
= util::NumberFormat::UNDEFINED
;
514 if (rStrValue
!= nullptr)
516 switch (rStrValue
[0])
519 if (nStrLength
== 7 && !strcmp(rStrValue
, "boolean"))
520 nCellType
= util::NumberFormat::LOGICAL
;
523 if (nStrLength
== 8 && !strcmp(rStrValue
, "currency"))
524 nCellType
= util::NumberFormat::CURRENCY
;
527 if (nStrLength
== 4 && !strcmp(rStrValue
, "date"))
528 nCellType
= util::NumberFormat::DATETIME
;
531 if (nStrLength
== 5 && !strcmp(rStrValue
, "float"))
532 nCellType
= util::NumberFormat::NUMBER
;
535 if (nStrLength
== 10 && !strcmp(rStrValue
, "percentage"))
536 nCellType
= util::NumberFormat::PERCENT
;
539 if (nStrLength
== 6 && !strcmp(rStrValue
, "string"))
540 nCellType
= util::NumberFormat::TEXT
;
543 if (nStrLength
== 4 && !strcmp(rStrValue
, "time"))
544 nCellType
= util::NumberFormat::TIME
;
552 XMLShapeImportHelper
* ScXMLImport::CreateShapeImport()
554 return new XMLTableShapeImportHelper(*this);
557 bool ScXMLImport::GetValidation(const OUString
& sName
, ScMyImportValidation
& aValidation
)
559 auto aItr
= std::find_if(maValidations
.begin(), maValidations
.end(),
560 [&sName
](const ScMyImportValidation
& rValidation
) { return rValidation
.sName
== sName
; });
561 if (aItr
!= maValidations
.end())
563 // source position must be set as string,
564 // so sBaseCellAddress no longer has to be converted here
571 void ScXMLImport::AddNamedExpression(SCTAB nTab
, ScMyNamedExpression aNamedExp
)
573 SheetNamedExpMap::iterator itr
= m_SheetNamedExpressions
.find(nTab
);
574 if (itr
== m_SheetNamedExpressions
.end())
576 // No chain exists for this sheet. Create one.
577 ::std::pair
<SheetNamedExpMap::iterator
, bool> r
=
578 m_SheetNamedExpressions
.insert(std::make_pair(nTab
, ScMyNamedExpressions()));
585 ScMyNamedExpressions
& r
= itr
->second
;
586 r
.push_back(std::move(aNamedExp
));
589 ScXMLChangeTrackingImportHelper
* ScXMLImport::GetChangeTrackingImportHelper()
591 if (!pChangeTrackingImportHelper
)
592 pChangeTrackingImportHelper
.reset(new ScXMLChangeTrackingImportHelper());
593 return pChangeTrackingImportHelper
.get();
596 void ScXMLImport::InsertStyles()
598 GetStyles()->CopyStylesToDoc(true);
600 // if content is going to be loaded with the same import, set bLatinDefaultStyle flag now
601 if ( getImportFlags() & SvXMLImportFlags::CONTENT
)
602 ExamineDefaultStyle();
605 void ScXMLImport::ExamineDefaultStyle()
609 // #i62435# after inserting the styles, check if the default style has a latin-script-only
610 // number format (then, value cells can be pre-initialized with western script type)
612 const ScPatternAttr
* pDefPattern
= pDoc
->GetDefPattern();
613 if (pDefPattern
&& sc::NumFmtUtil::isLatinScript(*pDefPattern
, *pDoc
))
614 mpDocImport
->setDefaultNumericScript(SvtScriptType::LATIN
);
618 void ScXMLImport::SetChangeTrackingViewSettings(const css::uno::Sequence
<css::beans::PropertyValue
>& rChangeProps
)
623 if (!rChangeProps
.hasElements())
626 ScXMLImport::MutexGuard
aGuard(*this);
627 sal_Int16
nTemp16(0);
628 ScChangeViewSettings aViewSettings
;
629 for (const auto& rChangeProp
: rChangeProps
)
631 OUString
sName(rChangeProp
.Name
);
632 if (sName
== "ShowChanges")
633 aViewSettings
.SetShowChanges(::cppu::any2bool(rChangeProp
.Value
));
634 else if (sName
== "ShowAcceptedChanges")
635 aViewSettings
.SetShowAccepted(::cppu::any2bool(rChangeProp
.Value
));
636 else if (sName
== "ShowRejectedChanges")
637 aViewSettings
.SetShowRejected(::cppu::any2bool(rChangeProp
.Value
));
638 else if (sName
== "ShowChangesByDatetime")
639 aViewSettings
.SetHasDate(::cppu::any2bool(rChangeProp
.Value
));
640 else if (sName
== "ShowChangesByDatetimeMode")
642 if (rChangeProp
.Value
>>= nTemp16
)
643 aViewSettings
.SetTheDateMode(static_cast<SvxRedlinDateMode
>(nTemp16
));
645 else if (sName
== "ShowChangesByDatetimeFirstDatetime")
647 util::DateTime aDateTime
;
648 if (rChangeProp
.Value
>>= aDateTime
)
650 aViewSettings
.SetTheFirstDateTime(::DateTime(aDateTime
));
653 else if (sName
== "ShowChangesByDatetimeSecondDatetime")
655 util::DateTime aDateTime
;
656 if (rChangeProp
.Value
>>= aDateTime
)
658 aViewSettings
.SetTheLastDateTime(::DateTime(aDateTime
));
661 else if (sName
== "ShowChangesByAuthor")
662 aViewSettings
.SetHasAuthor(::cppu::any2bool(rChangeProp
.Value
));
663 else if (sName
== "ShowChangesByAuthorName")
666 if (rChangeProp
.Value
>>= sOUName
)
668 aViewSettings
.SetTheAuthorToShow(sOUName
);
671 else if (sName
== "ShowChangesByComment")
672 aViewSettings
.SetHasComment(::cppu::any2bool(rChangeProp
.Value
));
673 else if (sName
== "ShowChangesByCommentText")
676 if (rChangeProp
.Value
>>= sOUComment
)
678 aViewSettings
.SetTheComment(sOUComment
);
681 else if (sName
== "ShowChangesByRanges")
682 aViewSettings
.SetHasRange(::cppu::any2bool(rChangeProp
.Value
));
683 else if (sName
== "ShowChangesByRangesList")
686 if ((rChangeProp
.Value
>>= sRanges
) && !sRanges
.isEmpty())
688 ScRangeList aRangeList
;
689 ScRangeStringConverter::GetRangeListFromString(
690 aRangeList
, sRanges
, *pDoc
, FormulaGrammar::CONV_OOO
);
691 aViewSettings
.SetTheRangeList(aRangeList
);
695 pDoc
->SetChangeViewSettings(aViewSettings
);
698 void ScXMLImport::SetViewSettings(const uno::Sequence
<beans::PropertyValue
>& aViewProps
)
700 sal_Int32
nHeight(0);
704 for (const auto& rViewProp
: aViewProps
)
706 OUString
sName(rViewProp
.Name
);
707 if (sName
== "VisibleAreaHeight")
708 rViewProp
.Value
>>= nHeight
;
709 else if (sName
== "VisibleAreaLeft")
710 rViewProp
.Value
>>= nLeft
;
711 else if (sName
== "VisibleAreaTop")
712 rViewProp
.Value
>>= nTop
;
713 else if (sName
== "VisibleAreaWidth")
714 rViewProp
.Value
>>= nWidth
;
715 else if (sName
== "TrackedChangesViewSettings")
717 uno::Sequence
<beans::PropertyValue
> aChangeProps
;
718 if(rViewProp
.Value
>>= aChangeProps
)
719 SetChangeTrackingViewSettings(aChangeProps
);
722 if (!(nHeight
&& nWidth
&& GetModel().is()))
725 ScModelObj
* pDocObj(comphelper::getFromUnoTunnel
<ScModelObj
>( GetModel() ));
729 SfxObjectShell
* pEmbeddedObj
= pDocObj
->GetEmbeddedObject();
732 tools::Rectangle aRect
{ nLeft
, nTop
};
733 aRect
.setWidth( nWidth
);
734 aRect
.setHeight( nHeight
);
735 pEmbeddedObj
->SetVisArea(aRect
);
739 void ScXMLImport::SetConfigurationSettings(const uno::Sequence
<beans::PropertyValue
>& aConfigProps
)
741 if (!GetModel().is())
744 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
745 if (!xMultiServiceFactory
.is())
748 sal_Int32
nCount(aConfigProps
.getLength());
749 css::uno::Sequence
<css::beans::PropertyValue
> aFilteredProps(nCount
);
750 auto pFilteredProps
= aFilteredProps
.getArray();
751 sal_Int32 nFilteredPropsLen
= 0;
752 for (sal_Int32 i
= nCount
- 1; i
>= 0; --i
)
754 if (aConfigProps
[i
].Name
== "TrackedChangesProtectionKey")
757 if (aConfigProps
[i
].Value
>>= sKey
)
759 uno::Sequence
<sal_Int8
> aPass
;
760 ::comphelper::Base64::decode(aPass
, sKey
);
761 if (aPass
.hasElements())
763 if (pDoc
->GetChangeTrack())
764 pDoc
->GetChangeTrack()->SetProtection(aPass
);
767 std::set
<OUString
> aUsers
;
768 std::unique_ptr
<ScChangeTrack
> pTrack( new ScChangeTrack(*pDoc
, std::move(aUsers
)) );
769 pTrack
->SetProtection(aPass
);
770 pDoc
->SetChangeTrack(std::move(pTrack
));
775 // store the following items for later use (after document is loaded)
776 else if ((aConfigProps
[i
].Name
== "VBACompatibilityMode") || (aConfigProps
[i
].Name
== "ScriptConfiguration"))
778 uno::Reference
< beans::XPropertySet
> xImportInfo
= getImportInfo();
779 if (xImportInfo
.is())
781 uno::Reference
< beans::XPropertySetInfo
> xPropertySetInfo
= xImportInfo
->getPropertySetInfo();
782 if (xPropertySetInfo
.is() && xPropertySetInfo
->hasPropertyByName(aConfigProps
[i
].Name
))
783 xImportInfo
->setPropertyValue( aConfigProps
[i
].Name
, aConfigProps
[i
].Value
);
786 if (aConfigProps
[i
].Name
!= "LinkUpdateMode")
788 pFilteredProps
[nFilteredPropsLen
++] = aConfigProps
[i
];
791 aFilteredProps
.realloc(nFilteredPropsLen
);
792 uno::Reference
<uno::XInterface
> xInterface
= xMultiServiceFactory
->createInstance("com.sun.star.comp.SpreadsheetSettings");
793 uno::Reference
<beans::XPropertySet
> xProperties(xInterface
, uno::UNO_QUERY
);
794 if (xProperties
.is())
795 SvXMLUnitConverter::convertPropertySet(xProperties
, aFilteredProps
);
798 sal_Int32
ScXMLImport::SetCurrencySymbol(const sal_Int32 nKey
, std::u16string_view rCurrency
)
800 uno::Reference
<util::XNumberFormatsSupplier
> xNumberFormatsSupplier(GetNumberFormatsSupplier());
801 if (xNumberFormatsSupplier
.is())
803 uno::Reference
<util::XNumberFormats
> xLocalNumberFormats(xNumberFormatsSupplier
->getNumberFormats());
804 if (xLocalNumberFormats
.is())
806 OUString sFormatString
;
809 uno::Reference
<beans::XPropertySet
> xProperties(xLocalNumberFormats
->getByKey(nKey
));
810 if (xProperties
.is())
812 lang::Locale aLocale
;
813 if (GetDocument() && (xProperties
->getPropertyValue(SC_LOCALE
) >>= aLocale
))
816 ScXMLImport::MutexGuard
aGuard(*this);
817 LocaleDataWrapper
aLocaleData( comphelper::getProcessComponentContext(), LanguageTag( aLocale
) );
818 sFormatString
= "#" +
819 aLocaleData
.getNumThousandSep() +
821 aLocaleData
.getNumDecimalSep() +
826 sal_Int32 nNewKey
= xLocalNumberFormats
->queryKey(sFormatString
, aLocale
, true);
828 nNewKey
= xLocalNumberFormats
->addNew(sFormatString
, aLocale
);
833 catch ( const util::MalformedNumberFormatException
& rException
)
835 OUString sErrorMessage
="Error in Formatstring " +
836 sFormatString
+ " at position " +
837 OUString::number(rException
.CheckPos
);
838 uno::Sequence
<OUString
> aSeq
{ sErrorMessage
};
839 uno::Reference
<xml::sax::XLocator
> xLocator
;
840 SetError(XMLERROR_API
| XMLERROR_FLAG_ERROR
, aSeq
, rException
.Message
, xLocator
);
847 bool ScXMLImport::IsCurrencySymbol(const sal_Int32 nNumberFormat
, std::u16string_view sCurrentCurrency
, std::u16string_view sBankSymbol
)
849 uno::Reference
<util::XNumberFormatsSupplier
> xNumberFormatsSupplier(GetNumberFormatsSupplier());
850 if (xNumberFormatsSupplier
.is())
852 uno::Reference
<util::XNumberFormats
> xLocalNumberFormats(xNumberFormatsSupplier
->getNumberFormats());
853 if (xLocalNumberFormats
.is())
857 uno::Reference
<beans::XPropertySet
> xNumberPropertySet(xLocalNumberFormats
->getByKey(nNumberFormat
));
858 if (xNumberPropertySet
.is())
861 if ( xNumberPropertySet
->getPropertyValue(SC_CURRENCYSYMBOL
) >>= sTemp
)
863 if (sCurrentCurrency
== sTemp
)
865 // A release that saved an unknown currency may have
866 // saved the currency symbol of the number format
867 // instead of an ISO code bank symbol. In another
868 // release we may have a match for that. In this case
869 // sCurrentCurrency is the ISO code obtained through
870 // XMLNumberFormatAttributesExportHelper::GetCellType()
871 // and sBankSymbol is the currency symbol.
872 if (sCurrentCurrency
.size() == 3 && sBankSymbol
== sTemp
)
874 // #i61657# This may be a legacy currency symbol that changed in the meantime.
875 if (SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sCurrentCurrency
, sBankSymbol
) != nullptr)
877 // In the rare case that sCurrentCurrency is not the
878 // currency symbol, but a matching ISO code
879 // abbreviation instead that was obtained through
880 // XMLNumberFormatAttributesExportHelper::GetCellType(),
881 // check with the number format's symbol. This happens,
882 // for example, in the es_BO locale, where a legacy
883 // B$,BOB matched B$->BOP, which leads to
884 // sCurrentCurrency being BOP, and the previous call
885 // with BOP,BOB didn't find an entry, but B$,BOB will.
886 return SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sTemp
, sBankSymbol
) != nullptr;
890 catch ( uno::Exception
& )
892 OSL_FAIL("Numberformat not found");
899 void ScXMLImport::SetType(const uno::Reference
<beans::XPropertySet
>& rProperties
,
900 sal_Int32
& rNumberFormat
,
901 const sal_Int16 nCellType
,
902 std::u16string_view rCurrency
)
907 if ((nCellType
== util::NumberFormat::TEXT
) || (nCellType
== util::NumberFormat::UNDEFINED
))
910 if (rNumberFormat
== -1)
911 rProperties
->getPropertyValue( SC_UNONAME_NUMFMT
) >>= rNumberFormat
;
912 OSL_ENSURE(rNumberFormat
!= -1, "no NumberFormat");
914 // sCurrentCurrency may be the ISO code abbreviation if the currency
915 // symbol matches such, or if no match found the symbol itself!
916 OUString sCurrentCurrency
;
917 sal_Int32
nCurrentCellType(
918 GetNumberFormatAttributesExportHelper()->GetCellType(
919 rNumberFormat
, sCurrentCurrency
, bIsStandard
) & ~util::NumberFormat::DEFINED
);
920 // If the (numeric) cell type (number, currency, date, time, boolean)
921 // is different from the format type then for some combinations we may
922 // have to apply a format, e.g. in case the generator deduced format
923 // from type and did not apply a format but we don't keep a dedicated
924 // type internally. Specifically this is necessary if the cell type is
925 // not number but the format type is (i.e. General). Currency cells
926 // need extra attention, see calls of ScXMLImport::IsCurrencySymbol()
927 // and description within there and ScXMLImport::SetCurrencySymbol().
928 if ((nCellType
!= nCurrentCellType
) &&
929 (nCellType
!= util::NumberFormat::NUMBER
) &&
930 (bIsStandard
|| (nCellType
== util::NumberFormat::CURRENCY
)))
932 if (!xNumberFormats
.is())
934 uno::Reference
<util::XNumberFormatsSupplier
> xNumberFormatsSupplier(GetNumberFormatsSupplier());
935 if (xNumberFormatsSupplier
.is())
936 xNumberFormats
.set(xNumberFormatsSupplier
->getNumberFormats());
938 if (xNumberFormats
.is())
942 uno::Reference
< beans::XPropertySet
> xNumberFormatProperties(xNumberFormats
->getByKey(rNumberFormat
));
943 if (xNumberFormatProperties
.is())
945 if (nCellType
!= util::NumberFormat::CURRENCY
)
947 lang::Locale aLocale
;
948 if ( xNumberFormatProperties
->getPropertyValue(SC_LOCALE
) >>= aLocale
)
950 if (!xNumberFormatTypes
.is())
951 xNumberFormatTypes
.set(uno::Reference
<util::XNumberFormatTypes
>(xNumberFormats
, uno::UNO_QUERY
));
952 rProperties
->setPropertyValue( SC_UNONAME_NUMFMT
, uno::Any(xNumberFormatTypes
->getStandardFormat(nCellType
, aLocale
)) );
955 else if (!rCurrency
.empty() && !sCurrentCurrency
.isEmpty())
957 if (sCurrentCurrency
!= rCurrency
)
958 if (!IsCurrencySymbol(rNumberFormat
, sCurrentCurrency
, rCurrency
))
959 rProperties
->setPropertyValue( SC_UNONAME_NUMFMT
, uno::Any(SetCurrencySymbol(rNumberFormat
, rCurrency
)));
963 catch ( uno::Exception
& )
965 OSL_FAIL("Numberformat not found");
971 if ((nCellType
== util::NumberFormat::CURRENCY
) && !rCurrency
.empty() && !sCurrentCurrency
.isEmpty() &&
972 sCurrentCurrency
!= rCurrency
&& !IsCurrencySymbol(rNumberFormat
, sCurrentCurrency
, rCurrency
))
973 rProperties
->setPropertyValue( SC_UNONAME_NUMFMT
, uno::Any(SetCurrencySymbol(rNumberFormat
, rCurrency
)));
977 void ScXMLImport::SetStyleToRanges()
982 if (!sPrevStyleName
.isEmpty())
984 uno::Reference
<beans::XPropertySet
> xProperties (xSheetCellRanges
, uno::UNO_QUERY
);
985 if (xProperties
.is())
987 XMLTableStylesContext
*pStyles(static_cast<XMLTableStylesContext
*>(GetAutoStyles()));
988 XMLTableStyleContext
* pStyle
= nullptr;
990 pStyle
= const_cast<XMLTableStyleContext
*>(static_cast<const XMLTableStyleContext
*>(pStyles
->FindStyleChildContext(
991 XmlStyleFamily::TABLE_CELL
, sPrevStyleName
, true)));
994 pStyle
->FillPropertySet(xProperties
);
995 // here needs to be the cond format import method
996 sal_Int32
nNumberFormat(pStyle
->GetNumberFormat());
997 SetType(xProperties
, nNumberFormat
, nPrevCellType
, sPrevCurrency
);
999 css::uno::Any aAny
= xProperties
->getPropertyValue("FormatID");
1000 sal_uInt64 nKey
= 0;
1001 if ((aAny
>>= nKey
) && nKey
)
1003 ScFormatSaveData
* pFormatSaveData
= comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->GetFormatSaveData();
1004 pFormatSaveData
->maIDToName
.insert(std::pair
<sal_uInt64
, OUString
>(nKey
, sPrevStyleName
));
1007 // store first cell of first range for each style, once per sheet
1008 uno::Sequence
<table::CellRangeAddress
> aAddresses(xSheetCellRanges
->getRangeAddresses());
1009 pStyle
->ApplyCondFormat(aAddresses
);
1010 if ( aAddresses
.hasElements() )
1012 const table::CellRangeAddress
& rRange
= aAddresses
[0];
1013 if ( rRange
.Sheet
!= pStyle
->GetLastSheet() )
1015 ScSheetSaveData
* pSheetData
= comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->GetSheetSaveData();
1016 pSheetData
->AddCellStyle( sPrevStyleName
,
1017 ScAddress( static_cast<SCCOL
>(rRange
.StartColumn
), static_cast<SCROW
>(rRange
.StartRow
), static_cast<SCTAB
>(rRange
.Sheet
) ) );
1018 pStyle
->SetLastSheet(rRange
.Sheet
);
1024 xProperties
->setPropertyValue(SC_UNONAME_CELLSTYL
, uno::Any(GetStyleDisplayName( XmlStyleFamily::TABLE_CELL
, sPrevStyleName
)));
1025 sal_Int32
nNumberFormat(GetStyleNumberFormats()->GetStyleNumberFormat(sPrevStyleName
));
1026 bool bInsert(nNumberFormat
== -1);
1027 SetType(xProperties
, nNumberFormat
, nPrevCellType
, sPrevCurrency
);
1029 GetStyleNumberFormats()->AddStyleNumberFormat(sPrevStyleName
, nNumberFormat
);
1033 if (GetModel().is())
1035 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
1036 if (xMultiServiceFactory
.is())
1037 xSheetCellRanges
.set(uno::Reference
<sheet::XSheetCellRangeContainer
>(
1038 xMultiServiceFactory
->createInstance("com.sun.star.sheet.SheetCellRanges"),
1041 OSL_ENSURE(xSheetCellRanges
.is(), "didn't get SheetCellRanges");
1044 void ScXMLImport::SetStyleToRanges(const ScRangeList
& rRanges
, const OUString
* pStyleName
,
1045 const sal_Int16 nCellType
, const OUString
* pCurrency
)
1047 if (!mbImportStyles
)
1050 if (sPrevStyleName
.isEmpty())
1052 nPrevCellType
= nCellType
;
1054 sPrevStyleName
= *pStyleName
;
1056 sPrevCurrency
= *pCurrency
;
1057 else if (!sPrevCurrency
.isEmpty())
1058 sPrevCurrency
.clear();
1060 else if ((nCellType
!= nPrevCellType
) ||
1061 ((pStyleName
&& *pStyleName
!= sPrevStyleName
) ||
1062 (!pStyleName
&& !sPrevStyleName
.isEmpty())) ||
1063 ((pCurrency
&& *pCurrency
!= sPrevCurrency
) ||
1064 (!pCurrency
&& !sPrevCurrency
.isEmpty())))
1067 nPrevCellType
= nCellType
;
1069 sPrevStyleName
= *pStyleName
;
1070 else if(!sPrevStyleName
.isEmpty())
1071 sPrevStyleName
.clear();
1073 sPrevCurrency
= *pCurrency
;
1074 else if(!sPrevCurrency
.isEmpty())
1075 sPrevCurrency
.clear();
1078 if (!xSheetCellRanges
.is() && GetModel().is())
1080 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(GetModel(), uno::UNO_QUERY
);
1081 if (xMultiServiceFactory
.is())
1082 xSheetCellRanges
.set(uno::Reference
<sheet::XSheetCellRangeContainer
>(xMultiServiceFactory
->createInstance("com.sun.star.sheet.SheetCellRanges"), uno::UNO_QUERY
));
1083 OSL_ENSURE(xSheetCellRanges
.is(), "didn't get SheetCellRanges");
1086 static_cast<ScCellRangesObj
*>(xSheetCellRanges
.get())->SetNewRanges(rRanges
);
1089 bool ScXMLImport::SetNullDateOnUnitConverter()
1091 if (!bNullDateSetted
)
1092 bNullDateSetted
= GetMM100UnitConverter().setNullDate(GetModel());
1093 OSL_ENSURE(bNullDateSetted
, "could not set the null date");
1094 return bNullDateSetted
;
1097 XMLNumberFormatAttributesExportHelper
* ScXMLImport::GetNumberFormatAttributesExportHelper()
1099 if (!pNumberFormatAttributesExportHelper
)
1100 pNumberFormatAttributesExportHelper
.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier()));
1101 return pNumberFormatAttributesExportHelper
.get();
1104 ScMyStyleNumberFormats
* ScXMLImport::GetStyleNumberFormats()
1106 if (!pStyleNumberFormats
)
1107 pStyleNumberFormats
.reset(new ScMyStyleNumberFormats
);
1108 return pStyleNumberFormats
.get();
1111 void ScXMLImport::SetStylesToRangesFinished()
1114 sPrevStyleName
.clear();
1118 void SAL_CALL
ScXMLImport::setTargetDocument( const css::uno::Reference
< css::lang::XComponent
>& xDoc
)
1120 ScXMLImport::MutexGuard
aGuard(*this);
1121 SvXMLImport::setTargetDocument( xDoc
);
1123 uno::Reference
<frame::XModel
> xModel(xDoc
, uno::UNO_QUERY
);
1124 pDoc
= ScXMLConverter::GetScDocument( xModel
);
1125 OSL_ENSURE( pDoc
, "ScXMLImport::setTargetDocument - no ScDocument!" );
1127 throw lang::IllegalArgumentException();
1129 if (ScDocShell
* pDocSh
= static_cast<ScDocShell
*>(pDoc
->GetDocumentShell()))
1130 pDocSh
->SetInitialLinkUpdate( pDocSh
->GetMedium());
1132 mpDocImport
.reset(new ScDocumentImport(*pDoc
));
1133 mpComp
.reset(new ScCompiler(*pDoc
, ScAddress(), formula::FormulaGrammar::GRAM_ODFF
));
1135 uno::Reference
<document::XActionLockable
> xActionLockable(xDoc
, uno::UNO_QUERY
);
1136 if (xActionLockable
.is())
1137 xActionLockable
->addActionLock();
1140 // css::xml::sax::XDocumentHandler
1141 void SAL_CALL
ScXMLImport::startDocument()
1143 ScXMLImport::MutexGuard
aGuard(*this);
1144 SvXMLImport::startDocument();
1145 if (pDoc
&& !pDoc
->IsImportingXML())
1147 comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->BeforeXMLLoading();
1148 bSelfImportingXMLSet
= true;
1151 // if content and styles are loaded with separate imports,
1152 // set bLatinDefaultStyle flag at the start of the content import
1153 SvXMLImportFlags nFlags
= getImportFlags();
1154 if ( ( nFlags
& SvXMLImportFlags::CONTENT
) && !( nFlags
& SvXMLImportFlags::STYLES
) )
1155 ExamineDefaultStyle();
1157 if (getImportFlags() & SvXMLImportFlags::CONTENT
)
1159 if (GetModel().is())
1161 // store initial namespaces, to find the ones that were added from the file later
1162 ScSheetSaveData
* pSheetData
= comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->GetSheetSaveData();
1163 const SvXMLNamespaceMap
& rNamespaces
= GetNamespaceMap();
1164 pSheetData
->StoreInitialNamespaces(rNamespaces
);
1168 uno::Reference
< beans::XPropertySet
> const xImportInfo( getImportInfo() );
1169 uno::Reference
< beans::XPropertySetInfo
> const xPropertySetInfo(
1170 xImportInfo
.is() ? xImportInfo
->getPropertySetInfo() : nullptr);
1171 if (xPropertySetInfo
.is())
1173 OUString
const sOrganizerMode(
1175 if (xPropertySetInfo
->hasPropertyByName(sOrganizerMode
))
1177 bool bStyleOnly(false);
1178 if (xImportInfo
->getPropertyValue(sOrganizerMode
) >>= bStyleOnly
)
1180 bLoadDoc
= !bStyleOnly
;
1188 sal_Int32
ScXMLImport::GetRangeType(std::u16string_view sRangeType
)
1190 sal_Int32
nRangeType(0);
1191 OUStringBuffer sBuffer
;
1193 while (i
<= sRangeType
.size())
1195 if ((i
== sRangeType
.size()) || (sRangeType
[i
] == ' '))
1197 OUString sTemp
= sBuffer
.makeStringAndClear();
1198 if (sTemp
== "repeat-column")
1199 nRangeType
|= sheet::NamedRangeFlag::COLUMN_HEADER
;
1200 else if (sTemp
== SC_REPEAT_ROW
)
1201 nRangeType
|= sheet::NamedRangeFlag::ROW_HEADER
;
1202 else if (sTemp
== SC_FILTER
)
1203 nRangeType
|= sheet::NamedRangeFlag::FILTER_CRITERIA
;
1204 else if (sTemp
== SC_PRINT_RANGE
)
1205 nRangeType
|= sheet::NamedRangeFlag::PRINT_AREA
;
1207 else if (i
< sRangeType
.size())
1208 sBuffer
.append(sRangeType
[i
]);
1214 void ScXMLImport::SetLabelRanges()
1216 if (maMyLabelRanges
.empty())
1219 uno::Reference
<beans::XPropertySet
> xPropertySet (GetModel(), uno::UNO_QUERY
);
1220 if (!xPropertySet
.is())
1223 uno::Any aColAny
= xPropertySet
->getPropertyValue(SC_UNO_COLLABELRNG
);
1224 uno::Any aRowAny
= xPropertySet
->getPropertyValue(SC_UNO_ROWLABELRNG
);
1226 uno::Reference
< sheet::XLabelRanges
> xColRanges
;
1227 uno::Reference
< sheet::XLabelRanges
> xRowRanges
;
1229 if ( !(( aColAny
>>= xColRanges
) && ( aRowAny
>>= xRowRanges
)) )
1232 table::CellRangeAddress aLabelRange
;
1233 table::CellRangeAddress aDataRange
;
1235 for (const auto& rLabelRange
: maMyLabelRanges
)
1237 sal_Int32
nOffset1(0);
1238 sal_Int32
nOffset2(0);
1239 FormulaGrammar::AddressConvention eConv
= FormulaGrammar::CONV_OOO
;
1242 if (ScRangeStringConverter::GetRangeFromString( aLabelRange
, rLabelRange
.sLabelRangeStr
, *pDoc
, eConv
, nOffset1
) &&
1243 ScRangeStringConverter::GetRangeFromString( aDataRange
, rLabelRange
.sDataRangeStr
, *pDoc
, eConv
, nOffset2
))
1245 if ( rLabelRange
.bColumnOrientation
)
1246 xColRanges
->addNew( aLabelRange
, aDataRange
);
1248 xRowRanges
->addNew( aLabelRange
, aDataRange
);
1252 maMyLabelRanges
.clear();
1257 class RangeNameInserter
1260 ScRangeName
& mrRangeName
;
1264 RangeNameInserter(ScDocument
& rDoc
, ScRangeName
& rRangeName
, SCTAB nTab
) :
1265 mrDoc(rDoc
), mrRangeName(rRangeName
), mnTab(nTab
) {}
1267 void operator() (const ScMyNamedExpression
& p
) const
1269 using namespace formula
;
1271 const OUString
& aType
= p
.sRangeType
;
1272 sal_uInt32 nUnoType
= ScXMLImport::GetRangeType(aType
);
1274 ScRangeData::Type nNewType
= ScRangeData::Type::Name
;
1275 if ( nUnoType
& sheet::NamedRangeFlag::FILTER_CRITERIA
) nNewType
|= ScRangeData::Type::Criteria
;
1276 if ( nUnoType
& sheet::NamedRangeFlag::PRINT_AREA
) nNewType
|= ScRangeData::Type::PrintArea
;
1277 if ( nUnoType
& sheet::NamedRangeFlag::COLUMN_HEADER
) nNewType
|= ScRangeData::Type::ColHeader
;
1278 if ( nUnoType
& sheet::NamedRangeFlag::ROW_HEADER
) nNewType
|= ScRangeData::Type::RowHeader
;
1280 // Insert a new name.
1282 sal_Int32 nOffset
= 0;
1283 bool bSuccess
= ScRangeStringConverter::GetAddressFromString(
1284 aPos
, p
.sBaseCellAddress
, mrDoc
, FormulaGrammar::CONV_OOO
, nOffset
);
1288 SAL_WARN("sc.filter", "No conversion from table:base-cell-address '" << p
.sBaseCellAddress
1289 << "' for name '" << p
.sName
<< "' on sheet " << mnTab
);
1290 // Do not lose the defined name. Relative addressing in
1291 // content/expression, if any, will be broken though.
1292 // May had happened due to tdf#150312.
1293 aPos
.SetTab(mnTab
< 0 ? 0 : mnTab
);
1299 OUString aContent
= p
.sContent
;
1300 if (!p
.bIsExpression
)
1301 ScXMLConverter::ConvertCellRangeAddress(aContent
);
1303 ScRangeData
* pData
= new ScRangeData(
1304 mrDoc
, p
.sName
, aContent
, aPos
, nNewType
, p
.eGrammar
);
1305 mrRangeName
.insert(pData
);
1312 void ScXMLImport::SetNamedRanges()
1314 if (m_aMyNamedExpressions
.empty())
1320 // Insert the namedRanges
1321 ScRangeName
* pRangeNames
= pDoc
->GetRangeName();
1322 ::std::for_each(m_aMyNamedExpressions
.begin(), m_aMyNamedExpressions
.end(),
1323 RangeNameInserter(*pDoc
, *pRangeNames
, -1));
1326 void ScXMLImport::SetSheetNamedRanges()
1331 for (auto const& itr
: m_SheetNamedExpressions
)
1333 const SCTAB nTab
= itr
.first
;
1334 ScRangeName
* pRangeNames
= pDoc
->GetRangeName(nTab
);
1338 const ScMyNamedExpressions
& rNames
= itr
.second
;
1339 ::std::for_each(rNames
.begin(), rNames
.end(), RangeNameInserter(*pDoc
, *pRangeNames
, nTab
));
1343 void ScXMLImport::SetStringRefSyntaxIfMissing()
1348 ScCalcConfig aCalcConfig
= pDoc
->GetCalcConfig();
1350 // Has any string ref syntax been imported?
1351 // If not, we need to take action
1352 if ( !aCalcConfig
.mbHasStringRefSyntax
)
1354 aCalcConfig
.meStringRefAddressSyntax
= formula::FormulaGrammar::CONV_A1_XL_A1
;
1355 pDoc
->SetCalcConfig(aCalcConfig
);
1359 void SAL_CALL
ScXMLImport::endDocument()
1361 ScXMLImport::MutexGuard
aGuard(*this);
1362 if (getImportFlags() & SvXMLImportFlags::CONTENT
)
1364 if (GetModel().is())
1366 mpDocImport
->finalize();
1368 uno::Reference
<document::XViewDataSupplier
> xViewDataSupplier(GetModel(), uno::UNO_QUERY
);
1369 if (xViewDataSupplier
.is())
1371 uno::Reference
<container::XIndexAccess
> xIndexAccess(xViewDataSupplier
->getViewData());
1372 if (xIndexAccess
.is() && xIndexAccess
->getCount() > 0)
1374 uno::Sequence
< beans::PropertyValue
> aSeq
;
1375 if (xIndexAccess
->getByIndex(0) >>= aSeq
)
1377 for (const auto& rProp
: std::as_const(aSeq
))
1379 OUString
sName(rProp
.Name
);
1380 if (sName
== SC_ACTIVETABLE
)
1383 if(rProp
.Value
>>= sTabName
)
1386 if (pDoc
->GetTable(sTabName
, nTab
))
1388 pDoc
->SetVisibleTab(nTab
);
1399 SetSheetNamedRanges();
1400 SetStringRefSyntaxIfMissing();
1402 // Process pivot table sources after the named ranges have been set.
1403 mpPivotSources
->process();
1405 GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
1410 // After CompileXML, links must be completely changed to the new URLs.
1411 // Otherwise, hasExternalFile for API wouldn't work (#i116940#),
1412 // and typing a new formula would create a second link with the same "real" file name.
1413 if (pDoc
->HasExternalRefManager())
1414 pDoc
->GetExternalRefManager()->updateAbsAfterLoad();
1417 // If the stream contains cells outside of the current limits, the styles can't be re-created,
1418 // so stream copying is disabled then.
1419 if (pDoc
&& GetModel().is() && !pDoc
->HasRangeOverflow())
1421 // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
1422 // in UpdateRowHeights can already clear the flags again)
1423 ScSheetSaveData
* pSheetData
= comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->GetSheetSaveData();
1425 SCTAB nTabCount
= pDoc
->GetTableCount();
1426 for (SCTAB nTab
=0; nTab
<nTabCount
; ++nTab
)
1428 pDoc
->SetDrawPageSize(nTab
);
1429 if (!pSheetData
->IsSheetBlocked( nTab
))
1430 pDoc
->SetStreamValid( nTab
, true );
1434 // There are rows with optimal height which need to be updated
1435 if (pDoc
&& !maRecalcRowRanges
.empty())
1437 bool bLockHeight
= pDoc
->IsAdjustHeightLocked();
1440 pDoc
->UnlockAdjustHeight();
1443 ScSizeDeviceProvider
aProv(static_cast<ScDocShell
*>(pDoc
->GetDocumentShell()));
1444 ScDocRowHeightUpdater
aUpdater(*pDoc
, aProv
.GetDevice(), aProv
.GetPPTX(), aProv
.GetPPTY(), &maRecalcRowRanges
);
1449 pDoc
->LockAdjustHeight();
1453 // Initialize and set position and size of objects
1454 if (pDoc
&& pDoc
->GetDrawLayer())
1456 ScDrawLayer
* pDrawLayer
= pDoc
->GetDrawLayer();
1457 SCTAB nTabCount
= pDoc
->GetTableCount();
1458 for (SCTAB nTab
= 0; nTab
< nTabCount
; ++nTab
)
1460 const SdrPage
* pPage
= pDrawLayer
->GetPage(nTab
);
1463 bool bNegativePage
= pDoc
->IsNegativePage(nTab
);
1464 const size_t nCount
= pPage
->GetObjCount();
1465 for (size_t i
= 0; i
< nCount
; ++i
)
1467 SdrObject
* pObj
= pPage
->GetObj(i
);
1468 ScDrawObjData
* pData
1469 = ScDrawLayer::GetObjDataTab(pObj
, nTab
);
1470 // Existence of pData means, that it is a cell anchored object
1473 // Finish and correct import based on full size (no hidden row/col) and LTR
1474 pDrawLayer
->InitializeCellAnchoredObj(pObj
, *pData
);
1475 // Adapt object to hidden row/col and RTL
1476 pDrawLayer
->RecalcPos(pObj
, *pData
, bNegativePage
,
1477 true /*bUpdateNoteCaptionPos*/);
1483 aTables
.FixupOLEs();
1485 if (GetModel().is())
1487 uno::Reference
<document::XActionLockable
> xActionLockable(GetModel(), uno::UNO_QUERY
);
1488 if (xActionLockable
.is())
1489 xActionLockable
->removeActionLock();
1491 SvXMLImport::endDocument();
1495 pDoc
->BroadcastUno(SfxHint(SfxHintId::ScClearCache
));
1498 if(pDoc
&& bSelfImportingXMLSet
)
1499 comphelper::getFromUnoTunnel
<ScModelObj
>(GetModel())->AfterXMLLoading();
1503 void ScXMLImport::DisposingModel()
1505 SvXMLImport::DisposingModel();
1509 ScXMLImport::MutexGuard::MutexGuard(ScXMLImport
& rImport
) :
1512 mrImport
.LockSolarMutex();
1515 ScXMLImport::MutexGuard::~MutexGuard()
1517 mrImport
.UnlockSolarMutex();
1520 void ScXMLImport::LockSolarMutex()
1522 // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked,
1523 // so there's no need to allocate (and later delete) the SolarMutexGuard.
1524 if (!mbLockSolarMutex
)
1526 DBG_TESTSOLARMUTEX();
1530 if (nSolarMutexLocked
== 0)
1532 OSL_ENSURE(!pSolarMutexGuard
, "Solar Mutex is locked");
1533 pSolarMutexGuard
.reset(new SolarMutexGuard());
1535 ++nSolarMutexLocked
;
1538 void ScXMLImport::UnlockSolarMutex()
1540 if (nSolarMutexLocked
> 0)
1542 nSolarMutexLocked
--;
1543 if (nSolarMutexLocked
== 0)
1545 OSL_ENSURE(pSolarMutexGuard
, "Solar Mutex is always unlocked");
1546 pSolarMutexGuard
.reset();
1551 sal_Int32
ScXMLImport::GetByteOffset() const
1553 sal_Int32 nOffset
= -1;
1554 uno::Reference
<xml::sax::XLocator
> xLocator
= GetLocator();
1555 uno::Reference
<io::XSeekable
> xSeek( xLocator
, uno::UNO_QUERY
); //! should use different interface
1557 nOffset
= static_cast<sal_Int32
>(xSeek
->getPosition());
1561 void ScXMLImport::SetRangeOverflowType(ErrCode nType
)
1563 // #i31130# Overflow is stored in the document, because the ScXMLImport object
1564 // isn't available in ScXMLImportWrapper::ImportFromComponent when using the
1565 // OOo->Oasis transformation.
1568 pDoc
->SetRangeOverflowType( nType
);
1571 void ScXMLImport::ProgressBarIncrement()
1574 if (nProgressCount
> 100)
1576 GetProgressBarHelper()->Increment(nProgressCount
);
1581 void ScXMLImport::ExtractFormulaNamespaceGrammar(
1582 OUString
& rFormula
, OUString
& rFormulaNmsp
, FormulaGrammar::Grammar
& reGrammar
,
1583 const OUString
& rAttrValue
, bool bRestrictToExternalNmsp
) const
1585 // parse the attribute value, extract namespace ID, literal namespace, and formula string
1586 rFormulaNmsp
.clear();
1587 sal_uInt16 nNsId
= GetNamespaceMap().GetKeyByQName(rAttrValue
, nullptr, &rFormula
, &rFormulaNmsp
, SvXMLNamespaceMap::QNameMode::AttrValue
);
1589 // check if we have an ODF formula namespace
1590 if( !bRestrictToExternalNmsp
) switch( nNsId
)
1592 case XML_NAMESPACE_OOOC
:
1593 rFormulaNmsp
.clear(); // remove namespace string for built-in grammar
1594 reGrammar
= FormulaGrammar::GRAM_PODF
;
1596 case XML_NAMESPACE_OF
:
1597 rFormulaNmsp
.clear(); // remove namespace string for built-in grammar
1598 reGrammar
= FormulaGrammar::GRAM_ODFF
;
1602 /* Find default grammar for formulas without namespace. There may be
1603 documents in the wild that stored no namespace in ODF 1.0/1.1. Use
1604 GRAM_PODF then (old style ODF 1.0/1.1 formulas). The default for ODF
1605 1.2 and later without namespace is GRAM_ODFF (OpenFormula). */
1606 FormulaGrammar::Grammar eDefaultGrammar
=
1607 (GetDocument()->GetStorageGrammar() == FormulaGrammar::GRAM_PODF
) ?
1608 FormulaGrammar::GRAM_PODF
: FormulaGrammar::GRAM_ODFF
;
1610 /* Check if we have no namespace at all. The value XML_NAMESPACE_NONE
1611 indicates that there is no colon. If the first character of the
1612 attribute value is the equality sign, the value XML_NAMESPACE_UNKNOWN
1613 indicates that there is a colon somewhere in the formula string. */
1614 if( (nNsId
== XML_NAMESPACE_NONE
) || ((nNsId
== XML_NAMESPACE_UNKNOWN
) && (rAttrValue
.toChar() == '=')) )
1616 rFormula
= rAttrValue
; // return entire string as formula
1617 reGrammar
= eDefaultGrammar
;
1621 /* Check if a namespace URL could be resolved from the attribute value.
1622 Use that namespace only, if the Calc document knows an associated
1623 external formula parser. This prevents that the range operator in
1624 conjunction with defined names is confused as namespaces prefix, e.g.
1625 in the expression 'table:A1' where 'table' is a named reference. */
1626 if( ((nNsId
& XML_NAMESPACE_UNKNOWN_FLAG
) != 0) && !rFormulaNmsp
.isEmpty() &&
1627 GetDocument()->GetFormulaParserPool().hasFormulaParser( rFormulaNmsp
) )
1629 reGrammar
= FormulaGrammar::GRAM_EXTERNAL
;
1633 /* All attempts failed (e.g. no namespace and no leading equality sign, or
1634 an invalid namespace prefix), continue with the entire attribute value. */
1635 rFormula
= rAttrValue
;
1636 rFormulaNmsp
.clear(); // remove any namespace string
1637 reGrammar
= eDefaultGrammar
;
1640 FormulaError
ScXMLImport::GetFormulaErrorConstant( const OUString
& rStr
) const
1643 return FormulaError::NONE
;
1645 return mpComp
->GetErrorConstant(rStr
);
1648 ScEditEngineDefaulter
* ScXMLImport::GetEditEngine()
1652 mpEditEngine
.reset(new ScEditEngineDefaulter(pDoc
->GetEnginePool()));
1653 mpEditEngine
->SetRefMapMode(MapMode(MapUnit::Map100thMM
));
1654 mpEditEngine
->SetEditTextObjectPool(pDoc
->GetEditPool());
1655 mpEditEngine
->SetUpdateLayout(false);
1656 mpEditEngine
->EnableUndo(false);
1657 mpEditEngine
->SetControlWord(mpEditEngine
->GetControlWord() & ~EEControlBits::ALLOWBIGOBJS
);
1659 return mpEditEngine
.get();
1662 const ScXMLEditAttributeMap
& ScXMLImport::GetEditAttributeMap() const
1665 mpEditAttrMap
.reset(new ScXMLEditAttributeMap
);
1666 return *mpEditAttrMap
;
1669 void ScXMLImport::NotifyContainsEmbeddedFont()
1672 pDoc
->SetEmbedFonts(true);
1675 ScMyImpDetectiveOpArray
* ScXMLImport::GetDetectiveOpArray()
1677 if (!pDetectiveOpArray
)
1678 pDetectiveOpArray
.reset(new ScMyImpDetectiveOpArray());
1679 return pDetectiveOpArray
.get();
1682 extern "C" SAL_DLLPUBLIC_EXPORT
bool TestImportFODS(SvStream
&rStream
)
1686 SfxObjectShellLock
xDocSh(new ScDocShell
);
1687 xDocSh
->DoInitNew();
1688 uno::Reference
<frame::XModel
> xModel(xDocSh
->GetModel());
1690 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1691 uno::Reference
<io::XInputStream
> xStream(new ::utl::OSeekableInputStreamWrapper(rStream
));
1692 uno::Reference
<uno::XInterface
> xInterface(xMultiServiceFactory
->createInstance("com.sun.star.comp.Writer.XmlFilterAdaptor"), uno::UNO_SET_THROW
);
1694 css::uno::Sequence
<OUString
> aUserData
1696 "com.sun.star.comp.filter.OdfFlatXml",
1698 "com.sun.star.comp.Calc.XMLOasisImporter",
1699 "com.sun.star.comp.Calc.XMLOasisExporter",
1704 uno::Sequence
<beans::PropertyValue
> aAdaptorArgs(comphelper::InitPropertySequence(
1706 { "UserData", uno::Any(aUserData
) },
1708 css::uno::Sequence
<uno::Any
> aOuterArgs
{ uno::Any(aAdaptorArgs
) };
1710 uno::Reference
<lang::XInitialization
> xInit(xInterface
, uno::UNO_QUERY_THROW
);
1711 xInit
->initialize(aOuterArgs
);
1713 uno::Reference
<document::XImporter
> xImporter(xInterface
, uno::UNO_QUERY_THROW
);
1714 uno::Sequence
<beans::PropertyValue
> aArgs(comphelper::InitPropertySequence(
1716 { "InputStream", uno::Any(xStream
) },
1717 { "URL", uno::Any(OUString("private:stream")) },
1719 xImporter
->setTargetDocument(xModel
);
1721 uno::Reference
<document::XFilter
> xFilter(xInterface
, uno::UNO_QUERY_THROW
);
1722 //SetLoading hack because the document properties will be re-initted
1723 //by the xml filter and during the init, while it's considered uninitialized,
1724 //setting a property will inform the document it's modified, which attempts
1725 //to update the properties, which throws cause the properties are uninitialized
1726 xDocSh
->SetLoading(SfxLoadedFlags::NONE
);
1727 bool ret
= xFilter
->filter(aArgs
);
1728 xDocSh
->SetLoading(SfxLoadedFlags::ALL
);
1735 extern "C" SAL_DLLPUBLIC_EXPORT
bool TestImportXLSX(SvStream
&rStream
)
1739 SfxObjectShellLock
xDocSh(new ScDocShell
);
1740 xDocSh
->DoInitNew();
1741 uno::Reference
<frame::XModel
> xModel(xDocSh
->GetModel());
1743 uno::Reference
<lang::XMultiServiceFactory
> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1744 uno::Reference
<io::XInputStream
> xStream(new utl::OSeekableInputStreamWrapper(rStream
));
1746 uno::Reference
<document::XFilter
> xFilter(xMultiServiceFactory
->createInstance("com.sun.star.comp.oox.xls.ExcelFilter"), uno::UNO_QUERY_THROW
);
1748 uno::Reference
<document::XImporter
> xImporter(xFilter
, uno::UNO_QUERY_THROW
);
1749 uno::Sequence
<beans::PropertyValue
> aArgs(comphelper::InitPropertySequence(
1751 { "InputStream", uno::Any(xStream
) },
1752 { "InputMode", uno::Any(true) },
1754 xImporter
->setTargetDocument(xModel
);
1756 //SetLoading hack because the document properties will be re-initted
1757 //by the xml filter and during the init, while it's considered uninitialized,
1758 //setting a property will inform the document it's modified, which attempts
1759 //to update the properties, which throws cause the properties are uninitialized
1760 xDocSh
->SetLoading(SfxLoadedFlags::NONE
);
1764 ret
= xFilter
->filter(aArgs
);
1766 catch (const css::io::IOException
&)
1769 catch (const css::lang::WrappedTargetRuntimeException
&)
1772 xDocSh
->SetLoading(SfxLoadedFlags::ALL
);
1779 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */