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 
40 using ::com::sun::star::uno::Reference;
41 
43  ScXMLImport& rImport,
45  ScXMLImportContext( rImport ),
46  mrExternalRefInfo(rRefInfo)
47 {
48  using namespace ::xmloff::token;
49 
50  if ( !rAttrList.is() )
51  return;
52 
53  for (auto &it : *rAttrList)
54  {
55  sal_Int32 nAttrToken = it.getToken();
56  if ( nAttrToken == XML_ELEMENT( XLINK, XML_HREF ) )
57  maRelativeUrl = it.toString();
58  else if ( nAttrToken == XML_ELEMENT( TABLE, XML_TABLE_NAME ) )
59  // todo
60  ;
61  else if ( nAttrToken == XML_ELEMENT( TABLE, XML_FILTER_NAME ) )
62  maFilterName = it.toString();
63  else if ( nAttrToken == XML_ELEMENT( TABLE, XML_FILTER_OPTIONS ) )
64  maFilterOptions = it.toString();
65  }
66 }
67 
69 {
70 }
71 
79 static bool lcl_isValidRelativeURL(const OUString& rUrl)
80 {
81  sal_Int32 n = ::std::min( rUrl.getLength(), static_cast<sal_Int32>(3));
82  if (n < 3)
83  return false;
84  const sal_Unicode* p = rUrl.getStr();
85  for (sal_Int32 i = 0; i < n; ++i)
86  {
87  sal_Unicode c = p[i];
88  if (i < 2 && c != '.')
89  // the path must begin with '..'
90  return false;
91  else if (i == 2 && c != '/')
92  // a '/' path separator must follow
93  return false;
94  }
95  return true;
96 }
97 
98 void SAL_CALL ScXMLExternalRefTabSourceContext::endFastElement( sal_Int32 /*nElement*/ )
99 {
100  ScDocument* pDoc = GetScImport().GetDocument();
101  if (!pDoc)
102  return;
103 
104  ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
108 }
109 
111  ScXMLImport& rImport, ScXMLExternalTabData& rRefInfo ) :
112  ScXMLImportContext( rImport ),
113  mrExternalRefInfo(rRefInfo)
114 {
115 }
116 
118 {
119 }
120 
121 Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefRowsContext::createFastChildContext(
122  sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
123 {
124  // #i101319# row elements inside group, rows or header-rows
125  // are treated like row elements directly in the table element
126 
127  const SvXMLTokenMap& rTokenMap = GetScImport().GetTableRowsElemTokenMap();
128  sal_uInt16 nToken = rTokenMap.Get( nElement );
129  sax_fastparser::FastAttributeList *pAttribList =
131 
132  switch (nToken)
133  {
137  return new ScXMLExternalRefRowsContext(
140  return new ScXMLExternalRefRowContext(
141  GetScImport(), pAttribList, mrExternalRefInfo);
142  default:
143  ;
144  }
145  return nullptr;
146 }
147 
149  ScXMLImport& rImport,
151  ScXMLImportContext( rImport ),
152  mrScImport(rImport),
153  mrExternalRefInfo(rRefInfo),
154  mnRepeatRowCount(1)
155 {
157 
158  const SvXMLTokenMap& rAttrTokenMap = mrScImport.GetTableRowAttrTokenMap();
159  if ( !rAttrList.is() )
160  return;
161 
162  for (auto &it : *rAttrList)
163  {
164  switch ( rAttrTokenMap.Get( it.getToken() ) )
165  {
167  {
168  mnRepeatRowCount = std::max(it.toInt32(), static_cast<sal_Int32>(1));
169  }
170  break;
171  }
172  }
173 }
174 
176 {
177 }
178 
179 Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefRowContext::createFastChildContext(
180  sal_Int32 nElement, const Reference< XFastAttributeList >& xAttrList )
181 {
182  const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowElemTokenMap();
183  sal_uInt16 nToken = rTokenMap.Get( nElement );
184  sax_fastparser::FastAttributeList *pAttribList =
186 
187  if (nToken == XML_TOK_TABLE_ROW_CELL || nToken == XML_TOK_TABLE_ROW_COVERED_CELL)
188  return new ScXMLExternalRefCellContext(mrScImport, pAttribList, mrExternalRefInfo);
189 
190  return nullptr;
191 }
192 
193 void SAL_CALL ScXMLExternalRefRowContext::endFastElement( sal_Int32 /* nElement */ )
194 {
196 
197  for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i)
198  {
199  // Performance: duplicates of a non-existent row will still not exist.
200  // Don't find that out for every cell.
201  // External references often are a sparse matrix.
202  if (i == 1 && !pTab->hasRow( mrExternalRefInfo.mnRow))
203  {
205  return;
206  }
207 
208  for (sal_Int32 j = 0; j < mrExternalRefInfo.mnCol; ++j)
209  {
210  ScExternalRefCache::TokenRef pToken = pTab->getCell(
211  static_cast<SCCOL>(j), static_cast<SCROW>(mrExternalRefInfo.mnRow));
212 
213  if (pToken)
214  {
215  pTab->setCell(static_cast<SCCOL>(j),
216  static_cast<SCROW>(mrExternalRefInfo.mnRow+i), pToken);
217  }
218  }
219  }
221 }
222 
224  ScXMLImport& rImport,
226  ScXMLImportContext( rImport ),
227  mrScImport(rImport),
228  mrExternalRefInfo(rRefInfo),
229  mfCellValue(0.0),
230  mnRepeatCount(1),
231  mnNumberFormat(-1),
232  mnCellType(css::util::NumberFormat::UNDEFINED),
233  mbIsNumeric(false),
234  mbIsEmpty(true)
235 {
236  using namespace ::xmloff::token;
237 
238  const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
239  if ( !rAttrList.is() )
240  return;
241 
242  for (auto &it : *rAttrList)
243  {
244  switch ( rTokenMap.Get( it.getToken() ) )
245  {
247  {
249  const XMLTableStyleContext* pStyle = static_cast<const XMLTableStyleContext*>(
250  pStyles->FindStyleChildContext(XmlStyleFamily::TABLE_CELL, it.toString(), true));
251  if (pStyle)
252  mnNumberFormat = const_cast<XMLTableStyleContext*>(pStyle)->GetNumberFormat();
253  }
254  break;
256  {
257  mnRepeatCount = ::std::max( it.toInt32(), static_cast<sal_Int32>(1) );
258  }
259  break;
261  {
262  mnCellType = ScXMLImport::GetCellType( it.toCString(), it.getLength() );
263  }
264  break;
266  {
267  if ( !it.isEmpty() )
268  {
269  mfCellValue = it.toDouble();
270  mbIsNumeric = true;
271  mbIsEmpty = false;
272  }
273  }
274  break;
276  {
277  if ( !it.isEmpty() && mrScImport.SetNullDateOnUnitConverter() )
278  {
280  mbIsNumeric = true;
281  mbIsEmpty = false;
282  }
283  }
284  break;
286  {
287  if ( !it.isEmpty() )
288  {
290  mbIsNumeric = true;
291  mbIsEmpty = false;
292  }
293  }
294  break;
296  {
297  if ( !it.isEmpty() )
298  {
299  maCellString = it.toString();
300  mbIsNumeric = false;
301  mbIsEmpty = false;
302  }
303  }
304  break;
306  {
307  if ( !it.isEmpty() )
308  {
309  mfCellValue = IsXMLToken( it, XML_TRUE ) ? 1.0 : 0.0;
310  mbIsNumeric = true;
311  mbIsEmpty = false;
312  }
313  }
314  break;
315  default:
316  ;
317  }
318  }
319 }
320 
322 {
323 }
324 
325 Reference< XFastContextHandler > SAL_CALL ScXMLExternalRefCellContext::createFastChildContext(
326  sal_Int32 nElement, const Reference< XFastAttributeList >& /*xAttrList*/ )
327 {
329  sal_uInt16 nToken = rTokenMap.Get( nElement );
330 
331  if (nToken == XML_TOK_TABLE_ROW_CELL_P)
332  return new ScXMLExternalRefCellTextContext(mrScImport, *this);
333 
334  return nullptr;
335 }
336 
337 void SAL_CALL ScXMLExternalRefCellContext::endFastElement( sal_Int32 /*nElement*/ )
338 {
339  if (!maCellString.isEmpty())
340  mbIsEmpty = false;
341 
342  for (sal_Int32 i = 0; i < mnRepeatCount; ++i, ++mrExternalRefInfo.mnCol)
343  {
344  if (mbIsEmpty)
345  continue;
346 
348  if (mbIsNumeric)
349  aToken.reset(new formula::FormulaDoubleToken(mfCellValue));
350  else
351  {
352  ScDocument& rDoc = mrScImport.GetDoc().getDoc();
354  aToken.reset(new formula::FormulaStringToken(aSS));
355  }
356 
357  sal_uInt32 nNumFmt = mnNumberFormat >= 0 ? static_cast<sal_uInt32>(mnNumberFormat) : 0;
359  static_cast<SCCOL>(mrExternalRefInfo.mnCol),
360  static_cast<SCROW>(mrExternalRefInfo.mnRow),
361  aToken, nNumFmt);
362  }
363 }
364 
366 {
367  maCellString = rStr;
368 }
369 
371  ScXMLImport& rImport,
372  ScXMLExternalRefCellContext& rParent ) :
373  ScXMLImportContext( rImport ),
374  mrParent(rParent)
375 {
376 }
377 
379 {
380 }
381 
382 void SAL_CALL ScXMLExternalRefCellTextContext::characters( const OUString& rChars )
383 {
384  maCellStrBuf.append( rChars );
385 }
386 
387 void SAL_CALL ScXMLExternalRefCellTextContext::endFastElement( sal_Int32 /*nElement*/ )
388 {
389  mrParent.SetCellString( maCellStrBuf.makeStringAndClear() );
390 }
391 
392 /* 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.
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
UNDEFINED
XML_TABLE_NAME
SharedString intern(const OUString &rStr)
SC_DLLPUBLIC svl::SharedStringPool & GetSharedStringPool()
Definition: documen2.cxx:563
sal_uInt16 mnFileId
Definition: xmltabi.hxx:36
ScDocument * GetDocument()
Definition: xmlimprt.hxx:296
virtual ~ScXMLExternalRefRowsContext() override
sal_Int64 n
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
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
const SvXMLTokenMap & GetTableRowCellElemTokenMap()
Definition: xmlimprt.cxx:466
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:1312
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:618
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
const SvXMLTokenMap & GetTableRowElemTokenMap()
Definition: xmlimprt.cxx:429
int i
void convertDateTime(OUStringBuffer &rBuffer, const double &fDateTime, bool const bAddTimeIf0AM=false)
XML_HREF
sal_uInt16 Get(sal_uInt16 nPrefix, const OUString &rLName) const
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:727
const SvXMLTokenMap & GetTableRowsElemTokenMap()
Definition: xmlimprt.cxx:410
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
TABLE
::formula::FormulaTokenRef TokenRef
DefTokenId nToken
Definition: qproform.cxx:400
virtual ~ScXMLExternalRefCellContext() override
const SvXMLTokenMap & GetTableRowCellAttrTokenMap()
Definition: xmlimprt.cxx:173
void SetCellString(const OUString &rStr)
ScXMLExternalRefRowsContext(ScXMLImport &rImport, ScXMLExternalTabData &rRefInfo)
std::shared_ptr< Table > TableTypeRef
XML_FILTER_NAME
#define XML_ELEMENT(prefix, name)
const SvXMLUnitConverter & GetMM100UnitConverter() const
void * p
ScXMLExternalTabData & mrExternalRefInfo
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
const SvXMLTokenMap & GetTableRowAttrTokenMap()
Definition: xmlimprt.cxx:446
XML_TRUE
const SvXMLStyleContext * FindStyleChildContext(XmlStyleFamily nFamily, const OUString &rName, bool bCreateIndex=false) const
ScXMLExternalTabData & mrExternalRefInfo
SvXMLStylesContext * GetAutoStyles()
BaseContainerNodeSharedPtr & mrParent
virtual ~ScXMLExternalRefRowContext() override
ScDocumentImport & GetDoc()
Definition: xmlimprt.cxx:722
ScDocument & getDoc()