1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
20 #include <sal/config.h>
21 #include <sal/log.hxx>
22 #include <osl/diagnose.h>
23 
24 #include <svl/zforlist.hxx>
25 
26 #include <xmloff/nmspmap.hxx>
27 #include <xmloff/xmlnmspe.hxx>
28 #include <xmloff/xmltkmap.hxx>
29 #include <xmloff/xmlictxt.hxx>
30 #include <xmloff/xmlmetai.hxx>
31 #include <sfx2/objsh.hxx>
32 #include <unotools/streamwrap.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 
42 #include <svl/languageoptions.hxx>
43 #include <editeng/editstat.hxx>
44 #include <formula/errorcodes.hxx>
45 #include <vcl/svapp.hxx>
46 
47 #include <appluno.hxx>
48 #include "xmlimprt.hxx"
49 #include "importcontext.hxx"
50 #include <document.hxx>
51 #include <docsh.hxx>
52 #include <docuno.hxx>
53 #include "xmlbodyi.hxx"
54 #include "xmlstyli.hxx"
55 #include <ViewSettingsSequenceDefines.hxx>
56 
57 #include <compiler.hxx>
58 
59 #include "XMLConverter.hxx"
60 #include "XMLDetectiveContext.hxx"
61 #include "XMLTableShapeImportHelper.hxx"
62 #include "XMLChangeTrackingImportHelper.hxx"
63 #include <chgviset.hxx>
64 #include "XMLStylesImportHelper.hxx"
65 #include <sheetdata.hxx>
66 #include <rangeutl.hxx>
67 #include <formulaparserpool.hxx>
68 #include <externalrefmgr.hxx>
69 #include <editutil.hxx>
70 #include "editattributemap.hxx"
71 #include <documentimport.hxx>
72 #include "pivotsource.hxx"
73 #include <unonames.hxx>
74 #include <numformat.hxx>
75 #include <sizedev.hxx>
76 #include <scdll.hxx>
77 #include "xmlstyle.hxx"
78 
79 #include <comphelper/base64.hxx>
80 #include <comphelper/extract.hxx>
81 #include <comphelper/propertysequence.hxx>
82 #include <comphelper/processfactory.hxx>
83 
84 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
85 #include <com/sun/star/frame/XModel.hpp>
86 #include <com/sun/star/io/IOException.hpp>
87 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
88 #include <com/sun/star/document/XActionLockable.hpp>
89 #include <com/sun/star/util/MalformedNumberFormatException.hpp>
90 #include <com/sun/star/util/NumberFormat.hpp>
91 #include <com/sun/star/util/XNumberFormatTypes.hpp>
92 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
93 #include <com/sun/star/sheet/NamedRangeFlag.hpp>
94 #include <com/sun/star/sheet/XLabelRanges.hpp>
95 #include <com/sun/star/io/XSeekable.hpp>
96 #include <com/sun/star/beans/XPropertySet.hpp>
97 #include <com/sun/star/sheet/XSheetCellRangeContainer.hpp>
98 
99 #include <memory>
100 #include <utility>
101 
102 #define SC_LOCALE           "Locale"
103 #define SC_CURRENCYSYMBOL   "CurrencySymbol"
104 #define SC_REPEAT_ROW "repeat-row"
105 #define SC_FILTER "filter"
106 #define SC_PRINT_RANGE "print-range"
107 
108 using namespace com::sun::star;
109 using namespace ::xmloff::token;
110 using namespace ::formula;
111 
ScXMLImport_getImplementationName()112 OUString ScXMLImport_getImplementationName() throw()
113 {
114     return "com.sun.star.comp.Calc.XMLOasisImporter";
115 }
116 
ScXMLImport_getSupportedServiceNames()117 uno::Sequence< OUString > ScXMLImport_getSupportedServiceNames() throw()
118 {
119     return { ScXMLImport_getImplementationName() };
120 }
121 
ScXMLImport_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)122 uno::Reference< uno::XInterface > ScXMLImport_createInstance(
123     const uno::Reference< lang::XMultiServiceFactory > & rSMgr )
124 {
125     // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_ALL);
126     return static_cast<cppu::OWeakObject*>(new ScXMLImport( comphelper::getComponentContext(rSMgr), ScXMLImport_getImplementationName(), SvXMLImportFlags::ALL ));
127 }
128 
ScXMLImport_Meta_getImplementationName()129 OUString ScXMLImport_Meta_getImplementationName() throw()
130 {
131     return "com.sun.star.comp.Calc.XMLOasisMetaImporter";
132 }
133 
ScXMLImport_Meta_getSupportedServiceNames()134 uno::Sequence< OUString > ScXMLImport_Meta_getSupportedServiceNames() throw()
135 {
136     return { ScXMLImport_Meta_getImplementationName() };
137 }
138 
ScXMLImport_Meta_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)139 uno::Reference< uno::XInterface > ScXMLImport_Meta_createInstance(
140     const uno::Reference< lang::XMultiServiceFactory > & rSMgr )
141 {
142     // return (cppu::OWeakObject*)new ScXMLImport(IMPORT_META);
143     return static_cast<cppu::OWeakObject*>(new ScXMLImport( comphelper::getComponentContext(rSMgr), ScXMLImport_Meta_getImplementationName(), SvXMLImportFlags::META ));
144 }
145 
ScXMLImport_Styles_getImplementationName()146 OUString ScXMLImport_Styles_getImplementationName() throw()
147 {
148     return "com.sun.star.comp.Calc.XMLOasisStylesImporter";
149 }
150 
ScXMLImport_Styles_getSupportedServiceNames()151 uno::Sequence< OUString > ScXMLImport_Styles_getSupportedServiceNames() throw()
152 {
153     return { ScXMLImport_Styles_getImplementationName() };
154 }
155 
ScXMLImport_Styles_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)156 uno::Reference< uno::XInterface > ScXMLImport_Styles_createInstance(
157     const uno::Reference< lang::XMultiServiceFactory > & rSMgr )
158 {
159     // return (cppu::OWeakObject*)new ScXMLImport(SvXMLImportFlagsSTYLES|SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::MASTERSTYLES|SvXMLImportFlags::FONTDECLS);
160     return static_cast<cppu::OWeakObject*>(new ScXMLImport( comphelper::getComponentContext(rSMgr), ScXMLImport_Styles_getImplementationName(), SvXMLImportFlags::STYLES|SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::MASTERSTYLES|SvXMLImportFlags::FONTDECLS));
161 }
162 
ScXMLImport_Content_getImplementationName()163 OUString ScXMLImport_Content_getImplementationName() throw()
164 {
165     return "com.sun.star.comp.Calc.XMLOasisContentImporter";
166 }
167 
ScXMLImport_Content_getSupportedServiceNames()168 uno::Sequence< OUString > ScXMLImport_Content_getSupportedServiceNames() throw()
169 {
170     return { ScXMLImport_Content_getImplementationName() };
171 }
172 
ScXMLImport_Content_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)173 uno::Reference< uno::XInterface > ScXMLImport_Content_createInstance(
174     const uno::Reference< lang::XMultiServiceFactory > & rSMgr )
175 {
176     // return (cppu::OWeakObject*)new ScXMLImport(SvXMLImportFlags::META|SvXMLImportFlags::STYLES|SvXMLImportFlags::MASTERSTYLES|SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SCRIPTS|SvXMLImportFlags::SETTINGS|SvXMLImportFlags::FONTDECLS);
177     return static_cast<cppu::OWeakObject*>(new ScXMLImport( comphelper::getComponentContext(rSMgr), ScXMLImport_Content_getImplementationName(), SvXMLImportFlags::AUTOSTYLES|SvXMLImportFlags::CONTENT|SvXMLImportFlags::SCRIPTS|SvXMLImportFlags::FONTDECLS));
178 }
179 
ScXMLImport_Settings_getImplementationName()180 OUString ScXMLImport_Settings_getImplementationName() throw()
181 {
182     return "com.sun.star.comp.Calc.XMLOasisSettingsImporter";
183 }
184 
ScXMLImport_Settings_getSupportedServiceNames()185 uno::Sequence< OUString > ScXMLImport_Settings_getSupportedServiceNames() throw()
186 {
187     return { ScXMLImport_Settings_getImplementationName() };
188 }
189 
ScXMLImport_Settings_createInstance(const uno::Reference<lang::XMultiServiceFactory> & rSMgr)190 uno::Reference< uno::XInterface > ScXMLImport_Settings_createInstance(
191     const uno::Reference< lang::XMultiServiceFactory > & rSMgr )
192 {
193     // return (cppu::OWeakObject*)new ScXMLImport(SvXMLImportFlags::SETTINGS);
194     return static_cast<cppu::OWeakObject*>(new ScXMLImport( comphelper::getComponentContext(rSMgr), ScXMLImport_Settings_getImplementationName(), SvXMLImportFlags::SETTINGS ));
195 }
196 
GetTableRowCellAttrTokenMap()197 const SvXMLTokenMap& ScXMLImport::GetTableRowCellAttrTokenMap()
198 {
199     static const SvXMLTokenMapEntry aTableRowCellAttrTokenMap[] =
200     {
201         { XML_NAMESPACE_TABLE,  XML_STYLE_NAME,                     XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME              },
202         { XML_NAMESPACE_TABLE,  XML_CONTENT_VALIDATION_NAME,        XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME },
203         { XML_NAMESPACE_TABLE,  XML_NUMBER_ROWS_SPANNED,            XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS            },
204         { XML_NAMESPACE_TABLE,  XML_NUMBER_COLUMNS_SPANNED,         XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS            },
205         { XML_NAMESPACE_TABLE,  XML_NUMBER_MATRIX_COLUMNS_SPANNED,  XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS     },
206         { XML_NAMESPACE_TABLE,  XML_NUMBER_MATRIX_ROWS_SPANNED,     XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS     },
207         { XML_NAMESPACE_TABLE,  XML_NUMBER_COLUMNS_REPEATED,        XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED                },
208         { XML_NAMESPACE_OFFICE, XML_VALUE_TYPE,                     XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE              },
209         { XML_NAMESPACE_CALC_EXT, XML_VALUE_TYPE,                   XML_TOK_TABLE_ROW_CELL_ATTR_NEW_VALUE_TYPE          },
210         { XML_NAMESPACE_OFFICE, XML_VALUE,                          XML_TOK_TABLE_ROW_CELL_ATTR_VALUE                   },
211         { XML_NAMESPACE_OFFICE, XML_DATE_VALUE,                     XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE              },
212         { XML_NAMESPACE_OFFICE, XML_TIME_VALUE,                     XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE              },
213         { XML_NAMESPACE_OFFICE, XML_STRING_VALUE,                   XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE            },
214         { XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE,                  XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE           },
215         { XML_NAMESPACE_TABLE,  XML_FORMULA,                        XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA                 },
216         { XML_NAMESPACE_OFFICE, XML_CURRENCY,                       XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY                },
217         XML_TOKEN_MAP_END
218     };
219 
220     if ( !pTableRowCellAttrTokenMap )
221         pTableRowCellAttrTokenMap.reset(new SvXMLTokenMap( aTableRowCellAttrTokenMap ));
222     return *pTableRowCellAttrTokenMap;
223 }
224 
225 // NB: virtually inherit so we can multiply inherit properly
226 //     in ScXMLFlatDocContext_Impl
227 class ScXMLDocContext_Impl : public virtual SvXMLImportContext
228 {
229 protected:
GetScImport()230     ScXMLImport& GetScImport() { return static_cast<ScXMLImport&>(GetImport()); }
231 
232 public:
233     ScXMLDocContext_Impl( ScXMLImport& rImport );
234 
235     virtual SvXMLImportContextRef CreateChildContext( sal_uInt16 nPrefix,
236         const OUString& rLocalName,
237         const uno::Reference<xml::sax::XAttributeList>& xAttrList ) override;
238 
239     virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
240         createFastChildContext( sal_Int32 nElement,
241         const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
242 
243     virtual void SAL_CALL startFastElement (sal_Int32 nElement,
244         const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) override;
245 
246     virtual void SAL_CALL characters(const OUString & aChars) override;
247 
248     virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
249 };
250 
ScXMLDocContext_Impl(ScXMLImport & rImport)251 ScXMLDocContext_Impl::ScXMLDocContext_Impl( ScXMLImport& rImport ) :
252 SvXMLImportContext( rImport )
253 {
254 }
255 
256 // context for flat file xml format
257 class ScXMLFlatDocContext_Impl
258     : public ScXMLDocContext_Impl, public SvXMLMetaDocumentContext
259 {
260 public:
261 
262     ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
263         const uno::Reference<document::XDocumentProperties>& i_xDocProps);
264 
265     virtual void SAL_CALL startFastElement (sal_Int32 nElement,
266         const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList) override;
267 
268     virtual void SAL_CALL endFastElement(sal_Int32 nElement) override;
269 
270     virtual void SAL_CALL characters( const OUString& aChars ) override;
271 
272     virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
273         createFastChildContext( sal_Int32 nElement,
274         const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
275 };
276 
ScXMLFlatDocContext_Impl(ScXMLImport & i_rImport,const uno::Reference<document::XDocumentProperties> & i_xDocProps)277 ScXMLFlatDocContext_Impl::ScXMLFlatDocContext_Impl( ScXMLImport& i_rImport,
278                                                    const uno::Reference<document::XDocumentProperties>& i_xDocProps) :
279 SvXMLImportContext(i_rImport),
280 ScXMLDocContext_Impl(i_rImport),
281 SvXMLMetaDocumentContext(i_rImport, i_xDocProps)
282 {
283 }
284 
285 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
createFastChildContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> & xAttrList)286     ScXMLFlatDocContext_Impl::createFastChildContext( sal_Int32 nElement,
287     const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
288 {
289     if ( nElement == XML_ELEMENT( OFFICE, XML_META ) )
290         return SvXMLMetaDocumentContext::createFastChildContext( nElement, xAttrList );
291     else
292         return ScXMLDocContext_Impl::createFastChildContext( nElement, xAttrList );
293 }
294 
startFastElement(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> & xAttrList)295 void SAL_CALL ScXMLFlatDocContext_Impl::startFastElement(sal_Int32 nElement,
296     const uno::Reference< xml::sax::XFastAttributeList > & xAttrList)
297 {
298     SvXMLMetaDocumentContext::startFastElement( nElement, xAttrList );
299 }
300 
endFastElement(sal_Int32 nElement)301 void SAL_CALL ScXMLFlatDocContext_Impl::endFastElement(sal_Int32 nElement)
302 {
303     SvXMLMetaDocumentContext::endFastElement( nElement );
304 }
305 
characters(const OUString & rChars)306 void SAL_CALL ScXMLFlatDocContext_Impl::characters(const OUString& rChars)
307 {
308     SvXMLMetaDocumentContext::characters(rChars);
309 }
310 
311 class ScXMLBodyContext_Impl : public ScXMLImportContext
312 {
313 public:
314     ScXMLBodyContext_Impl( ScXMLImport& rImport );
315 
316     virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL
317         createFastChildContext( sal_Int32 nElement,
318         const css::uno::Reference<css::xml::sax::XFastAttributeList>& xAttrList ) override;
319 };
320 
ScXMLBodyContext_Impl(ScXMLImport & rImport)321 ScXMLBodyContext_Impl::ScXMLBodyContext_Impl( ScXMLImport& rImport ) :
322 ScXMLImportContext( rImport )
323 {
324 }
325 
326 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
createFastChildContext(sal_Int32,const uno::Reference<xml::sax::XFastAttributeList> & xAttrList)327     ScXMLBodyContext_Impl::createFastChildContext( sal_Int32 /*nElement*/,
328     const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
329 {
330     sax_fastparser::FastAttributeList *pAttribList =
331         sax_fastparser::FastAttributeList::castToFastAttributeList( xAttrList );
332     return GetScImport().CreateBodyContext( pAttribList );
333 }
334 
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)335 SvXMLImportContextRef ScXMLDocContext_Impl::CreateChildContext( sal_uInt16 nPrefix,
336                                                              const OUString& rLocalName,
337                                                              const uno::Reference<xml::sax::XAttributeList>& xAttrList )
338 {
339     SvXMLImportContext *pContext(nullptr);
340 
341     const SvXMLTokenMap& rTokenMap(GetScImport().GetDocElemTokenMap());
342     switch( rTokenMap.Get( nPrefix, rLocalName ) )
343     {
344     case XML_TOK_DOC_FONTDECLS:
345         if (GetScImport().getImportFlags() & SvXMLImportFlags::FONTDECLS)
346             pContext = GetScImport().CreateFontDeclsContext(nPrefix, rLocalName, xAttrList);
347         break;
348     case XML_TOK_DOC_STYLES:
349         if (GetScImport().getImportFlags() & SvXMLImportFlags::STYLES)
350             pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, false);
351         break;
352     case XML_TOK_DOC_AUTOSTYLES:
353         if (GetScImport().getImportFlags() & SvXMLImportFlags::AUTOSTYLES)
354             pContext = GetScImport().CreateStylesContext( rLocalName, xAttrList, true);
355         break;
356     case XML_TOK_DOC_MASTERSTYLES:
357         if (GetScImport().getImportFlags() & SvXMLImportFlags::MASTERSTYLES)
358             pContext = new ScXMLMasterStylesContext( GetImport(), nPrefix, rLocalName,
359             xAttrList );
360         break;
361     case XML_TOK_DOC_META:
362         SAL_INFO("sc", "XML_TOK_DOC_META: should not have come here, maybe document is invalid?");
363         break;
364     case XML_TOK_DOC_SCRIPTS:
365         if (GetScImport().getImportFlags() & SvXMLImportFlags::SCRIPTS)
366             pContext = GetScImport().CreateScriptContext( rLocalName );
367         break;
368     case XML_TOK_DOC_SETTINGS:
369         if (GetScImport().getImportFlags() & SvXMLImportFlags::SETTINGS)
370             pContext = new XMLDocumentSettingsContext(GetScImport(), nPrefix, rLocalName, xAttrList );
371         break;
372     }
373 
374     if(!pContext)
375         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
376 
377     return pContext;
378 }
379 
380 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
createFastChildContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> &)381     ScXMLDocContext_Impl::createFastChildContext( sal_Int32 nElement,
382     const uno::Reference< xml::sax::XFastAttributeList > & /*xAttrList*/ )
383 {
384     SvXMLImportContext *pContext(nullptr);
385 
386     switch( nElement )
387     {
388         case XML_ELEMENT( OFFICE, XML_BODY ):
389         if (GetScImport().getImportFlags() & SvXMLImportFlags::CONTENT)
390             pContext = new ScXMLBodyContext_Impl( GetScImport() );
391         break;
392 
393         //TODO: handle all other cases
394         default:
395            pContext = new SvXMLImportContext( GetImport() );
396     }
397 
398     if(!pContext)
399         pContext = new SvXMLImportContext( GetImport() );
400 
401     return pContext;
402 }
403 
startFastElement(sal_Int32,const uno::Reference<xml::sax::XFastAttributeList> &)404 void SAL_CALL ScXMLDocContext_Impl::startFastElement(sal_Int32 /*nElement*/,
405     const uno::Reference< xml::sax::XFastAttributeList > & /*xAttrList*/)
406 {
407 }
408 
endFastElement(sal_Int32)409 void SAL_CALL ScXMLDocContext_Impl::endFastElement(sal_Int32 /*nElement*/)
410 {
411 }
412 
characters(const OUString &)413 void SAL_CALL ScXMLDocContext_Impl::characters(const OUString &)
414 {
415 }
416 
GetDocElemTokenMap()417 const SvXMLTokenMap& ScXMLImport::GetDocElemTokenMap()
418 {
419     if( !pDocElemTokenMap )
420     {
421         static const SvXMLTokenMapEntry aDocTokenMap[] =
422         {
423             { XML_NAMESPACE_OFFICE, XML_FONT_FACE_DECLS,    XML_TOK_DOC_FONTDECLS           },
424             { XML_NAMESPACE_OFFICE, XML_STYLES,             XML_TOK_DOC_STYLES              },
425             { XML_NAMESPACE_OFFICE, XML_AUTOMATIC_STYLES,   XML_TOK_DOC_AUTOSTYLES          },
426             { XML_NAMESPACE_OFFICE, XML_MASTER_STYLES,      XML_TOK_DOC_MASTERSTYLES        },
427             { XML_NAMESPACE_OFFICE, XML_META,               XML_TOK_DOC_META                },
428             { XML_NAMESPACE_OFFICE, XML_SCRIPTS,            XML_TOK_DOC_SCRIPTS             },
429             { XML_NAMESPACE_OFFICE, XML_BODY,               XML_TOK_DOC_BODY                },
430             { XML_NAMESPACE_OFFICE, XML_SETTINGS,           XML_TOK_DOC_SETTINGS            },
431             XML_TOKEN_MAP_END
432         };
433 
434         pDocElemTokenMap.reset(new SvXMLTokenMap( aDocTokenMap ));
435 
436     } // if( !pDocElemTokenMap )
437 
438     return *pDocElemTokenMap;
439 }
440 
GetContentValidationElemTokenMap()441 const SvXMLTokenMap& ScXMLImport::GetContentValidationElemTokenMap()
442 {
443     if( !pContentValidationElemTokenMap )
444     {
445         static const SvXMLTokenMapEntry aContentValidationElemTokenMap[] =
446         {
447             { XML_NAMESPACE_TABLE,  XML_HELP_MESSAGE,    XML_TOK_CONTENT_VALIDATION_ELEM_HELP_MESSAGE    },
448             { XML_NAMESPACE_TABLE,  XML_ERROR_MESSAGE,   XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MESSAGE   },
449             { XML_NAMESPACE_TABLE,  XML_ERROR_MACRO,     XML_TOK_CONTENT_VALIDATION_ELEM_ERROR_MACRO     },
450             { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_CONTENT_VALIDATION_ELEM_EVENT_LISTENERS },
451             XML_TOKEN_MAP_END
452         };
453 
454         pContentValidationElemTokenMap.reset(new SvXMLTokenMap( aContentValidationElemTokenMap ));
455     } // if( !pContentValidationElemTokenMap )
456 
457     return *pContentValidationElemTokenMap;
458 }
459 
GetContentValidationMessageElemTokenMap()460 const SvXMLTokenMap& ScXMLImport::GetContentValidationMessageElemTokenMap()
461 {
462     if( !pContentValidationMessageElemTokenMap )
463     {
464         static const SvXMLTokenMapEntry aContentValidationMessageElemTokenMap[] =
465         {
466             { XML_NAMESPACE_TEXT, XML_P,    XML_TOK_P   },
467             XML_TOKEN_MAP_END
468         };
469 
470         pContentValidationMessageElemTokenMap.reset(new SvXMLTokenMap( aContentValidationMessageElemTokenMap ));
471     } // if( !pContentValidationMessageElemTokenMap )
472 
473     return *pContentValidationMessageElemTokenMap;
474 }
475 
476 
GetTableElemTokenMap()477 const SvXMLTokenMap& ScXMLImport::GetTableElemTokenMap()
478 {
479     if( !pTableElemTokenMap )
480     {
481         static const SvXMLTokenMapEntry aTableTokenMap[] =
482         {
483             { XML_NAMESPACE_TABLE,  XML_NAMED_EXPRESSIONS,    XML_TOK_TABLE_NAMED_EXPRESSIONS },
484             { XML_NAMESPACE_TABLE,  XML_TABLE_COLUMN_GROUP,   XML_TOK_TABLE_COL_GROUP       },
485             { XML_NAMESPACE_TABLE,  XML_TABLE_HEADER_COLUMNS, XML_TOK_TABLE_HEADER_COLS },
486             { XML_NAMESPACE_TABLE,  XML_TABLE_COLUMNS,        XML_TOK_TABLE_COLS            },
487             { XML_NAMESPACE_TABLE,  XML_TABLE_COLUMN,         XML_TOK_TABLE_COL         },
488             { XML_NAMESPACE_TABLE,  XML_TABLE_PROTECTION,     XML_TOK_TABLE_PROTECTION    },
489             { XML_NAMESPACE_LO_EXT, XML_TABLE_PROTECTION,     XML_TOK_TABLE_PROTECTION_EXT  },
490             { XML_NAMESPACE_OFFICE_EXT, XML_TABLE_PROTECTION, XML_TOK_TABLE_PROTECTION_EXT  },
491             { XML_NAMESPACE_TABLE,  XML_TABLE_ROW_GROUP,      XML_TOK_TABLE_ROW_GROUP       },
492             { XML_NAMESPACE_TABLE,  XML_TABLE_HEADER_ROWS,    XML_TOK_TABLE_HEADER_ROWS },
493             { XML_NAMESPACE_TABLE,  XML_TABLE_ROWS,           XML_TOK_TABLE_ROWS            },
494             { XML_NAMESPACE_TABLE,  XML_TABLE_ROW,            XML_TOK_TABLE_ROW         },
495             { XML_NAMESPACE_TABLE,  XML_TABLE_SOURCE,         XML_TOK_TABLE_SOURCE      },
496             { XML_NAMESPACE_TABLE,  XML_SCENARIO,             XML_TOK_TABLE_SCENARIO        },
497             { XML_NAMESPACE_TABLE,  XML_SHAPES,               XML_TOK_TABLE_SHAPES      },
498             { XML_NAMESPACE_OFFICE, XML_FORMS,                XML_TOK_TABLE_FORMS           },
499             { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS,      XML_TOK_TABLE_EVENT_LISTENERS },
500             { XML_NAMESPACE_OFFICE_EXT, XML_EVENT_LISTENERS,  XML_TOK_TABLE_EVENT_LISTENERS_EXT },
501             { XML_NAMESPACE_CALC_EXT, XML_CONDITIONAL_FORMATS, XML_TOK_TABLE_CONDFORMATS },
502             XML_TOKEN_MAP_END
503         };
504 
505         pTableElemTokenMap.reset(new SvXMLTokenMap( aTableTokenMap ));
506     } // if( !pTableElemTokenMap )
507 
508     return *pTableElemTokenMap;
509 }
510 
GetTableRowsElemTokenMap()511 const SvXMLTokenMap& ScXMLImport::GetTableRowsElemTokenMap()
512 {
513     if( !pTableRowsElemTokenMap )
514     {
515         static const SvXMLTokenMapEntry aTableRowsElemTokenMap[] =
516         {
517             { XML_NAMESPACE_TABLE, XML_TABLE_ROW_GROUP,     XML_TOK_TABLE_ROWS_ROW_GROUP    },
518             { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS,   XML_TOK_TABLE_ROWS_HEADER_ROWS  },
519             { XML_NAMESPACE_TABLE, XML_TABLE_ROWS,          XML_TOK_TABLE_ROWS_ROWS         },
520             { XML_NAMESPACE_TABLE, XML_TABLE_ROW,           XML_TOK_TABLE_ROWS_ROW          },
521             XML_TOKEN_MAP_END
522         };
523 
524         pTableRowsElemTokenMap.reset(new SvXMLTokenMap( aTableRowsElemTokenMap ));
525     } // if( !pTableRowsElemTokenMap )
526 
527     return *pTableRowsElemTokenMap;
528 }
529 
GetTableRowElemTokenMap()530 const SvXMLTokenMap& ScXMLImport::GetTableRowElemTokenMap()
531 {
532     if( !pTableRowElemTokenMap )
533     {
534         static const SvXMLTokenMapEntry aTableRowTokenMap[] =
535         {
536             { XML_NAMESPACE_TABLE, XML_TABLE_CELL,      XML_TOK_TABLE_ROW_CELL              },
537             { XML_NAMESPACE_TABLE, XML_COVERED_TABLE_CELL,  XML_TOK_TABLE_ROW_COVERED_CELL      },
538             XML_TOKEN_MAP_END
539         };
540 
541         pTableRowElemTokenMap.reset(new SvXMLTokenMap( aTableRowTokenMap ));
542     } // if( !pTableRowElemTokenMap )
543 
544     return *pTableRowElemTokenMap;
545 }
546 
GetTableRowAttrTokenMap()547 const SvXMLTokenMap& ScXMLImport::GetTableRowAttrTokenMap()
548 {
549     if( !pTableRowAttrTokenMap )
550     {
551         static const SvXMLTokenMapEntry aTableRowAttrTokenMap[] =
552         {
553             { XML_NAMESPACE_TABLE, XML_STYLE_NAME,                  XML_TOK_TABLE_ROW_ATTR_STYLE_NAME           },
554             { XML_NAMESPACE_TABLE, XML_VISIBILITY,                  XML_TOK_TABLE_ROW_ATTR_VISIBILITY           },
555             { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_REPEATED,        XML_TOK_TABLE_ROW_ATTR_REPEATED             },
556             { XML_NAMESPACE_TABLE, XML_DEFAULT_CELL_STYLE_NAME,     XML_TOK_TABLE_ROW_ATTR_DEFAULT_CELL_STYLE_NAME },
557             //  { XML_NAMESPACE_TABLE, XML_USE_OPTIMAL_HEIGHT,          XML_TOK_TABLE_ROW_ATTR_USE_OPTIMAL_HEIGHT   },
558             XML_TOKEN_MAP_END
559         };
560 
561         pTableRowAttrTokenMap.reset(new SvXMLTokenMap( aTableRowAttrTokenMap ));
562     } // if( !pTableRowAttrTokenMap )
563 
564     return *pTableRowAttrTokenMap;
565 }
566 
GetTableRowCellElemTokenMap()567 const SvXMLTokenMap& ScXMLImport::GetTableRowCellElemTokenMap()
568 {
569     if( !pTableRowCellElemTokenMap )
570     {
571         static const SvXMLTokenMapEntry aTableRowCellTokenMap[] =
572         {
573             { XML_NAMESPACE_TEXT,   XML_P,                  XML_TOK_TABLE_ROW_CELL_P                    },
574             { XML_NAMESPACE_TABLE,  XML_SUB_TABLE,          XML_TOK_TABLE_ROW_CELL_TABLE                },
575             { XML_NAMESPACE_OFFICE, XML_ANNOTATION,         XML_TOK_TABLE_ROW_CELL_ANNOTATION           },
576             { XML_NAMESPACE_TABLE,  XML_DETECTIVE,          XML_TOK_TABLE_ROW_CELL_DETECTIVE            },
577             { XML_NAMESPACE_TABLE,  XML_CELL_RANGE_SOURCE,  XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE    },
578             XML_TOKEN_MAP_END
579         };
580 
581         pTableRowCellElemTokenMap.reset(new SvXMLTokenMap( aTableRowCellTokenMap ));
582     } // if( !pTableRowCellElemTokenMap )
583 
584     return *pTableRowCellElemTokenMap;
585 }
586 
GetTableAnnotationAttrTokenMap()587 const SvXMLTokenMap& ScXMLImport::GetTableAnnotationAttrTokenMap()
588 {
589     if( !pTableAnnotationAttrTokenMap )
590     {
591         static const SvXMLTokenMapEntry aTableAnnotationAttrTokenMap[] =
592         {
593             { XML_NAMESPACE_OFFICE, XML_AUTHOR,                 XML_TOK_TABLE_ANNOTATION_ATTR_AUTHOR                },
594             { XML_NAMESPACE_OFFICE, XML_CREATE_DATE,            XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE           },
595             { XML_NAMESPACE_OFFICE, XML_CREATE_DATE_STRING,     XML_TOK_TABLE_ANNOTATION_ATTR_CREATE_DATE_STRING    },
596             { XML_NAMESPACE_OFFICE, XML_DISPLAY,                XML_TOK_TABLE_ANNOTATION_ATTR_DISPLAY               },
597             { XML_NAMESPACE_SVG,    XML_X,                      XML_TOK_TABLE_ANNOTATION_ATTR_X                     },
598             { XML_NAMESPACE_SVG,    XML_Y,                      XML_TOK_TABLE_ANNOTATION_ATTR_Y                     },
599             XML_TOKEN_MAP_END
600         };
601 
602         pTableAnnotationAttrTokenMap.reset(new SvXMLTokenMap( aTableAnnotationAttrTokenMap ));
603     } // if( !pTableAnnotationAttrTokenMap )
604 
605     return *pTableAnnotationAttrTokenMap;
606 }
607 
608 
SetPostProcessData(sc::ImportPostProcessData * p)609 void ScXMLImport::SetPostProcessData( sc::ImportPostProcessData* p )
610 {
611     mpPostProcessData = p;
612 }
613 
GetPivotTableSources()614 sc::PivotTableSources& ScXMLImport::GetPivotTableSources()
615 {
616     if (!mpPivotSources)
617         mpPivotSources.reset(new sc::PivotTableSources);
618 
619     return *mpPivotSources;
620 }
621 
CreateFastContext(sal_Int32 nElement,const uno::Reference<xml::sax::XFastAttributeList> &)622 SvXMLImportContext *ScXMLImport::CreateFastContext( sal_Int32 nElement,
623         const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
624 {
625     SvXMLImportContext *pContext = nullptr;
626 
627     switch( nElement )
628     {
629     case XML_ELEMENT( OFFICE, XML_DOCUMENT_STYLES ):
630     case XML_ELEMENT( OFFICE, XML_DOCUMENT_CONTENT ):
631     case XML_ELEMENT( OFFICE, XML_DOCUMENT_SETTINGS ):
632         pContext = new ScXMLDocContext_Impl( *this );
633         break;
634 
635     case XML_ELEMENT( OFFICE, XML_DOCUMENT_META ):
636         pContext = CreateMetaContext(nElement);
637         break;
638 
639     case XML_ELEMENT( OFFICE, XML_DOCUMENT ):
640     {
641         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
642             GetModel(), uno::UNO_QUERY_THROW);
643         // flat OpenDocument file format
644         pContext = new ScXMLFlatDocContext_Impl( *this,
645             xDPS->getDocumentProperties());
646         break;
647     }
648 
649     default:
650         pContext = new SvXMLImportContext( *this );
651     }
652 
653     return pContext;
654 }
655 
656 static constexpr OUStringLiteral gsNumberFormat(SC_UNONAME_NUMFMT);
657 static constexpr OUStringLiteral gsLocale(SC_LOCALE);
658 static constexpr OUStringLiteral gsCellStyle(SC_UNONAME_CELLSTYL);
659 
ScXMLImport(const css::uno::Reference<css::uno::XComponentContext> & rContext,OUString const & implementationName,SvXMLImportFlags nImportFlag)660 ScXMLImport::ScXMLImport(
661     const css::uno::Reference< css::uno::XComponentContext >& rContext,
662     OUString const & implementationName, SvXMLImportFlags nImportFlag)
663 :   SvXMLImport( rContext, implementationName, nImportFlag ),
664     pDoc( nullptr ),
665     mpPostProcessData(nullptr),
666     aTables(*this),
667     sPrevStyleName(),
668     sPrevCurrency(),
669     nSolarMutexLocked(0),
670     nProgressCount(0),
671     nPrevCellType(0),
672     bLoadDoc( true ),
673     bNullDateSetted(false),
674     bSelfImportingXMLSet(false),
675     mbLockSolarMutex(true),
676     mbImportStyles(true),
677     mbHasNewCondFormatData(false)
678 {
679     pStylesImportHelper.reset(new ScMyStylesImportHelper(*this));
680 
681     xScPropHdlFactory = new XMLScPropHdlFactory;
682     xCellStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScCellStylesProperties, xScPropHdlFactory, false);
683     xColumnStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScColumnStylesProperties, xScPropHdlFactory, false);
684     xRowStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScRowStylesImportProperties, xScPropHdlFactory, false);
685     xTableStylesPropertySetMapper = new XMLPropertySetMapper(aXMLScTableStylesImportProperties, xScPropHdlFactory, false);
686 
687     // #i66550# needed for 'presentation:event-listener' element for URLs in shapes
688     GetNamespaceMap().Add(
689         GetXMLToken( XML_NP_PRESENTATION ),
690         GetXMLToken( XML_N_PRESENTATION ),
691         XML_NAMESPACE_PRESENTATION );
692 }
693 
~ScXMLImport()694 ScXMLImport::~ScXMLImport() throw()
695 {
696     //  delete pI18NMap;
697     pDocElemTokenMap.reset();
698     pContentValidationElemTokenMap.reset();
699     pContentValidationMessageElemTokenMap.reset();
700     pTableElemTokenMap.reset();
701     pTableRowsElemTokenMap.reset();
702     pTableRowElemTokenMap.reset();
703     pTableRowAttrTokenMap.reset();
704     pTableRowCellElemTokenMap.reset();
705     pTableRowCellAttrTokenMap.reset();
706     pTableAnnotationAttrTokenMap.reset();
707 
708     pChangeTrackingImportHelper.reset();
709     pNumberFormatAttributesExportHelper.reset();
710     pStyleNumberFormats.reset();
711     pStylesImportHelper.reset();
712 
713     m_pMyNamedExpressions.reset();
714     pMyLabelRanges.reset();
715     pValidations.reset();
716     pDetectiveOpArray.reset();
717 
718     //call SvXMLImport dtor contents before deleting pSolarMutexGuard
719     cleanup();
720 
721     pSolarMutexGuard.reset();
722 }
723 
initialize(const css::uno::Sequence<css::uno::Any> & aArguments)724 void ScXMLImport::initialize( const css::uno::Sequence<css::uno::Any>& aArguments )
725 {
726     SvXMLImport::initialize(aArguments);
727 
728     uno::Reference<beans::XPropertySet> xInfoSet = getImportInfo();
729     if (!xInfoSet.is())
730         return;
731 
732     uno::Reference<beans::XPropertySetInfo> xInfoSetInfo = xInfoSet->getPropertySetInfo();
733     if (!xInfoSetInfo.is())
734         return;
735 
736     if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_LOCK_SOLAR_MUTEX))
737         xInfoSet->getPropertyValue(SC_UNO_ODS_LOCK_SOLAR_MUTEX) >>= mbLockSolarMutex;
738 
739     if (xInfoSetInfo->hasPropertyByName(SC_UNO_ODS_IMPORT_STYLES))
740         xInfoSet->getPropertyValue(SC_UNO_ODS_IMPORT_STYLES) >>= mbImportStyles;
741 }
742 
CreateFontDeclsContext(const sal_uInt16 nPrefix,const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList)743 SvXMLImportContext *ScXMLImport::CreateFontDeclsContext(const sal_uInt16 nPrefix, const OUString& rLocalName,
744                                                         const uno::Reference<xml::sax::XAttributeList>& xAttrList)
745 {
746     XMLFontStylesContext *pFSContext = new XMLFontStylesContext(
747         *this, nPrefix, rLocalName, xAttrList, osl_getThreadTextEncoding());
748     SetFontDecls(pFSContext);
749     SvXMLImportContext* pContext = pFSContext;
750     return pContext;
751 }
752 
CreateStylesContext(const OUString & rLocalName,const uno::Reference<xml::sax::XAttributeList> & xAttrList,bool bIsAutoStyle)753 SvXMLImportContext *ScXMLImport::CreateStylesContext(const OUString& rLocalName,
754                                                      const uno::Reference<xml::sax::XAttributeList>& xAttrList, bool bIsAutoStyle )
755 {
756     SvXMLImportContext* pContext = new XMLTableStylesContext(
757         *this, XML_NAMESPACE_OFFICE, rLocalName, xAttrList, bIsAutoStyle);
758 
759     if (bIsAutoStyle)
760         SetAutoStyles(static_cast<SvXMLStylesContext*>(pContext));
761     else
762         SetStyles(static_cast<SvXMLStylesContext*>(pContext));
763 
764     return pContext;
765 }
766 
CreateBodyContext(const rtl::Reference<sax_fastparser::FastAttributeList> & rAttrList)767 SvXMLImportContext *ScXMLImport::CreateBodyContext(const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList)
768 {
769     return new ScXMLBodyContext(*this, rAttrList);
770 }
771 
CreateMetaContext(const sal_Int32)772 SvXMLImportContext *ScXMLImport::CreateMetaContext(
773     const sal_Int32 /*nElement*/ )
774 {
775     SvXMLImportContext* pContext = nullptr;
776 
777     if (getImportFlags() & SvXMLImportFlags::META)
778     {
779         uno::Reference<document::XDocumentPropertiesSupplier> xDPS(
780             GetModel(), uno::UNO_QUERY_THROW);
781         uno::Reference<document::XDocumentProperties> const xDocProps(
782             (IsStylesOnlyMode()) ? nullptr : xDPS->getDocumentProperties());
783         pContext = new SvXMLMetaDocumentContext(*this, xDocProps);
784     }
785 
786     if( !pContext )
787         pContext = new SvXMLImportContext( *this );
788 
789     return pContext;
790 }
791 
CreateScriptContext(const OUString & rLocalName)792 SvXMLImportContext *ScXMLImport::CreateScriptContext(
793     const OUString& rLocalName )
794 {
795     SvXMLImportContext* pContext = nullptr;
796 
797     if( !(IsStylesOnlyMode()) )
798     {
799         pContext = new XMLScriptContext( *this, rLocalName, GetModel() );
800     }
801 
802     if( !pContext )
803         pContext = new SvXMLImportContext( *this, XML_NAMESPACE_OFFICE,
804         rLocalName );
805 
806     return pContext;
807 }
808 
SetStatistics(const uno::Sequence<beans::NamedValue> & i_rStats)809 void ScXMLImport::SetStatistics(const uno::Sequence<beans::NamedValue> & i_rStats)
810 {
811     static const char* s_stats[] =
812     { "TableCount", "CellCount", "ObjectCount", nullptr };
813 
814     SvXMLImport::SetStatistics(i_rStats);
815 
816     sal_uInt32 nCount(0);
817     for (const auto& rStat : i_rStats) {
818         for (const char** pStat = s_stats; *pStat != nullptr; ++pStat) {
819             if (rStat.Name.equalsAscii(*pStat)) {
820                 sal_Int32 val = 0;
821                 if (rStat.Value >>= val) {
822                     nCount += val;
823                 } else {
824                     OSL_FAIL("ScXMLImport::SetStatistics: invalid entry");
825                 }
826             }
827         }
828     }
829 
830     if (nCount)
831     {
832         GetProgressBarHelper()->SetReference(nCount);
833         GetProgressBarHelper()->SetValue(0);
834     }
835 }
836 
GetDoc()837 ScDocumentImport& ScXMLImport::GetDoc()
838 {
839     return *mpDocImport;
840 }
841 
GetCellType(const char * rStrValue,const sal_Int32 nStrLength)842 sal_Int16 ScXMLImport::GetCellType(const char* rStrValue, const sal_Int32 nStrLength)
843 {
844     sal_Int16 nCellType = util::NumberFormat::UNDEFINED;
845     if (rStrValue != nullptr)
846     {
847         switch (rStrValue[0])
848         {
849             case 'b':
850                 if (nStrLength == 7 && !strcmp(rStrValue, "boolean"))
851                     nCellType = util::NumberFormat::LOGICAL;
852             break;
853             case 'c':
854                 if (nStrLength == 8 && !strcmp(rStrValue, "currency"))
855                     nCellType = util::NumberFormat::CURRENCY;
856             break;
857             case 'd':
858                 if (nStrLength == 4 && !strcmp(rStrValue, "date"))
859                     nCellType = util::NumberFormat::DATETIME;
860             break;
861             case 'f':
862                 if (nStrLength == 5 && !strcmp(rStrValue, "float"))
863                     nCellType = util::NumberFormat::NUMBER;
864             break;
865             case 'p':
866                 if (nStrLength == 10 && !strcmp(rStrValue, "percentage"))
867                     nCellType = util::NumberFormat::PERCENT;
868             break;
869             case 's':
870                 if (nStrLength == 6 && !strcmp(rStrValue, "string"))
871                     nCellType = util::NumberFormat::TEXT;
872             break;
873             case 't':
874                 if (nStrLength == 4 && !strcmp(rStrValue, "time"))
875                     nCellType = util::NumberFormat::TIME;
876             break;
877         }
878     }
879 
880     return nCellType;
881 }
882 
CreateShapeImport()883 XMLShapeImportHelper* ScXMLImport::CreateShapeImport()
884 {
885     return new XMLTableShapeImportHelper(*this);
886 }
887 
GetValidation(const OUString & sName,ScMyImportValidation & aValidation)888 bool ScXMLImport::GetValidation(const OUString& sName, ScMyImportValidation& aValidation)
889 {
890     if (pValidations)
891     {
892         auto aItr = std::find_if(pValidations->begin(), pValidations->end(),
893             [&sName](const ScMyImportValidation& rValidation) { return rValidation.sName == sName; });
894         if (aItr != pValidations->end())
895         {
896             // source position must be set as string,
897             // so sBaseCellAddress no longer has to be converted here
898             aValidation = *aItr;
899             return true;
900         }
901     }
902     return false;
903 }
904 
AddNamedExpression(SCTAB nTab,ScMyNamedExpression * pNamedExp)905 void ScXMLImport::AddNamedExpression(SCTAB nTab, ScMyNamedExpression* pNamedExp)
906 {
907     ::std::unique_ptr<ScMyNamedExpression> p(pNamedExp);
908     SheetNamedExpMap::iterator itr = m_SheetNamedExpressions.find(nTab);
909     if (itr == m_SheetNamedExpressions.end())
910     {
911         // No chain exists for this sheet.  Create one.
912         ::std::pair<SheetNamedExpMap::iterator, bool> r =
913             m_SheetNamedExpressions.insert(std::make_pair(nTab, std::make_unique<ScMyNamedExpressions>()));
914         if (!r.second)
915             // insertion failed.
916             return;
917 
918         itr = r.first;
919     }
920     ScMyNamedExpressions& r = *itr->second;
921     r.push_back(std::move(p));
922 }
923 
GetChangeTrackingImportHelper()924 ScXMLChangeTrackingImportHelper* ScXMLImport::GetChangeTrackingImportHelper()
925 {
926     if (!pChangeTrackingImportHelper)
927         pChangeTrackingImportHelper.reset(new ScXMLChangeTrackingImportHelper());
928     return pChangeTrackingImportHelper.get();
929 }
930 
InsertStyles()931 void ScXMLImport::InsertStyles()
932 {
933     GetStyles()->CopyStylesToDoc(true);
934 
935     // if content is going to be loaded with the same import, set bLatinDefaultStyle flag now
936     if ( getImportFlags() & SvXMLImportFlags::CONTENT )
937         ExamineDefaultStyle();
938 }
939 
ExamineDefaultStyle()940 void ScXMLImport::ExamineDefaultStyle()
941 {
942     if (pDoc)
943     {
944         // #i62435# after inserting the styles, check if the default style has a latin-script-only
945         // number format (then, value cells can be pre-initialized with western script type)
946 
947         const ScPatternAttr* pDefPattern = pDoc->GetDefPattern();
948         if (pDefPattern && sc::NumFmtUtil::isLatinScript(*pDefPattern, *pDoc))
949             mpDocImport->setDefaultNumericScript(SvtScriptType::LATIN);
950     }
951 }
952 
SetChangeTrackingViewSettings(const css::uno::Sequence<css::beans::PropertyValue> & rChangeProps)953 void ScXMLImport::SetChangeTrackingViewSettings(const css::uno::Sequence<css::beans::PropertyValue>& rChangeProps)
954 {
955     if (pDoc)
956     {
957         if (rChangeProps.hasElements())
958         {
959             ScXMLImport::MutexGuard aGuard(*this);
960             sal_Int16 nTemp16(0);
961             std::unique_ptr<ScChangeViewSettings> pViewSettings(new ScChangeViewSettings());
962             for (const auto& rChangeProp : rChangeProps)
963             {
964                 OUString sName(rChangeProp.Name);
965                 if (sName == "ShowChanges")
966                     pViewSettings->SetShowChanges(::cppu::any2bool(rChangeProp.Value));
967                 else if (sName == "ShowAcceptedChanges")
968                     pViewSettings->SetShowAccepted(::cppu::any2bool(rChangeProp.Value));
969                 else if (sName == "ShowRejectedChanges")
970                     pViewSettings->SetShowRejected(::cppu::any2bool(rChangeProp.Value));
971                 else if (sName == "ShowChangesByDatetime")
972                     pViewSettings->SetHasDate(::cppu::any2bool(rChangeProp.Value));
973                 else if (sName == "ShowChangesByDatetimeMode")
974                 {
975                     if (rChangeProp.Value >>= nTemp16)
976                         pViewSettings->SetTheDateMode(static_cast<SvxRedlinDateMode>(nTemp16));
977                 }
978                 else if (sName == "ShowChangesByDatetimeFirstDatetime")
979                 {
980                     util::DateTime aDateTime;
981                     if (rChangeProp.Value >>= aDateTime)
982                     {
983                         pViewSettings->SetTheFirstDateTime(::DateTime(aDateTime));
984                     }
985                 }
986                 else if (sName == "ShowChangesByDatetimeSecondDatetime")
987                 {
988                     util::DateTime aDateTime;
989                     if (rChangeProp.Value >>= aDateTime)
990                     {
991                         pViewSettings->SetTheLastDateTime(::DateTime(aDateTime));
992                     }
993                 }
994                 else if (sName == "ShowChangesByAuthor")
995                     pViewSettings->SetHasAuthor(::cppu::any2bool(rChangeProp.Value));
996                 else if (sName == "ShowChangesByAuthorName")
997                 {
998                     OUString sOUName;
999                     if (rChangeProp.Value >>= sOUName)
1000                     {
1001                         pViewSettings->SetTheAuthorToShow(sOUName);
1002                     }
1003                 }
1004                 else if (sName == "ShowChangesByComment")
1005                     pViewSettings->SetHasComment(::cppu::any2bool(rChangeProp.Value));
1006                 else if (sName == "ShowChangesByCommentText")
1007                 {
1008                     OUString sOUComment;
1009                     if (rChangeProp.Value >>= sOUComment)
1010                     {
1011                         pViewSettings->SetTheComment(sOUComment);
1012                     }
1013                 }
1014                 else if (sName == "ShowChangesByRanges")
1015                     pViewSettings->SetHasRange(::cppu::any2bool(rChangeProp.Value));
1016                 else if (sName == "ShowChangesByRangesList")
1017                 {
1018                     OUString sRanges;
1019                     if ((rChangeProp.Value >>= sRanges) && !sRanges.isEmpty())
1020                     {
1021                         ScRangeList aRangeList;
1022                         ScRangeStringConverter::GetRangeListFromString(
1023                             aRangeList, sRanges, GetDocument(), FormulaGrammar::CONV_OOO);
1024                         pViewSettings->SetTheRangeList(aRangeList);
1025                     }
1026                 }
1027             }
1028             pDoc->SetChangeViewSettings(*pViewSettings);
1029         }
1030     }
1031 }
1032 
SetViewSettings(const uno::Sequence<beans::PropertyValue> & aViewProps)1033 void ScXMLImport::SetViewSettings(const uno::Sequence<beans::PropertyValue>& aViewProps)
1034 {
1035     sal_Int32 nHeight(0);
1036     sal_Int32 nLeft(0);
1037     sal_Int32 nTop(0);
1038     sal_Int32 nWidth(0);
1039     for (const auto& rViewProp : aViewProps)
1040     {
1041         OUString sName(rViewProp.Name);
1042         if (sName == "VisibleAreaHeight")
1043             rViewProp.Value >>= nHeight;
1044         else if (sName == "VisibleAreaLeft")
1045             rViewProp.Value >>= nLeft;
1046         else if (sName == "VisibleAreaTop")
1047             rViewProp.Value >>= nTop;
1048         else if (sName == "VisibleAreaWidth")
1049             rViewProp.Value >>= nWidth;
1050         else if (sName == "TrackedChangesViewSettings")
1051         {
1052             uno::Sequence<beans::PropertyValue> aChangeProps;
1053             if(rViewProp.Value >>= aChangeProps)
1054                 SetChangeTrackingViewSettings(aChangeProps);
1055         }
1056     }
1057     if (nHeight && nWidth && GetModel().is())
1058     {
1059         ScModelObj* pDocObj(comphelper::getUnoTunnelImplementation<ScModelObj>( GetModel() ));
1060         if (pDocObj)
1061         {
1062             SfxObjectShell* pEmbeddedObj = pDocObj->GetEmbeddedObject();
1063             if (pEmbeddedObj)
1064             {
1065                 tools::Rectangle aRect;
1066                 aRect.setX( nLeft );
1067                 aRect.setY( nTop );
1068                 aRect.setWidth( nWidth );
1069                 aRect.setHeight( nHeight );
1070                 pEmbeddedObj->SetVisArea(aRect);
1071             }
1072         }
1073     }
1074 }
1075 
SetConfigurationSettings(const uno::Sequence<beans::PropertyValue> & aConfigProps)1076 void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyValue>& aConfigProps)
1077 {
1078     if (GetModel().is())
1079     {
1080         uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
1081         if (xMultiServiceFactory.is())
1082         {
1083             sal_Int32 nCount(aConfigProps.getLength());
1084             css::uno::Sequence<css::beans::PropertyValue> aFilteredProps(nCount);
1085             sal_Int32 nFilteredPropsLen = 0;
1086             for (sal_Int32 i = nCount - 1; i >= 0; --i)
1087             {
1088                 if (aConfigProps[i].Name == "TrackedChangesProtectionKey")
1089                 {
1090                     OUString sKey;
1091                     if (aConfigProps[i].Value >>= sKey)
1092                     {
1093                         uno::Sequence<sal_Int8> aPass;
1094                         ::comphelper::Base64::decode(aPass, sKey);
1095                         if (aPass.hasElements())
1096                         {
1097                             if (pDoc->GetChangeTrack())
1098                                 pDoc->GetChangeTrack()->SetProtection(aPass);
1099                             else
1100                             {
1101                                 std::set<OUString> aUsers;
1102                                 std::unique_ptr<ScChangeTrack> pTrack( new ScChangeTrack(pDoc, aUsers) );
1103                                 pTrack->SetProtection(aPass);
1104                                 pDoc->SetChangeTrack(std::move(pTrack));
1105                             }
1106                         }
1107                     }
1108                 }
1109                 // store the following items for later use (after document is loaded)
1110                 else if ((aConfigProps[i].Name == "VBACompatibilityMode") || (aConfigProps[i].Name == "ScriptConfiguration"))
1111                 {
1112                     uno::Reference< beans::XPropertySet > xImportInfo = getImportInfo();
1113                     if (xImportInfo.is())
1114                     {
1115                         uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = xImportInfo->getPropertySetInfo();
1116                         if (xPropertySetInfo.is() && xPropertySetInfo->hasPropertyByName(aConfigProps[i].Name))
1117                             xImportInfo->setPropertyValue( aConfigProps[i].Name, aConfigProps[i].Value );
1118                     }
1119                 }
1120                 if (aConfigProps[i].Name != "LinkUpdateMode")
1121                 {
1122                     aFilteredProps[nFilteredPropsLen++] = aConfigProps[i];
1123                 }
1124             }
1125             aFilteredProps.realloc(nFilteredPropsLen);
1126             uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance("com.sun.star.comp.SpreadsheetSettings");
1127             uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY);
1128             if (xProperties.is())
1129                 SvXMLUnitConverter::convertPropertySet(xProperties, aFilteredProps);
1130         }
1131     }
1132 }
1133 
SetCurrencySymbol(const sal_Int32 nKey,const OUString & rCurrency)1134 sal_Int32 ScXMLImport::SetCurrencySymbol(const sal_Int32 nKey, const OUString& rCurrency)
1135 {
1136     uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
1137     if (xNumberFormatsSupplier.is())
1138     {
1139         uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
1140         if (xLocalNumberFormats.is())
1141         {
1142             OUString sFormatString;
1143             try
1144             {
1145                 uno::Reference <beans::XPropertySet> xProperties(xLocalNumberFormats->getByKey(nKey));
1146                 if (xProperties.is())
1147                 {
1148                     lang::Locale aLocale;
1149                     if (GetDocument() && (xProperties->getPropertyValue(gsLocale) >>= aLocale))
1150                     {
1151                         {
1152                             ScXMLImport::MutexGuard aGuard(*this);
1153                             LocaleDataWrapper aLocaleData( comphelper::getProcessComponentContext(), LanguageTag( aLocale) );
1154                             OUStringBuffer aBuffer(15);
1155                             aBuffer.append("#");
1156                             aBuffer.append( aLocaleData.getNumThousandSep() );
1157                             aBuffer.append("##0");
1158                             aBuffer.append( aLocaleData.getNumDecimalSep() );
1159                             aBuffer.append("00 [$");
1160                             aBuffer.append(rCurrency);
1161                             aBuffer.append("]");
1162                             sFormatString = aBuffer.makeStringAndClear();
1163                         }
1164                         sal_Int32 nNewKey = xLocalNumberFormats->queryKey(sFormatString, aLocale, true);
1165                         if (nNewKey == -1)
1166                             nNewKey = xLocalNumberFormats->addNew(sFormatString, aLocale);
1167                         return nNewKey;
1168                     }
1169                 }
1170             }
1171             catch ( const util::MalformedNumberFormatException& rException )
1172             {
1173                 OUString sErrorMessage ="Error in Formatstring " +
1174                     sFormatString + " at position " +
1175                     OUString::number(rException.CheckPos);
1176                 uno::Sequence<OUString> aSeq { sErrorMessage };
1177                 uno::Reference<xml::sax::XLocator> xLocator;
1178                 SetError(XMLERROR_API | XMLERROR_FLAG_ERROR, aSeq, rException.Message, xLocator);
1179             }
1180         }
1181     }
1182     return nKey;
1183 }
1184 
IsCurrencySymbol(const sal_Int32 nNumberFormat,const OUString & sCurrentCurrency,const OUString & sBankSymbol)1185 bool ScXMLImport::IsCurrencySymbol(const sal_Int32 nNumberFormat, const OUString& sCurrentCurrency, const OUString& sBankSymbol)
1186 {
1187     uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
1188     if (xNumberFormatsSupplier.is())
1189     {
1190         uno::Reference <util::XNumberFormats> xLocalNumberFormats(xNumberFormatsSupplier->getNumberFormats());
1191         if (xLocalNumberFormats.is())
1192         {
1193             try
1194             {
1195                 uno::Reference <beans::XPropertySet> xNumberPropertySet(xLocalNumberFormats->getByKey(nNumberFormat));
1196                 if (xNumberPropertySet.is())
1197                 {
1198                     OUString sTemp;
1199                     if ( xNumberPropertySet->getPropertyValue(SC_CURRENCYSYMBOL) >>= sTemp)
1200                     {
1201                         if (sCurrentCurrency == sTemp)
1202                             return true;
1203                         // A release that saved an unknown currency may have
1204                         // saved the currency symbol of the number format
1205                         // instead of an ISO code bank symbol. In another
1206                         // release we may have a match for that. In this case
1207                         // sCurrentCurrency is the ISO code obtained through
1208                         // XMLNumberFormatAttributesExportHelper::GetCellType()
1209                         // and sBankSymbol is the currency symbol.
1210                         if (sCurrentCurrency.getLength() == 3 && sBankSymbol == sTemp)
1211                             return true;
1212                         // #i61657# This may be a legacy currency symbol that changed in the meantime.
1213                         if (SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sCurrentCurrency, sBankSymbol) != nullptr)
1214                             return true;
1215                         // In the rare case that sCurrentCurrency is not the
1216                         // currency symbol, but a matching ISO code
1217                         // abbreviation instead that was obtained through
1218                         // XMLNumberFormatAttributesExportHelper::GetCellType(),
1219                         // check with the number format's symbol. This happens,
1220                         // for example, in the es_BO locale, where a legacy
1221                         // B$,BOB matched B$->BOP, which leads to
1222                         // sCurrentCurrency being BOP, and the previous call
1223                         // with BOP,BOB didn't find an entry, but B$,BOB will.
1224                         return SvNumberFormatter::GetLegacyOnlyCurrencyEntry( sTemp, sBankSymbol) != nullptr;
1225                     }
1226                 }
1227             }
1228             catch ( uno::Exception& )
1229             {
1230                 OSL_FAIL("Numberformat not found");
1231             }
1232         }
1233     }
1234     return false;
1235 }
1236 
SetType(const uno::Reference<beans::XPropertySet> & rProperties,sal_Int32 & rNumberFormat,const sal_Int16 nCellType,const OUString & rCurrency)1237 void ScXMLImport::SetType(const uno::Reference <beans::XPropertySet>& rProperties,
1238                           sal_Int32& rNumberFormat,
1239                           const sal_Int16 nCellType,
1240                           const OUString& rCurrency)
1241 {
1242     if (!mbImportStyles)
1243         return;
1244 
1245     if ((nCellType != util::NumberFormat::TEXT) && (nCellType != util::NumberFormat::UNDEFINED))
1246     {
1247         if (rNumberFormat == -1)
1248             rProperties->getPropertyValue( gsNumberFormat ) >>= rNumberFormat;
1249         OSL_ENSURE(rNumberFormat != -1, "no NumberFormat");
1250         bool bIsStandard;
1251         // sCurrentCurrency may be the ISO code abbreviation if the currency
1252         // symbol matches such, or if no match found the symbol itself!
1253         OUString sCurrentCurrency;
1254         sal_Int32 nCurrentCellType(
1255             GetNumberFormatAttributesExportHelper()->GetCellType(
1256                 rNumberFormat, sCurrentCurrency, bIsStandard) & ~util::NumberFormat::DEFINED);
1257         // If the (numeric) cell type (number, currency, date, time, boolean)
1258         // is different from the format type then for some combinations we may
1259         // have to apply a format, e.g. in case the generator deduced format
1260         // from type and did not apply a format but we don't keep a dedicated
1261         // type internally. Specifically this is necessary if the cell type is
1262         // not number but the format type is (i.e. General). Currency cells
1263         // need extra attention, see calls of ScXMLImport::IsCurrencySymbol()
1264         // and description within there and ScXMLImport::SetCurrencySymbol().
1265         if ((nCellType != nCurrentCellType) &&
1266                 (nCellType != util::NumberFormat::NUMBER) &&
1267                 (bIsStandard || (nCellType == util::NumberFormat::CURRENCY)))
1268         {
1269             if (!xNumberFormats.is())
1270             {
1271                 uno::Reference <util::XNumberFormatsSupplier> xNumberFormatsSupplier(GetNumberFormatsSupplier());
1272                 if (xNumberFormatsSupplier.is())
1273                     xNumberFormats.set(xNumberFormatsSupplier->getNumberFormats());
1274             }
1275             if (xNumberFormats.is())
1276             {
1277                 try
1278                 {
1279                     uno::Reference < beans::XPropertySet> xNumberFormatProperties(xNumberFormats->getByKey(rNumberFormat));
1280                     if (xNumberFormatProperties.is())
1281                     {
1282                         if (nCellType != util::NumberFormat::CURRENCY)
1283                         {
1284                             lang::Locale aLocale;
1285                             if ( xNumberFormatProperties->getPropertyValue(gsLocale) >>= aLocale )
1286                             {
1287                                 if (!xNumberFormatTypes.is())
1288                                     xNumberFormatTypes.set(uno::Reference <util::XNumberFormatTypes>(xNumberFormats, uno::UNO_QUERY));
1289                                 rProperties->setPropertyValue( gsNumberFormat, uno::makeAny(xNumberFormatTypes->getStandardFormat(nCellType, aLocale)) );
1290                             }
1291                         }
1292                         else if (!rCurrency.isEmpty() && !sCurrentCurrency.isEmpty())
1293                         {
1294                             if (sCurrentCurrency != rCurrency)
1295                                 if (!IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
1296                                     rProperties->setPropertyValue( gsNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency)));
1297                         }
1298                     }
1299                 }
1300                 catch ( uno::Exception& )
1301                 {
1302                     OSL_FAIL("Numberformat not found");
1303                 }
1304             }
1305         }
1306         else
1307         {
1308             if ((nCellType == util::NumberFormat::CURRENCY) && !rCurrency.isEmpty() && !sCurrentCurrency.isEmpty() &&
1309                 sCurrentCurrency != rCurrency && !IsCurrencySymbol(rNumberFormat, sCurrentCurrency, rCurrency))
1310                 rProperties->setPropertyValue( gsNumberFormat, uno::makeAny(SetCurrencySymbol(rNumberFormat, rCurrency)));
1311         }
1312     }
1313 }
1314 
AddStyleRange(const table::CellRangeAddress & rCellRange)1315 void ScXMLImport::AddStyleRange(const table::CellRangeAddress& rCellRange)
1316 {
1317     if (!mbImportStyles)
1318         return;
1319 
1320     if (!xSheetCellRanges.is() && GetModel().is())
1321     {
1322         uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
1323         if (xMultiServiceFactory.is())
1324             xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(xMultiServiceFactory->createInstance("com.sun.star.sheet.SheetCellRanges"), uno::UNO_QUERY));
1325         OSL_ENSURE(xSheetCellRanges.is(), "didn't get SheetCellRanges");
1326 
1327     }
1328     xSheetCellRanges->addRangeAddress(rCellRange, false);
1329 }
1330 
SetStyleToRanges()1331 void ScXMLImport::SetStyleToRanges()
1332 {
1333     if (!mbImportStyles)
1334         return;
1335 
1336     if (!sPrevStyleName.isEmpty())
1337     {
1338         uno::Reference <beans::XPropertySet> xProperties (xSheetCellRanges, uno::UNO_QUERY);
1339         if (xProperties.is())
1340         {
1341             XMLTableStylesContext *pStyles(static_cast<XMLTableStylesContext *>(GetAutoStyles()));
1342             XMLTableStyleContext* pStyle = nullptr;
1343             if ( pStyles )
1344                 pStyle = const_cast<XMLTableStyleContext*>(static_cast<const XMLTableStyleContext *>(pStyles->FindStyleChildContext(
1345                         XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName, true)));
1346             if (pStyle)
1347             {
1348                 pStyle->FillPropertySet(xProperties);
1349                 // here needs to be the cond format import method
1350                 sal_Int32 nNumberFormat(pStyle->GetNumberFormat());
1351                 SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
1352 
1353                 css::uno::Any aAny = xProperties->getPropertyValue("FormatID");
1354                 sal_uInt64 nKey = 0;
1355                 if ((aAny >>= nKey) && nKey)
1356                 {
1357                     ScFormatSaveData* pFormatSaveData = comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->GetFormatSaveData();
1358                     pFormatSaveData->maIDToName.insert(std::pair<sal_uInt64, OUString>(nKey, sPrevStyleName));
1359                 }
1360 
1361                 // store first cell of first range for each style, once per sheet
1362                 uno::Sequence<table::CellRangeAddress> aAddresses(xSheetCellRanges->getRangeAddresses());
1363                 pStyle->ApplyCondFormat(aAddresses);
1364                 if ( aAddresses.hasElements() )
1365                 {
1366                     const table::CellRangeAddress& rRange = aAddresses[0];
1367                     if ( rRange.Sheet != pStyle->GetLastSheet() )
1368                     {
1369                         ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->GetSheetSaveData();
1370                         pSheetData->AddCellStyle( sPrevStyleName,
1371                             ScAddress( static_cast<SCCOL>(rRange.StartColumn), static_cast<SCROW>(rRange.StartRow), static_cast<SCTAB>(rRange.Sheet) ) );
1372                         pStyle->SetLastSheet(rRange.Sheet);
1373                     }
1374                 }
1375             }
1376             else
1377             {
1378                 xProperties->setPropertyValue(gsCellStyle, uno::makeAny(GetStyleDisplayName( XML_STYLE_FAMILY_TABLE_CELL, sPrevStyleName )));
1379                 sal_Int32 nNumberFormat(GetStyleNumberFormats()->GetStyleNumberFormat(sPrevStyleName));
1380                 bool bInsert(nNumberFormat == -1);
1381                 SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
1382                 if (bInsert)
1383                     GetStyleNumberFormats()->AddStyleNumberFormat(sPrevStyleName, nNumberFormat);
1384             }
1385         }
1386     }
1387     if (GetModel().is())
1388     {
1389         uno::Reference <lang::XMultiServiceFactory> xMultiServiceFactory(GetModel(), uno::UNO_QUERY);
1390         if (xMultiServiceFactory.is())
1391             xSheetCellRanges.set(uno::Reference <sheet::XSheetCellRangeContainer>(
1392             xMultiServiceFactory->createInstance("com.sun.star.sheet.SheetCellRanges"),
1393             uno::UNO_QUERY));
1394     }
1395     OSL_ENSURE(xSheetCellRanges.is(), "didn't get SheetCellRanges");
1396 }
1397 
SetStyleToRange(const ScRange & rRange,const OUString * pStyleName,const sal_Int16 nCellType,const OUString * pCurrency)1398 void ScXMLImport::SetStyleToRange(const ScRange& rRange, const OUString* pStyleName,
1399                                   const sal_Int16 nCellType, const OUString* pCurrency)
1400 {
1401     if (!mbImportStyles)
1402         return;
1403 
1404     if (sPrevStyleName.isEmpty())
1405     {
1406         nPrevCellType = nCellType;
1407         if (pStyleName)
1408             sPrevStyleName = *pStyleName;
1409         if (pCurrency)
1410             sPrevCurrency = *pCurrency;
1411         else if (!sPrevCurrency.isEmpty())
1412             sPrevCurrency.clear();
1413     }
1414     else if ((nCellType != nPrevCellType) ||
1415         ((pStyleName && *pStyleName != sPrevStyleName) ||
1416         (!pStyleName && !sPrevStyleName.isEmpty())) ||
1417         ((pCurrency && *pCurrency != sPrevCurrency) ||
1418         (!pCurrency && !sPrevCurrency.isEmpty())))
1419     {
1420         SetStyleToRanges();
1421         nPrevCellType = nCellType;
1422         if (pStyleName)
1423             sPrevStyleName = *pStyleName;
1424         else if(!sPrevStyleName.isEmpty())
1425             sPrevStyleName.clear();
1426         if (pCurrency)
1427             sPrevCurrency = *pCurrency;
1428         else if(!sPrevCurrency.isEmpty())
1429             sPrevCurrency.clear();
1430     }
1431     table::CellRangeAddress aCellRange;
1432     aCellRange.StartColumn = rRange.aStart.Col();
1433     aCellRange.StartRow = rRange.aStart.Row();
1434     aCellRange.Sheet = rRange.aStart.Tab();
1435     aCellRange.EndColumn = rRange.aEnd.Col();
1436     aCellRange.EndRow = rRange.aEnd.Row();
1437     AddStyleRange(aCellRange);
1438 }
1439 
SetNullDateOnUnitConverter()1440 bool ScXMLImport::SetNullDateOnUnitConverter()
1441 {
1442     if (!bNullDateSetted)
1443         bNullDateSetted = GetMM100UnitConverter().setNullDate(GetModel());
1444     OSL_ENSURE(bNullDateSetted, "could not set the null date");
1445     return bNullDateSetted;
1446 }
1447 
GetNumberFormatAttributesExportHelper()1448 XMLNumberFormatAttributesExportHelper* ScXMLImport::GetNumberFormatAttributesExportHelper()
1449 {
1450     if (!pNumberFormatAttributesExportHelper)
1451         pNumberFormatAttributesExportHelper.reset(new XMLNumberFormatAttributesExportHelper(GetNumberFormatsSupplier()));
1452     return pNumberFormatAttributesExportHelper.get();
1453 }
1454 
GetStyleNumberFormats()1455 ScMyStyleNumberFormats* ScXMLImport::GetStyleNumberFormats()
1456 {
1457     if (!pStyleNumberFormats)
1458         pStyleNumberFormats.reset(new ScMyStyleNumberFormats);
1459     return pStyleNumberFormats.get();
1460 }
1461 
SetStylesToRangesFinished()1462 void ScXMLImport::SetStylesToRangesFinished()
1463 {
1464     SetStyleToRanges();
1465     sPrevStyleName.clear();
1466 }
1467 
1468 // XImporter
setTargetDocument(const css::uno::Reference<css::lang::XComponent> & xDoc)1469 void SAL_CALL ScXMLImport::setTargetDocument( const css::uno::Reference< css::lang::XComponent >& xDoc )
1470 {
1471     ScXMLImport::MutexGuard aGuard(*this);
1472     SvXMLImport::setTargetDocument( xDoc );
1473 
1474     uno::Reference<frame::XModel> xModel(xDoc, uno::UNO_QUERY);
1475     pDoc = ScXMLConverter::GetScDocument( xModel );
1476     OSL_ENSURE( pDoc, "ScXMLImport::setTargetDocument - no ScDocument!" );
1477     if (!pDoc)
1478         throw lang::IllegalArgumentException();
1479 
1480     mpDocImport.reset(new ScDocumentImport(*pDoc));
1481     mpComp.reset(new ScCompiler(pDoc, ScAddress(), formula::FormulaGrammar::GRAM_ODFF));
1482 
1483     uno::Reference<document::XActionLockable> xActionLockable(xDoc, uno::UNO_QUERY);
1484     if (xActionLockable.is())
1485         xActionLockable->addActionLock();
1486 }
1487 
1488 // css::xml::sax::XDocumentHandler
startDocument()1489 void SAL_CALL ScXMLImport::startDocument()
1490 {
1491     ScXMLImport::MutexGuard aGuard(*this);
1492     SvXMLImport::startDocument();
1493     if (pDoc && !pDoc->IsImportingXML())
1494     {
1495         comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->BeforeXMLLoading();
1496         bSelfImportingXMLSet = true;
1497     }
1498 
1499     // if content and styles are loaded with separate imports,
1500     // set bLatinDefaultStyle flag at the start of the content import
1501     SvXMLImportFlags nFlags = getImportFlags();
1502     if ( ( nFlags & SvXMLImportFlags::CONTENT ) && !( nFlags & SvXMLImportFlags::STYLES ) )
1503         ExamineDefaultStyle();
1504 
1505     if (getImportFlags() & SvXMLImportFlags::CONTENT)
1506     {
1507         if (GetModel().is())
1508         {
1509             // store initial namespaces, to find the ones that were added from the file later
1510             ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->GetSheetSaveData();
1511             const SvXMLNamespaceMap& rNamespaces = GetNamespaceMap();
1512             pSheetData->StoreInitialNamespaces(rNamespaces);
1513         }
1514     }
1515 
1516     uno::Reference< beans::XPropertySet > const xImportInfo( getImportInfo() );
1517     uno::Reference< beans::XPropertySetInfo > const xPropertySetInfo(
1518             xImportInfo.is() ? xImportInfo->getPropertySetInfo() : nullptr);
1519     if (xPropertySetInfo.is())
1520     {
1521         OUString const sOrganizerMode(
1522             "OrganizerMode");
1523         if (xPropertySetInfo->hasPropertyByName(sOrganizerMode))
1524         {
1525             bool bStyleOnly(false);
1526             if (xImportInfo->getPropertyValue(sOrganizerMode) >>= bStyleOnly)
1527             {
1528                 bLoadDoc = !bStyleOnly;
1529             }
1530         }
1531     }
1532 
1533     UnlockSolarMutex();
1534 }
1535 
GetRangeType(const OUString & sRangeType)1536 sal_Int32 ScXMLImport::GetRangeType(const OUString& sRangeType)
1537 {
1538     sal_Int32 nRangeType(0);
1539     OUStringBuffer sBuffer;
1540     sal_Int32 i = 0;
1541     while (i <= sRangeType.getLength())
1542     {
1543         if ((i == sRangeType.getLength()) || (sRangeType[i] == ' '))
1544         {
1545             OUString sTemp = sBuffer.makeStringAndClear();
1546             if (sTemp == "repeat-column")
1547                 nRangeType |= sheet::NamedRangeFlag::COLUMN_HEADER;
1548             else if (sTemp == SC_REPEAT_ROW)
1549                 nRangeType |= sheet::NamedRangeFlag::ROW_HEADER;
1550             else if (sTemp == SC_FILTER)
1551                 nRangeType |= sheet::NamedRangeFlag::FILTER_CRITERIA;
1552             else if (sTemp == SC_PRINT_RANGE)
1553                 nRangeType |= sheet::NamedRangeFlag::PRINT_AREA;
1554         }
1555         else if (i < sRangeType.getLength())
1556             sBuffer.append(sRangeType[i]);
1557         ++i;
1558     }
1559     return nRangeType;
1560 }
1561 
SetLabelRanges()1562 void ScXMLImport::SetLabelRanges()
1563 {
1564     if (pMyLabelRanges)
1565     {
1566         uno::Reference <beans::XPropertySet> xPropertySet (GetModel(), uno::UNO_QUERY);
1567         if (xPropertySet.is())
1568         {
1569             uno::Any aColAny = xPropertySet->getPropertyValue(SC_UNO_COLLABELRNG);
1570             uno::Any aRowAny = xPropertySet->getPropertyValue(SC_UNO_ROWLABELRNG);
1571 
1572             uno::Reference< sheet::XLabelRanges > xColRanges;
1573             uno::Reference< sheet::XLabelRanges > xRowRanges;
1574 
1575             if ( ( aColAny >>= xColRanges ) && ( aRowAny >>= xRowRanges ) )
1576             {
1577                 table::CellRangeAddress aLabelRange;
1578                 table::CellRangeAddress aDataRange;
1579 
1580                 for (const auto& rxLabelRange : *pMyLabelRanges)
1581                 {
1582                     sal_Int32 nOffset1(0);
1583                     sal_Int32 nOffset2(0);
1584                     FormulaGrammar::AddressConvention eConv = FormulaGrammar::CONV_OOO;
1585 
1586                     if (ScRangeStringConverter::GetRangeFromString( aLabelRange, rxLabelRange->sLabelRangeStr, GetDocument(), eConv, nOffset1 ) &&
1587                         ScRangeStringConverter::GetRangeFromString( aDataRange, rxLabelRange->sDataRangeStr, GetDocument(), eConv, nOffset2 ))
1588                     {
1589                         if ( rxLabelRange->bColumnOrientation )
1590                             xColRanges->addNew( aLabelRange, aDataRange );
1591                         else
1592                             xRowRanges->addNew( aLabelRange, aDataRange );
1593                     }
1594                 }
1595 
1596                 pMyLabelRanges->clear();
1597             }
1598         }
1599     }
1600 }
1601 
1602 namespace {
1603 
1604 class RangeNameInserter
1605 {
1606     ScDocument* const mpDoc;
1607     ScRangeName& mrRangeName;
1608 
1609 public:
RangeNameInserter(ScDocument * pDoc,ScRangeName & rRangeName)1610     RangeNameInserter(ScDocument* pDoc, ScRangeName& rRangeName) :
1611         mpDoc(pDoc), mrRangeName(rRangeName) {}
1612 
operator ()(const std::unique_ptr<ScMyNamedExpression> & p) const1613     void operator() (const std::unique_ptr<ScMyNamedExpression>& p) const
1614     {
1615         using namespace formula;
1616 
1617         const OUString& aType = p->sRangeType;
1618         sal_uInt32 nUnoType = ScXMLImport::GetRangeType(aType);
1619 
1620         ScRangeData::Type nNewType = ScRangeData::Type::Name;
1621         if ( nUnoType & sheet::NamedRangeFlag::FILTER_CRITERIA )    nNewType |= ScRangeData::Type::Criteria;
1622         if ( nUnoType & sheet::NamedRangeFlag::PRINT_AREA )         nNewType |= ScRangeData::Type::PrintArea;
1623         if ( nUnoType & sheet::NamedRangeFlag::COLUMN_HEADER )      nNewType |= ScRangeData::Type::ColHeader;
1624         if ( nUnoType & sheet::NamedRangeFlag::ROW_HEADER )         nNewType |= ScRangeData::Type::RowHeader;
1625 
1626         if (mpDoc)
1627         {
1628             // Insert a new name.
1629             ScAddress aPos;
1630             sal_Int32 nOffset = 0;
1631             bool bSuccess = ScRangeStringConverter::GetAddressFromString(
1632                 aPos, p->sBaseCellAddress, mpDoc, FormulaGrammar::CONV_OOO, nOffset);
1633 
1634             if (bSuccess)
1635             {
1636                 OUString aContent = p->sContent;
1637                 if (!p->bIsExpression)
1638                     ScXMLConverter::ConvertCellRangeAddress(aContent);
1639 
1640                 ScRangeData* pData = new ScRangeData(
1641                     mpDoc, p->sName, aContent, aPos, nNewType, p->eGrammar);
1642                 mrRangeName.insert(pData);
1643             }
1644         }
1645     }
1646 };
1647 
1648 }
1649 
SetNamedRanges()1650 void ScXMLImport::SetNamedRanges()
1651 {
1652     if (!m_pMyNamedExpressions)
1653         return;
1654 
1655     if (!pDoc)
1656         return;
1657 
1658     // Insert the namedRanges
1659     ScRangeName* pRangeNames = pDoc->GetRangeName();
1660     ::std::for_each(m_pMyNamedExpressions->begin(), m_pMyNamedExpressions->end(), RangeNameInserter(pDoc, *pRangeNames));
1661 }
1662 
SetSheetNamedRanges()1663 void ScXMLImport::SetSheetNamedRanges()
1664 {
1665     if (!pDoc)
1666         return;
1667 
1668     for (auto const& itr : m_SheetNamedExpressions)
1669     {
1670         const SCTAB nTab = itr.first;
1671         ScRangeName* pRangeNames = pDoc->GetRangeName(nTab);
1672         if (!pRangeNames)
1673             continue;
1674 
1675         const ScMyNamedExpressions& rNames = *itr.second;
1676         ::std::for_each(rNames.begin(), rNames.end(), RangeNameInserter(pDoc, *pRangeNames));
1677     }
1678 }
1679 
SetStringRefSyntaxIfMissing()1680 void ScXMLImport::SetStringRefSyntaxIfMissing()
1681 {
1682     if (!pDoc)
1683         return;
1684 
1685     ScCalcConfig aCalcConfig = pDoc->GetCalcConfig();
1686 
1687     // Has any string ref syntax been imported?
1688     // If not, we need to take action
1689     if ( !aCalcConfig.mbHasStringRefSyntax )
1690     {
1691         aCalcConfig.meStringRefAddressSyntax = formula::FormulaGrammar::CONV_A1_XL_A1;
1692         pDoc->SetCalcConfig(aCalcConfig);
1693     }
1694 }
1695 
endDocument()1696 void SAL_CALL ScXMLImport::endDocument()
1697 {
1698     ScXMLImport::MutexGuard aGuard(*this);
1699     if (getImportFlags() & SvXMLImportFlags::CONTENT)
1700     {
1701         if (GetModel().is())
1702         {
1703             mpDocImport->finalize();
1704 
1705             uno::Reference<document::XViewDataSupplier> xViewDataSupplier(GetModel(), uno::UNO_QUERY);
1706             if (xViewDataSupplier.is())
1707             {
1708                 uno::Reference<container::XIndexAccess> xIndexAccess(xViewDataSupplier->getViewData());
1709                 if (xIndexAccess.is() && xIndexAccess->getCount() > 0)
1710                 {
1711                     uno::Sequence< beans::PropertyValue > aSeq;
1712                     if (xIndexAccess->getByIndex(0) >>= aSeq)
1713                     {
1714                         for (const auto& rProp : std::as_const(aSeq))
1715                         {
1716                             OUString sName(rProp.Name);
1717                             if (sName == SC_ACTIVETABLE)
1718                             {
1719                                 OUString sTabName;
1720                                 if(rProp.Value >>= sTabName)
1721                                 {
1722                                     SCTAB nTab(0);
1723                                     if (pDoc->GetTable(sTabName, nTab))
1724                                     {
1725                                         pDoc->SetVisibleTab(nTab);
1726                                         break;
1727                                     }
1728                                 }
1729                             }
1730                         }
1731                     }
1732                 }
1733             }
1734             SetLabelRanges();
1735             SetNamedRanges();
1736             SetSheetNamedRanges();
1737             SetStringRefSyntaxIfMissing();
1738             if (mpPivotSources)
1739                 // Process pivot table sources after the named ranges have been set.
1740                 mpPivotSources->process();
1741         }
1742         GetProgressBarHelper()->End();  // make room for subsequent SfxProgressBars
1743         if (pDoc)
1744         {
1745             pDoc->CompileXML();
1746 
1747             // After CompileXML, links must be completely changed to the new URLs.
1748             // Otherwise, hasExternalFile for API wouldn't work (#i116940#),
1749             // and typing a new formula would create a second link with the same "real" file name.
1750             if (pDoc->HasExternalRefManager())
1751                 pDoc->GetExternalRefManager()->updateAbsAfterLoad();
1752         }
1753 
1754         // If the stream contains cells outside of the current limits, the styles can't be re-created,
1755         // so stream copying is disabled then.
1756         if (pDoc && GetModel().is() && !pDoc->HasRangeOverflow())
1757         {
1758             // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
1759             // in UpdateRowHeights can already clear the flags again)
1760             ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->GetSheetSaveData();
1761 
1762             SCTAB nTabCount = pDoc->GetTableCount();
1763             for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
1764             {
1765                 pDoc->SetDrawPageSize(nTab);
1766                 if (!pSheetData->IsSheetBlocked( nTab ))
1767                     pDoc->SetStreamValid( nTab, true );
1768             }
1769         }
1770 
1771         // There are rows with optimal height which need to be updated
1772         if (pDoc && !maRecalcRowRanges.empty())
1773         {
1774             bool bLockHeight = pDoc->IsAdjustHeightLocked();
1775             if (bLockHeight)
1776             {
1777                 pDoc->UnlockAdjustHeight();
1778             }
1779 
1780             ScSizeDeviceProvider aProv(static_cast<ScDocShell*>(pDoc->GetDocumentShell()));
1781             ScDocRowHeightUpdater aUpdater(*pDoc, aProv.GetDevice(), aProv.GetPPTX(), aProv.GetPPTY(), &maRecalcRowRanges);
1782             aUpdater.update();
1783 
1784             if (bLockHeight)
1785             {
1786                 pDoc->LockAdjustHeight();
1787             }
1788         }
1789 
1790         aTables.FixupOLEs();
1791     }
1792     if (GetModel().is())
1793     {
1794         uno::Reference<document::XActionLockable> xActionLockable(GetModel(), uno::UNO_QUERY);
1795         if (xActionLockable.is())
1796             xActionLockable->removeActionLock();
1797     }
1798     SvXMLImport::endDocument();
1799 
1800     if (pDoc)
1801     {
1802         pDoc->BroadcastUno(SfxHint(SfxHintId::ScClearCache));
1803     }
1804 
1805     if(pDoc && bSelfImportingXMLSet)
1806         comphelper::getUnoTunnelImplementation<ScModelObj>(GetModel())->AfterXMLLoading();
1807 }
1808 
1809 // XEventListener
DisposingModel()1810 void ScXMLImport::DisposingModel()
1811 {
1812     SvXMLImport::DisposingModel();
1813     pDoc = nullptr;
1814 }
1815 
MutexGuard(ScXMLImport & rImport)1816 ScXMLImport::MutexGuard::MutexGuard(ScXMLImport& rImport) :
1817     mrImport(rImport)
1818 {
1819     mrImport.LockSolarMutex();
1820 }
1821 
~MutexGuard()1822 ScXMLImport::MutexGuard::~MutexGuard()
1823 {
1824     mrImport.UnlockSolarMutex();
1825 }
1826 
LockSolarMutex()1827 void ScXMLImport::LockSolarMutex()
1828 {
1829     // #i62677# When called from DocShell/Wrapper, the SolarMutex is already locked,
1830     // so there's no need to allocate (and later delete) the SolarMutexGuard.
1831     if (!mbLockSolarMutex)
1832     {
1833         DBG_TESTSOLARMUTEX();
1834         return;
1835     }
1836 
1837     if (nSolarMutexLocked == 0)
1838     {
1839         OSL_ENSURE(!pSolarMutexGuard, "Solar Mutex is locked");
1840         pSolarMutexGuard.reset(new SolarMutexGuard());
1841     }
1842     ++nSolarMutexLocked;
1843 }
1844 
UnlockSolarMutex()1845 void ScXMLImport::UnlockSolarMutex()
1846 {
1847     if (nSolarMutexLocked > 0)
1848     {
1849         nSolarMutexLocked--;
1850         if (nSolarMutexLocked == 0)
1851         {
1852             OSL_ENSURE(pSolarMutexGuard, "Solar Mutex is always unlocked");
1853             pSolarMutexGuard.reset();
1854         }
1855     }
1856 }
1857 
GetByteOffset() const1858 sal_Int32 ScXMLImport::GetByteOffset() const
1859 {
1860     sal_Int32 nOffset = -1;
1861     uno::Reference<xml::sax::XLocator> xLocator = GetLocator();
1862     uno::Reference<io::XSeekable> xSeek( xLocator, uno::UNO_QUERY );        //! should use different interface
1863     if ( xSeek.is() )
1864         nOffset = static_cast<sal_Int32>(xSeek->getPosition());
1865     return nOffset;
1866 }
1867 
SetRangeOverflowType(ErrCode nType)1868 void ScXMLImport::SetRangeOverflowType(ErrCode nType)
1869 {
1870     //  #i31130# Overflow is stored in the document, because the ScXMLImport object
1871     //  isn't available in ScXMLImportWrapper::ImportFromComponent when using the
1872     //  OOo->Oasis transformation.
1873 
1874     if ( pDoc )
1875         pDoc->SetRangeOverflowType( nType );
1876 }
1877 
ProgressBarIncrement()1878 void ScXMLImport::ProgressBarIncrement()
1879 {
1880     nProgressCount++;
1881     if (nProgressCount > 100)
1882     {
1883         GetProgressBarHelper()->Increment(nProgressCount);
1884         nProgressCount = 0;
1885     }
1886 }
1887 
ExtractFormulaNamespaceGrammar(OUString & rFormula,OUString & rFormulaNmsp,FormulaGrammar::Grammar & reGrammar,const OUString & rAttrValue,bool bRestrictToExternalNmsp) const1888 void ScXMLImport::ExtractFormulaNamespaceGrammar(
1889         OUString& rFormula, OUString& rFormulaNmsp, FormulaGrammar::Grammar& reGrammar,
1890         const OUString& rAttrValue, bool bRestrictToExternalNmsp ) const
1891 {
1892     // parse the attribute value, extract namespace ID, literal namespace, and formula string
1893     rFormulaNmsp.clear();
1894     sal_uInt16 nNsId = GetNamespaceMap().GetKeyByAttrName_( rAttrValue, nullptr, &rFormula, &rFormulaNmsp, false );
1895 
1896     // check if we have an ODF formula namespace
1897     if( !bRestrictToExternalNmsp ) switch( nNsId )
1898     {
1899         case XML_NAMESPACE_OOOC:
1900             rFormulaNmsp.clear();  // remove namespace string for built-in grammar
1901             reGrammar = FormulaGrammar::GRAM_PODF;
1902             return;
1903         case XML_NAMESPACE_OF:
1904             rFormulaNmsp.clear();  // remove namespace string for built-in grammar
1905             reGrammar = FormulaGrammar::GRAM_ODFF;
1906             return;
1907     }
1908 
1909     /*  Find default grammar for formulas without namespace. There may be
1910         documents in the wild that stored no namespace in ODF 1.0/1.1. Use
1911         GRAM_PODF then (old style ODF 1.0/1.1 formulas). The default for ODF
1912         1.2 and later without namespace is GRAM_ODFF (OpenFormula). */
1913     FormulaGrammar::Grammar eDefaultGrammar =
1914         (GetDocument()->GetStorageGrammar() == FormulaGrammar::GRAM_PODF) ?
1915             FormulaGrammar::GRAM_PODF : FormulaGrammar::GRAM_ODFF;
1916 
1917     /*  Check if we have no namespace at all. The value XML_NAMESPACE_NONE
1918         indicates that there is no colon. If the first character of the
1919         attribute value is the equality sign, the value XML_NAMESPACE_UNKNOWN
1920         indicates that there is a colon somewhere in the formula string. */
1921     if( (nNsId == XML_NAMESPACE_NONE) || ((nNsId == XML_NAMESPACE_UNKNOWN) && (rAttrValue.toChar() == '=')) )
1922     {
1923         rFormula = rAttrValue;          // return entire string as formula
1924         reGrammar = eDefaultGrammar;
1925         return;
1926     }
1927 
1928     /*  Check if a namespace URL could be resolved from the attribute value.
1929         Use that namespace only, if the Calc document knows an associated
1930         external formula parser. This prevents that the range operator in
1931         conjunction with defined names is confused as namespaces prefix, e.g.
1932         in the expression 'table:A1' where 'table' is a named reference. */
1933     if( ((nNsId & XML_NAMESPACE_UNKNOWN_FLAG) != 0) && !rFormulaNmsp.isEmpty() &&
1934         GetDocument()->GetFormulaParserPool().hasFormulaParser( rFormulaNmsp ) )
1935     {
1936         reGrammar = FormulaGrammar::GRAM_EXTERNAL;
1937         return;
1938     }
1939 
1940     /*  All attempts failed (e.g. no namespace and no leading equality sign, or
1941         an invalid namespace prefix), continue with the entire attribute value. */
1942     rFormula = rAttrValue;
1943     rFormulaNmsp.clear();  // remove any namespace string
1944     reGrammar = eDefaultGrammar;
1945 }
1946 
GetFormulaErrorConstant(const OUString & rStr) const1947 FormulaError ScXMLImport::GetFormulaErrorConstant( const OUString& rStr ) const
1948 {
1949     if (!mpComp)
1950         return FormulaError::NONE;
1951 
1952     return mpComp->GetErrorConstant(rStr);
1953 }
1954 
GetEditEngine()1955 ScEditEngineDefaulter* ScXMLImport::GetEditEngine()
1956 {
1957     if (!mpEditEngine)
1958     {
1959         mpEditEngine.reset(new ScEditEngineDefaulter(pDoc->GetEnginePool()));
1960         mpEditEngine->SetRefMapMode(MapMode(MapUnit::Map100thMM));
1961         mpEditEngine->SetEditTextObjectPool(pDoc->GetEditPool());
1962         mpEditEngine->SetUpdateMode(false);
1963         mpEditEngine->EnableUndo(false);
1964         mpEditEngine->SetControlWord(mpEditEngine->GetControlWord() & ~EEControlBits::ALLOWBIGOBJS);
1965     }
1966     return mpEditEngine.get();
1967 }
1968 
GetEditAttributeMap() const1969 const ScXMLEditAttributeMap& ScXMLImport::GetEditAttributeMap() const
1970 {
1971     if (!mpEditAttrMap)
1972         mpEditAttrMap.reset(new ScXMLEditAttributeMap);
1973     return *mpEditAttrMap;
1974 }
1975 
NotifyEmbeddedFontRead()1976 void ScXMLImport::NotifyEmbeddedFontRead()
1977 {
1978     if (pDoc)
1979         pDoc->SetEmbedFonts(true);
1980 }
1981 
GetDetectiveOpArray()1982 ScMyImpDetectiveOpArray* ScXMLImport::GetDetectiveOpArray()
1983 {
1984     if (!pDetectiveOpArray)
1985         pDetectiveOpArray.reset(new ScMyImpDetectiveOpArray());
1986     return pDetectiveOpArray.get();
1987 }
1988 
TestImportFODS(SvStream & rStream)1989 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportFODS(SvStream &rStream)
1990 {
1991     ScDLL::Init();
1992 
1993     SfxObjectShellLock xDocSh(new ScDocShell);
1994     xDocSh->DoInitNew();
1995     uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
1996 
1997     uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
1998     uno::Reference<io::XInputStream> xStream(new ::utl::OSeekableInputStreamWrapper(rStream));
1999     uno::Reference<uno::XInterface> xInterface(xMultiServiceFactory->createInstance("com.sun.star.comp.Writer.XmlFilterAdaptor"), uno::UNO_SET_THROW);
2000 
2001     css::uno::Sequence<OUString> aUserData(7);
2002     aUserData[0] = "com.sun.star.comp.filter.OdfFlatXml";
2003     aUserData[2] = "com.sun.star.comp.Calc.XMLOasisImporter";
2004     aUserData[3] = "com.sun.star.comp.Calc.XMLOasisExporter";
2005     aUserData[6] = "true";
2006     uno::Sequence<beans::PropertyValue> aAdaptorArgs(comphelper::InitPropertySequence(
2007     {
2008         { "UserData", uno::Any(aUserData) },
2009     }));
2010     css::uno::Sequence<uno::Any> aOuterArgs(1);
2011     aOuterArgs[0] <<= aAdaptorArgs;
2012 
2013     uno::Reference<lang::XInitialization> xInit(xInterface, uno::UNO_QUERY_THROW);
2014     xInit->initialize(aOuterArgs);
2015 
2016     uno::Reference<document::XImporter> xImporter(xInterface, uno::UNO_QUERY_THROW);
2017     uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
2018     {
2019         { "InputStream", uno::Any(xStream) },
2020         { "URL", uno::Any(OUString("private:stream")) },
2021     }));
2022     xImporter->setTargetDocument(xModel);
2023 
2024     uno::Reference<document::XFilter> xFilter(xInterface, uno::UNO_QUERY_THROW);
2025     //SetLoading hack because the document properties will be re-initted
2026     //by the xml filter and during the init, while it's considered uninitialized,
2027     //setting a property will inform the document it's modified, which attempts
2028     //to update the properties, which throws cause the properties are uninitialized
2029     xDocSh->SetLoading(SfxLoadedFlags::NONE);
2030     bool ret = xFilter->filter(aArgs);
2031     xDocSh->SetLoading(SfxLoadedFlags::ALL);
2032 
2033     xDocSh->DoClose();
2034 
2035     return ret;
2036 }
2037 
TestImportXLSX(SvStream & rStream)2038 extern "C" SAL_DLLPUBLIC_EXPORT bool TestImportXLSX(SvStream &rStream)
2039 {
2040     ScDLL::Init();
2041 
2042     SfxObjectShellLock xDocSh(new ScDocShell);
2043     xDocSh->DoInitNew();
2044     uno::Reference<frame::XModel> xModel(xDocSh->GetModel());
2045 
2046     uno::Reference<lang::XMultiServiceFactory> xMultiServiceFactory(comphelper::getProcessServiceFactory());
2047     uno::Reference<io::XInputStream> xStream(new utl::OSeekableInputStreamWrapper(rStream));
2048 
2049     uno::Reference<document::XFilter> xFilter(xMultiServiceFactory->createInstance("com.sun.star.comp.oox.xls.ExcelFilter"), uno::UNO_QUERY_THROW);
2050 
2051     uno::Reference<document::XImporter> xImporter(xFilter, uno::UNO_QUERY_THROW);
2052     uno::Sequence<beans::PropertyValue> aArgs(comphelper::InitPropertySequence(
2053     {
2054         { "InputStream", uno::makeAny(xStream) },
2055         { "InputMode", uno::makeAny(true) },
2056     }));
2057     xImporter->setTargetDocument(xModel);
2058 
2059     //SetLoading hack because the document properties will be re-initted
2060     //by the xml filter and during the init, while it's considered uninitialized,
2061     //setting a property will inform the document it's modified, which attempts
2062     //to update the properties, which throws cause the properties are uninitialized
2063     xDocSh->SetLoading(SfxLoadedFlags::NONE);
2064     bool ret = false;
2065     try
2066     {
2067         ret = xFilter->filter(aArgs);
2068     }
2069     catch (const css::io::IOException&)
2070     {
2071     }
2072     catch (const css::lang::WrappedTargetRuntimeException&)
2073     {
2074     }
2075     xDocSh->SetLoading(SfxLoadedFlags::ALL);
2076 
2077     xDocSh->DoClose();
2078 
2079     return ret;
2080 }
2081 
2082 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
2083