LibreOffice Module sc (master) 1
xmlexternaltabi.cxx
Go to the documentation of this file.
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 "xmlexternaltabi.hxx"
21#include "xmlimprt.hxx"
22#include "xmltabi.hxx"
23#include "xmlstyli.hxx"
24
25#include <document.hxx>
26#include <documentimport.hxx>
27
30#include <xmloff/xmltoken.hxx>
31#include <xmloff/xmluconv.hxx>
32
34
35#include <com/sun/star/util/NumberFormat.hpp>
36
37using namespace ::com::sun::star;
38using namespace ::com::sun::star::xml::sax;
39using namespace ::xmloff::token;
40
41using ::com::sun::star::uno::Reference;
42
44 ScXMLImport& rImport,
46 ScXMLImportContext( rImport ),
47 mrExternalRefInfo(rRefInfo)
48{
49 using namespace ::xmloff::token;
50
51 if ( !rAttrList.is() )
52 return;
53
54 for (auto &it : *rAttrList)
55 {
56 sal_Int32 nAttrToken = it.getToken();
57 if ( nAttrToken == XML_ELEMENT( XLINK, XML_HREF ) )
58 maRelativeUrl = it.toString();
59 else if ( nAttrToken == XML_ELEMENT( TABLE, XML_TABLE_NAME ) )
60 // todo
61 ;
62 else if ( nAttrToken == XML_ELEMENT( TABLE, XML_FILTER_NAME ) )
63 maFilterName = it.toString();
64 else if ( nAttrToken == XML_ELEMENT( TABLE, XML_FILTER_OPTIONS ) )
65 maFilterOptions = it.toString();
66 }
67}
68
70{
71}
72
80static bool lcl_isValidRelativeURL(const OUString& rUrl)
81{
82 sal_Int32 n = ::std::min( rUrl.getLength(), static_cast<sal_Int32>(3));
83 if (n < 3)
84 return false;
85 const sal_Unicode* p = rUrl.getStr();
86 for (sal_Int32 i = 0; i < n; ++i)
87 {
88 sal_Unicode c = p[i];
89 if (i < 2 && c != '.')
90 // the path must begin with '..'
91 return false;
92 else if (i == 2 && c != '/')
93 // a '/' path separator must follow
94 return false;
95 }
96 return true;
97}
98
99void SAL_CALL ScXMLExternalRefTabSourceContext::endFastElement( sal_Int32 /*nElement*/ )
100{
102 if (!pDoc)
103 return;
104
109}
110
112 ScXMLImport& rImport, ScXMLExternalTabData& rRefInfo ) :
113 ScXMLImportContext( rImport ),
114 mrExternalRefInfo(rRefInfo)
115{
116}
117
119{
120}
121
122Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefRowsContext::createFastChildContext(
123 sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
124{
125 // #i101319# row elements inside group, rows or header-rows
126 // are treated like row elements directly in the table element
127
130
131 switch (nElement)
132 {
140 GetScImport(), pAttribList, mrExternalRefInfo);
141 default:
142 XMLOFF_WARN_UNKNOWN_ELEMENT("sc", nElement);
143 }
144 return nullptr;
145}
146
148 ScXMLImport& rImport,
150 ScXMLImportContext( rImport ),
151 mrScImport(rImport),
152 mrExternalRefInfo(rRefInfo),
153 mnRepeatRowCount(1)
154{
156
157 for (auto &it : *rAttrList)
158 {
159 switch (it.getToken())
160 {
162 {
163 mnRepeatRowCount = std::max(it.toInt32(), static_cast<sal_Int32>(1));
164 }
165 break;
166 }
167 }
168}
169
171{
172}
173
174Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefRowContext::createFastChildContext(
175 sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
176{
179
180 if (nElement == XML_ELEMENT(TABLE, XML_TABLE_CELL) || nElement == XML_ELEMENT(TABLE, XML_COVERED_TABLE_CELL))
182
183 return nullptr;
184}
185
186void SAL_CALL ScXMLExternalRefRowContext::endFastElement( sal_Int32 /* nElement */ )
187{
189
190 for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i)
191 {
192 // Performance: duplicates of a non-existent row will still not exist.
193 // Don't find that out for every cell.
194 // External references often are a sparse matrix.
195 if (i == 1 && !pTab->hasRow( mrExternalRefInfo.mnRow))
196 {
198 return;
199 }
200
201 for (sal_Int32 j = 0; j < mrExternalRefInfo.mnCol; ++j)
202 {
203 ScExternalRefCache::TokenRef pToken = pTab->getCell(
204 static_cast<SCCOL>(j), static_cast<SCROW>(mrExternalRefInfo.mnRow));
205
206 if (pToken)
207 {
208 pTab->setCell(static_cast<SCCOL>(j),
209 static_cast<SCROW>(mrExternalRefInfo.mnRow+i), pToken);
210 }
211 }
212 }
214}
215
217 ScXMLImport& rImport,
219 ScXMLImportContext( rImport ),
220 mrScImport(rImport),
221 mrExternalRefInfo(rRefInfo),
222 mfCellValue(0.0),
223 mnRepeatCount(1),
224 mnNumberFormat(-1),
225 mnCellType(css::util::NumberFormat::UNDEFINED),
226 mbIsNumeric(false),
227 mbIsEmpty(true)
228{
229 using namespace ::xmloff::token;
230
231 for (auto &it : *rAttrList)
232 {
233 switch ( it.getToken() )
234 {
236 {
237 XMLTableStylesContext* pStyles = static_cast<XMLTableStylesContext*>(mrScImport.GetAutoStyles());
238 const XMLTableStyleContext* pStyle = static_cast<const XMLTableStyleContext*>(
239 pStyles->FindStyleChildContext(XmlStyleFamily::TABLE_CELL, it.toString(), true));
240 if (pStyle)
241 mnNumberFormat = const_cast<XMLTableStyleContext*>(pStyle)->GetNumberFormat();
242 }
243 break;
245 {
246 mnRepeatCount = ::std::max( it.toInt32(), static_cast<sal_Int32>(1) );
247 }
248 break;
250 {
251 mnCellType = ScXMLImport::GetCellType( it.toCString(), it.getLength() );
252 }
253 break;
255 {
256 if ( !it.isEmpty() )
257 {
258 mfCellValue = it.toDouble();
259 mbIsNumeric = true;
260 mbIsEmpty = false;
261 }
262 }
263 break;
265 {
266 if ( !it.isEmpty() && mrScImport.SetNullDateOnUnitConverter() )
267 {
268 mrScImport.GetMM100UnitConverter().convertDateTime( mfCellValue, it.toView() );
269 mbIsNumeric = true;
270 mbIsEmpty = false;
271 }
272 }
273 break;
275 {
276 if ( !it.isEmpty() )
277 {
279 mbIsNumeric = true;
280 mbIsEmpty = false;
281 }
282 }
283 break;
285 {
286 if ( !it.isEmpty() )
287 {
288 maCellString = it.toString();
289 mbIsNumeric = false;
290 mbIsEmpty = false;
291 }
292 }
293 break;
295 {
296 if ( !it.isEmpty() )
297 {
298 mfCellValue = IsXMLToken( it, XML_TRUE ) ? 1.0 : 0.0;
299 mbIsNumeric = true;
300 mbIsEmpty = false;
301 }
302 }
303 break;
304 default:
305 ;
306 }
307 }
308}
309
311{
312}
313
314Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefCellContext::createFastChildContext(
315 sal_Int32 nElement, const Reference< XFastAttributeList >& /*xAttrList*/ )
316{
317 if (nElement == XML_ELEMENT(TEXT, XML_P))
319
320 return nullptr;
321}
322
323void SAL_CALL ScXMLExternalRefCellContext::endFastElement( sal_Int32 /*nElement*/ )
324{
325 if (!maCellString.isEmpty())
326 mbIsEmpty = false;
327
328 for (sal_Int32 i = 0; i < mnRepeatCount; ++i, ++mrExternalRefInfo.mnCol)
329 {
330 if (mbIsEmpty)
331 continue;
332
334 if (mbIsNumeric)
335 aToken.reset(new formula::FormulaDoubleToken(mfCellValue));
336 else
337 {
340 aToken.reset(new formula::FormulaStringToken(std::move(aSS)));
341 }
342
343 sal_uInt32 nNumFmt = mnNumberFormat >= 0 ? static_cast<sal_uInt32>(mnNumberFormat) : 0;
345 static_cast<SCCOL>(mrExternalRefInfo.mnCol),
346 static_cast<SCROW>(mrExternalRefInfo.mnRow),
347 aToken, nNumFmt);
348 }
349}
350
352{
353 maCellString = rStr;
354}
355
357 ScXMLImport& rImport,
358 ScXMLExternalRefCellContext& rParent ) :
359 ScXMLImportContext( rImport ),
360 mrParent(rParent)
361{
362}
363
365{
366}
367
368void SAL_CALL ScXMLExternalRefCellTextContext::characters( const OUString& rChars )
369{
370 maCellStrBuf.append( rChars );
371}
372
373void SAL_CALL ScXMLExternalRefCellTextContext::endFastElement( sal_Int32 /*nElement*/ )
374{
375 mrParent.SetCellString( maCellStrBuf.makeStringAndClear() );
376}
377
378/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
BaseContainerNodeSharedPtr & mrParent
ScDocument & getDoc()
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:625
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:601
std::shared_ptr< Table > TableTypeRef
::formula::FormulaTokenRef TokenRef
void setFilterData(sal_uInt16 nFileId, const OUString &rFilterName, const OUString &rOptions)
Set the filter name and options if any for a given source document.
void setRelativeFileName(sal_uInt16 nFileId, const OUString &rRelUrl)
Set a relative file path for the specified file ID.
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
virtual ~ScXMLExternalRefCellContext() override
ScXMLExternalTabData & mrExternalRefInfo
ScXMLExternalRefCellContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList, ScXMLExternalTabData &rRefInfo)
void SetCellString(const OUString &rStr)
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
ScXMLExternalRefCellTextContext(ScXMLImport &rImport, ScXMLExternalRefCellContext &rParent)
virtual ~ScXMLExternalRefCellTextContext() override
virtual void SAL_CALL characters(const OUString &rChars) override
ScXMLExternalRefCellContext & mrParent
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
ScXMLExternalRefRowContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList, ScXMLExternalTabData &rRefInfo)
ScXMLExternalTabData & mrExternalRefInfo
virtual ~ScXMLExternalRefRowContext() override
ScXMLExternalRefRowsContext(ScXMLImport &rImport, ScXMLExternalTabData &rRefInfo)
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
virtual ~ScXMLExternalRefRowsContext() override
ScXMLExternalTabData & mrExternalRefInfo
virtual ~ScXMLExternalRefTabSourceContext() override
ScXMLExternalRefTabSourceContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList, ScXMLExternalTabData &rRefInfo)
ScXMLExternalTabData & mrExternalRefInfo
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
This class exists only to provide GetScImport() to its derived classes.
ScXMLImport & GetScImport()
ScDocumentImport & GetDoc()
Definition: xmlimprt.cxx:506
bool SetNullDateOnUnitConverter()
Definition: xmlimprt.cxx:1089
ScDocument * GetDocument()
Definition: xmlimprt.hxx:205
static sal_Int16 GetCellType(const char *rStrValue, const sal_Int32 nStrLength)
Definition: xmlimprt.cxx:511
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
static void convertDuration(OUStringBuffer &rBuffer, const double fTime)
SharedString intern(const OUString &rStr)
UNDEFINED
void * p
sal_Int64 n
TABLE
int i
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
XML_TABLE_NAME
XML_TABLE_ROW
XML_COVERED_TABLE_CELL
XML_BOOLEAN_VALUE
XML_DATE_VALUE
XML_HREF
XML_TRUE
XML_TIME_VALUE
XML_FILTER_OPTIONS
XML_TABLE_ROW_GROUP
XML_VALUE
XML_STRING_VALUE
XML_STYLE_NAME
XML_P
XML_TABLE_HEADER_ROWS
XML_VALUE_TYPE
XML_NUMBER_ROWS_REPEATED
XML_NUMBER_COLUMNS_REPEATED
XML_TABLE_ROWS
XML_FILTER_NAME
XML_TABLE_CELL
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
sal_uInt16 mnFileId
Definition: xmltabi.hxx:34
ScExternalRefCache::TableTypeRef mpCacheTable
Definition: xmltabi.hxx:31
TEXT
sal_uInt16 sal_Unicode
sal_Int16 SCCOL
Definition: types.hxx:21
sal_Int32 SCROW
Definition: types.hxx:17
static bool lcl_isValidRelativeURL(const OUString &rUrl)
Make sure the URL is a valid relative URL, mainly to avoid storing absolute URL as relative URL by ac...
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
#define XML_ELEMENT(prefix, name)