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 
28 #include <svl/sharedstringpool.hxx>
29 #include <xmloff/xmlnamespace.hxx>
30 #include <xmloff/xmltoken.hxx>
31 #include <xmloff/xmluconv.hxx>
32 
33 #include <sax/tools/converter.hxx>
34 
35 #include <com/sun/star/util/NumberFormat.hpp>
36 
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::xml::sax;
39 using namespace ::xmloff::token;
40 
41 using ::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 
80 static 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 
99 void SAL_CALL ScXMLExternalRefTabSourceContext::endFastElement( sal_Int32 /*nElement*/ )
100 {
101  ScDocument* pDoc = GetScImport().GetDocument();
102  if (!pDoc)
103  return;
104 
105  ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
109 }
110 
112  ScXMLImport& rImport, ScXMLExternalTabData& rRefInfo ) :
113  ScXMLImportContext( rImport ),
114  mrExternalRefInfo(rRefInfo)
115 {
116 }
117 
119 {
120 }
121 
122 Reference< 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 
128  sax_fastparser::FastAttributeList *pAttribList =
130 
131  switch (nElement)
132  {
136  return new ScXMLExternalRefRowsContext(
139  return new ScXMLExternalRefRowContext(
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 
174 Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefRowContext::createFastChildContext(
175  sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
176 {
177  sax_fastparser::FastAttributeList *pAttribList =
179 
180  if (nElement == XML_ELEMENT(TABLE, XML_TABLE_CELL) || nElement == XML_ELEMENT(TABLE, XML_COVERED_TABLE_CELL))
181  return new ScXMLExternalRefCellContext(mrScImport, pAttribList, mrExternalRefInfo);
182 
183  return nullptr;
184 }
185 
186 void 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  {
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  {
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 
314 Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefCellContext::createFastChildContext(
315  sal_Int32 nElement, const Reference< XFastAttributeList >& /*xAttrList*/ )
316 {
317  if (nElement == XML_ELEMENT(TEXT, XML_P))
318  return new ScXMLExternalRefCellTextContext(mrScImport, *this);
319 
320  return nullptr;
321 }
322 
323 void 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  {
338  ScDocument& rDoc = mrScImport.GetDoc().getDoc();
340  aToken.reset(new formula::FormulaStringToken(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 
368 void SAL_CALL ScXMLExternalRefCellTextContext::characters( const OUString& rChars )
369 {
370  maCellStrBuf.append( rChars );
371 }
372 
373 void SAL_CALL ScXMLExternalRefCellTextContext::endFastElement( sal_Int32 /*nElement*/ )
374 {
375  mrParent.SetCellString( maCellStrBuf.makeStringAndClear() );
376 }
377 
378 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
exports com.sun.star.lib. util
void setFilterData(sal_uInt16 nFileId, const OUString &rFilterName, const OUString &rOptions)
Set the filter name and options if any for a given source document.
UNDEFINED
XML_NUMBER_ROWS_REPEATED
XML_TABLE_NAME
SharedString intern(const OUString &rStr)
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:562
XML_VALUE_TYPE
XML_STYLE_NAME
sal_uInt16 mnFileId
Definition: xmltabi.hxx:36
ScDocument * GetDocument()
Definition: xmlimprt.hxx:206
virtual ~ScXMLExternalRefRowsContext() override
sal_Int64 n
XML_VALUE
ScXMLExternalRefCellContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList, ScXMLExternalTabData &rRefInfo)
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
XML_TABLE_ROW_GROUP
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
ScXMLExternalRefTabSourceContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList, ScXMLExternalTabData &rRefInfo)
ScXMLExternalRefCellContext & mrParent
ScXMLExternalRefCellTextContext(ScXMLImport &rImport, ScXMLExternalRefCellContext &rParent)
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...
ScExternalRefCache::TableTypeRef mpCacheTable
Definition: xmltabi.hxx:33
XML_FILTER_OPTIONS
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
ScXMLExternalTabData & mrExternalRefInfo
sal_uInt16 sal_Unicode
bool SetNullDateOnUnitConverter()
Definition: xmlimprt.cxx:1103
XML_TABLE_CELL
XML_NUMBER_COLUMNS_REPEATED
virtual css::uno::Reference< XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:617
virtual void SAL_CALL characters(const OUString &rChars) override
ScXMLExternalRefRowContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList, ScXMLExternalTabData &rRefInfo)
virtual ~ScXMLExternalRefTabSourceContext() override
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
void setRelativeFileName(sal_uInt16 nFileId, const OUString &rRelUrl)
Set a relative file path for the specified file ID.
This class exists only to provide GetScImport() to its derived classes.
ScXMLExternalTabData & mrExternalRefInfo
XML_TABLE_ROW
int i
void convertDateTime(OUStringBuffer &rBuffer, const double &fDateTime, bool const bAddTimeIf0AM=false)
XML_HREF
XML_STRING_VALUE
static void convertDuration(OUStringBuffer &rBuffer, const double fTime)
virtual ~ScXMLExternalRefCellTextContext() override
ScXMLImport & GetScImport()
static sal_Int16 GetCellType(const char *rStrValue, const sal_Int32 nStrLength)
Definition: xmlimprt.cxx:518
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
XML_COVERED_TABLE_CELL
TABLE
::formula::FormulaTokenRef TokenRef
virtual ~ScXMLExternalRefCellContext() override
XML_BOOLEAN_VALUE
void SetCellString(const OUString &rStr)
ScXMLExternalRefRowsContext(ScXMLImport &rImport, ScXMLExternalTabData &rRefInfo)
std::shared_ptr< Table > TableTypeRef
XML_FILTER_NAME
XML_P
#define XML_ELEMENT(prefix, name)
const SvXMLUnitConverter & GetMM100UnitConverter() const
void * p
ScXMLExternalTabData & mrExternalRefInfo
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
XML_TRUE
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
ScXMLExternalTabData & mrExternalRefInfo
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
XML_DATE_VALUE
XML_TABLE_HEADER_ROWS
XML_TIME_VALUE
SvXMLStylesContext * GetAutoStyles()
XML_TABLE_ROWS
BaseContainerNodeSharedPtr & mrParent
virtual ~ScXMLExternalRefRowContext() override
TEXT
ScDocumentImport & GetDoc()
Definition: xmlimprt.cxx:513
ScDocument & getDoc()