LibreOffice Module sc (master)  1
xmltabi.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 "xmltabi.hxx"
21 #include "xmlimprt.hxx"
22 #include "xmlrowi.hxx"
23 #include "xmlcoli.hxx"
24 #include "xmlsceni.hxx"
25 #include "xmlexternaltabi.hxx"
26 #include "xmlnexpi.hxx"
27 #include <document.hxx>
28 #include <docuno.hxx>
29 #include <olinetab.hxx>
33 #include <rangeutl.hxx>
34 #include <externalrefmgr.hxx>
35 #include <sheetdata.hxx>
36 #include "xmlcondformat.hxx"
37 
38 #include <xmloff/xmltkmap.hxx>
39 #include <xmloff/xmltoken.hxx>
40 #include <xmloff/xmlnamespace.hxx>
42 #include <sal/log.hxx>
43 
44 #include <tools/urlobj.hxx>
45 #include <sax/fastattribs.hxx>
46 #include <com/sun/star/sheet/XSpreadsheet.hpp>
48 
49 using namespace com::sun::star;
50 using namespace xmloff::token;
51 using ::com::sun::star::uno::Reference;
52 using ::com::sun::star::uno::UNO_QUERY;
53 using ::com::sun::star::xml::sax::XAttributeList;
54 
67 static bool lcl_isExternalRefCache(const OUString& rName, OUString& rUrl, OUString& rExtTabName)
68 {
69  // 'file:///path/to/file.ods'#MySheet
70  // 'file:///path/to/file.ods'#MySheet with space
71  // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
72  // That's allowed.)
73 
74  if ( rName.toChar() != '\'' ) // initial quote
75  return false;
76 
77  // #i114504# Other schemes besides "file:" are also allowed.
78  // CompareProtocolScheme is quick, only looks at the start of the string.
79  INetProtocol eProt = INetURLObject::CompareProtocolScheme( rName.copy(1) );
80  if ( eProt == INetProtocol::NotValid )
81  return false;
82 
83  OUString aPrefix = INetURLObject::GetScheme( eProt );
84  sal_Int32 nPrefLen = aPrefix.getLength();
85 
86  OUStringBuffer aUrlBuf, aTabNameBuf;
87  aUrlBuf.append( aPrefix );
88  sal_Int32 n = rName.getLength();
89  const sal_Unicode* p = rName.getStr();
90 
91  bool bInUrl = true;
92  sal_Unicode cPrev = 0;
93  for (sal_Int32 i = nPrefLen+1; i < n; ++i) // start the loop after quote and prefix
94  {
95  const sal_Unicode c = p[i];
96  if (bInUrl)
97  {
98  // parsing file URL
99  if (c == '#')
100  {
101  if (cPrev != '\'')
102  return false;
103 
104  rUrl = aUrlBuf.makeStringAndClear();
105  rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
106  bInUrl = false;
107  }
108  else
109  aUrlBuf.append(c);
110  }
111  else
112  // parsing sheet name.
113  aTabNameBuf.append(c);
114 
115  cPrev = c;
116  }
117 
118  if (bInUrl)
119  return false;
120 
121  if (aTabNameBuf.isEmpty())
122  return false;
123 
124  rExtTabName = aTabNameBuf.makeStringAndClear();
125 
126  return true;
127 }
128 
130  mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
131 {
132 }
133 
136  ScXMLImportContext( rImport ),
137  nStartOffset(-1),
138  bStartFormPage(false),
139  bPrintEntireSheet(true)
140 {
141  // get start offset in file (if available)
143 
144  ScXMLTabProtectionData aProtectData;
145  OUString sName;
146  OUString sStyleName;
147 
148  if ( rAttrList.is() )
149  {
150  for (auto &it : *rAttrList)
151  {
152  switch (it.getToken())
153  {
154  case XML_ELEMENT( TABLE, XML_NAME ):
155  sName = it.toString();
156  break;
158  sStyleName = it.toString();
159  break;
161  aProtectData.mbProtected = IsXMLToken( it, XML_TRUE );
162  break;
164  sPrintRanges = it.toString();
165  break;
167  aProtectData.maPassword = it.toString();
168  break;
170  aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
171  break;
174  aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
175  break;
176  case XML_ELEMENT( TABLE, XML_PRINT ):
177  {
178  if ( IsXMLToken( it, XML_FALSE) )
179  bPrintEntireSheet = false;
180  }
181  break;
182  }
183 
184  }
185  }
186 
187  OUString aExtUrl, aExtTabName;
188  if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName))
189  {
190  // This is an external ref cache table.
192  ScDocument* pDoc = GetScImport().GetDocument();
193  if (pDoc)
194  {
195  ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
196  pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
197  pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true,
198  nullptr, &aExtUrl);
199  pExternalRefInfo->mpCacheTable->setWholeTableCached();
200  }
201  }
202  else
203  {
204  // This is a regular table.
205  GetScImport().GetTables().NewSheet(sName, sStyleName, aProtectData);
206  }
207 }
208 
210 {
211 }
212 
214  const OUString& rLName,
215  const css::uno::Reference<css::xml::sax::XAttributeList>& /*xAttrList*/ )
216 {
217  const SvXMLTokenMap& rTokenMap(GetScImport().GetTableElemTokenMap());
218  sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLName);
219  if (pExternalRefInfo)
220  {
221  return new SvXMLImportContext(GetImport(), nPrefix, rLName);
222  }
223 
224  SvXMLImportContext *pContext(nullptr);
225 
226  switch (nToken)
227  {
228  case XML_TOK_TABLE_FORMS:
229  {
230  GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
231  bStartFormPage = true;
233  }
234  break;
235  default:
236  ;
237  }
238 
239  return pContext;
240 }
241 
242 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
244  const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
245 {
246  sax_fastparser::FastAttributeList *pAttribList =
248 
249  if (pExternalRefInfo)
250  {
251  // We only care about the table-row and table-source elements for
252  // external cache data.
253  switch ( nElement )
254  {
258  // #i101319# don't discard rows in groups or header (repeat range)
259  return new ScXMLExternalRefRowsContext(
262  return new ScXMLExternalRefRowContext(
263  GetScImport(), pAttribList, *pExternalRefInfo);
266  GetScImport(), pAttribList, *pExternalRefInfo);
267  default:
268  ;
269  }
270  return nullptr;
271  }
272 
273  SvXMLImportContext *pContext(nullptr);
274 
275  switch ( nElement )
276  {
278  {
280  pContext = new ScXMLNamedExpressionsContext(
281  GetScImport(),
282  std::make_shared<ScXMLNamedExpressionsContext::SheetLocalInserter>(GetScImport(), nTab));
283  }
284  break;
286  pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
287  false, true );
288  break;
290  pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
291  true, false );
292  break;
294  pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
295  false, false );
296  break;
298  pContext = new ScXMLTableColContext( GetScImport(), pAttribList );
299  break;
301  case XML_ELEMENT( LO_EXT, XML_TABLE_PROTECTION ):
302  case XML_ELEMENT( OFFICE_EXT, XML_TABLE_PROTECTION ):
303  pContext = new ScXMLTableProtectionContext( GetScImport(), pAttribList );
304  break;
306  pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
307  false, true );
308  break;
310  pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
311  true, false );
312  break;
314  pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
315  false, false );
316  break;
318  pContext = new ScXMLTableRowContext( GetScImport(), pAttribList );
319  break;
321  pContext = new ScXMLTableSourceContext( GetScImport(), pAttribList);
322  break;
323  case XML_ELEMENT( TABLE, XML_SCENARIO ):
324  pContext = new ScXMLTableScenarioContext( GetScImport(), pAttribList);
325  break;
326  case XML_ELEMENT( TABLE, XML_SHAPES ):
327  pContext = new ScXMLTableShapesContext( GetScImport() );
328  break;
329  case XML_ELEMENT( CALC_EXT, XML_CONDITIONAL_FORMATS ):
330  pContext = new ScXMLConditionalFormatsContext( GetScImport() );
331  break;
333  case XML_ELEMENT(OFFICE_EXT, XML_EVENT_LISTENERS):
334  {
335  // use XEventsSupplier interface of the sheet
336  uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
337  pContext = new XMLEventsImportContext( GetImport(), xSupplier );
338  }
339  break;
340  }
341 
342  return pContext;
343 }
344 
345 void SAL_CALL ScXMLTableContext::endFastElement(sal_Int32 /*nElement*/)
346 {
347  ScXMLImport::MutexGuard aMutexGuard(GetScImport());
348  ScXMLImport& rImport = GetScImport();
349  rImport.GetStylesImportHelper()->EndTable();
350  ScDocument* pDoc(rImport.GetDocument());
351  if (!pDoc)
352  return;
353 
354  ScMyTables& rTables = rImport.GetTables();
355  SCTAB nCurTab = rTables.GetCurrentSheet();
356  if (!sPrintRanges.isEmpty())
357  {
358  ScRangeList aRangeList;
360  size_t nCount = aRangeList.size();
361  for (size_t i=0; i< nCount; i++ )
362  {
363  pDoc->AddPrintRange( nCurTab, aRangeList[i] );
364  }
365  }
366  else if (!bPrintEntireSheet)
367  // Sheet has "print entire sheet" option by default. Remove it.
368  pDoc->ClearPrintRanges(nCurTab);
369 
370  ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(nCurTab));
371  if (pOutlineTable)
372  {
373  ScOutlineArray& rColArray(pOutlineTable->GetColArray());
374  size_t nDepth = rColArray.GetDepth();
375  for (size_t i = 0; i < nDepth; ++i)
376  {
377  size_t nCount = rColArray.GetCount(i);
378  for (size_t j = 0; j < nCount; ++j)
379  {
380  const ScOutlineEntry* pEntry = rColArray.GetEntry(i, j);
381  if (pEntry->IsHidden())
382  rColArray.SetVisibleBelow(i, j, false);
383  }
384  }
385  ScOutlineArray& rRowArray(pOutlineTable->GetRowArray());
386  nDepth = rRowArray.GetDepth();
387  for (size_t i = 0; i < nDepth; ++i)
388  {
389  size_t nCount = rRowArray.GetCount(i);
390  for (size_t j = 0; j < nCount; ++j)
391  {
392  const ScOutlineEntry* pEntry = rRowArray.GetEntry(i, j);
393  if (pEntry->IsHidden())
394  rRowArray.SetVisibleBelow(i, j, false);
395  }
396  }
397  }
398  if (rTables.HasDrawPage())
399  {
400  if (rTables.HasXShapes())
401  {
402  rImport.GetShapeImport()->popGroupAndPostProcess();
403  uno::Reference < drawing::XShapes > xTempShapes(rTables.GetCurrentXShapes());
404  rImport.GetShapeImport()->endPage(xTempShapes);
405  }
406  if (bStartFormPage)
407  rImport.GetFormImport()->endPage();
408  }
409 
410  rTables.DeleteTable();
411  rImport.ProgressBarIncrement();
412 
413  // store stream positions
414  if (!pExternalRefInfo && nStartOffset >= 0 /* && nEndOffset >= 0 */)
415  {
416  ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(rImport.GetModel())->GetSheetSaveData();
417  SCTAB nTab = rTables.GetCurrentSheet();
418  // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
419  pSheetData->StartStreamPos( nTab, nStartOffset );
420  }
421 }
422 
424  ScXMLImport& rImport,
426  ScXMLImportContext( rImport )
427 {
428  bool bSelectProtectedCells = false;
429  bool bSelectUnprotectedCells = false;
430  bool bInsertColumns = false;
431  bool bInsertRows = false;
432  bool bDeleteColumns = false;
433  bool bDeleteRows = false;
434 
435  if ( rAttrList.is() )
436  {
437  for (auto &aIter : *rAttrList)
438  {
439  sal_Int32 nToken = aIter.getToken();
440  switch (nToken)
441  {
443  case XML_ELEMENT( OFFICE_EXT, XML_SELECT_PROTECTED_CELLS ):
444  case XML_ELEMENT( LO_EXT, XML_SELECT_PROTECTED_CELLS ):
445  bSelectProtectedCells = IsXMLToken(aIter, XML_TRUE);
446  break;
448  case XML_ELEMENT( OFFICE_EXT, XML_SELECT_UNPROTECTED_CELLS ):
450  bSelectUnprotectedCells = IsXMLToken(aIter, XML_TRUE);
451  break;
452  case XML_ELEMENT( LO_EXT, XML_INSERT_COLUMNS ):
453  bInsertColumns = IsXMLToken(aIter, XML_TRUE);
454  break;
455  case XML_ELEMENT( LO_EXT, XML_INSERT_ROWS ):
456  bInsertRows = IsXMLToken(aIter, XML_TRUE);
457  break;
458  case XML_ELEMENT( LO_EXT, XML_DELETE_COLUMNS ):
459  bDeleteColumns = IsXMLToken(aIter, XML_TRUE);
460  break;
461  case XML_ELEMENT( LO_EXT, XML_DELETE_ROWS ):
462  bDeleteRows = IsXMLToken(aIter, XML_TRUE);
463  break;
464  default:
465  SAL_WARN("sc", "unknown attribute " << SvXMLImport::getPrefixAndNameFromToken(nToken) << "=" << aIter.toString());
466  }
467  }
468  }
469 
471  rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
472  rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
473  rProtectData.mbInsertColumns = bInsertColumns;
474  rProtectData.mbInsertRows = bInsertRows;
475  rProtectData.mbDeleteColumns = bDeleteColumns;
476  rProtectData.mbDeleteRows = bDeleteRows;
477 }
478 
480 {
481 }
482 
483 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLTableProtectionContext::createFastChildContext(
484  sal_Int32 /*nElement*/, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
485 {
486  return nullptr;
487 }
488 
489 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void NewSheet(const OUString &sTableName, const OUString &sStyleName, const ScXMLTabProtectionData &rProtectData)
Definition: xmlsubti.cxx:95
bool IsXMLToken(const OUString &rString, enum XMLTokenEnum eToken)
XML_TABLE_COLUMN_GROUP
::std::unique_ptr< ScXMLExternalTabData > pExternalRefInfo
Definition: xmltabi.hxx:44
XML_STYLE_NAME
rtl::Reference< ::xmloff::OFormLayerXMLImport > const & GetFormImport()
bool bPrintEntireSheet
Definition: xmltabi.hxx:47
SC_DLLPUBLIC bool IsHidden() const
Definition: olinetab.hxx:50
XML_SELECT_UNPROTECTED_CELLS
sal_Int32 nStartOffset
Definition: xmltabi.hxx:45
static SvXMLImportContext * createOfficeFormsContext(SvXMLImport &_rImport, sal_uInt16 _nPrefix, const OUString &_rLocalName)
SCTAB GetCurrentSheet() const
Definition: xmlsubti.hxx:85
XML_NAME
ScDocument * GetDocument()
Definition: xmlimprt.hxx:296
void StartStreamPos(SCTAB nTab, sal_Int32 nStartOffset)
Definition: sheetdata.cxx:116
XML_EVENT_LISTENERS
ScMyTables & GetTables()
Definition: xmlimprt.hxx:299
SvXMLImport & GetImport()
XML_DELETE_ROWS
bool HasDrawPage() const
Definition: xmlsubti.cxx:243
sal_Int64 n
sal_Int32 mnCol
XML_TABLE_ROW_GROUP
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
sal_uInt16 getExternalFileId(const OUString &rFile)
ScMyStylesImportHelper * GetStylesImportHelper()
Definition: xmlimprt.hxx:354
ScPasswordHash meHash1
Definition: xmlsubti.hxx:37
XML_INSERT_ROWS
sal_uInt16 sal_Unicode
XML_PROTECTION_KEY
XML_TABLE_HEADER_COLUMNS
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
Definition: xmltabi.cxx:345
size_t GetDepth() const
Definition: olinetab.hxx:111
int nCount
XML_PROTECTED
XML_INSERT_COLUMNS
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:618
static OUString getPrefixAndNameFromToken(sal_Int32 nToken)
INetProtocol
ScXMLTableContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:134
bool HasXShapes() const
Definition: xmlsubti.cxx:248
ScPasswordHash getHashTypeFromURI(const OUString &rURI)
XML_FALSE
const char * sName
virtual ~ScXMLTableProtectionContext() override
Definition: xmltabi.cxx:479
This class exists only to provide GetScImport() to its derived classes.
XML_TABLE_ROW
int i
XML_TABLE_SOURCE
XML_PRINT
XML_SHAPES
size_t size() const
Definition: rangelst.hxx:90
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
Definition: xmltabi.cxx:483
XML_SELECT_PROTECTED_CELLS
XML_CONDITIONAL_FORMATS
static OUString GetScheme(INetProtocol eTheScheme)
sal_uInt16 Get(sal_uInt16 nPrefix, const OUString &rLName) const
Use this class to manage solar mutex locking instead of calling LockSolarMutex() and UnlockSolarMutex...
Definition: xmlimprt.hxx:392
ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
Get a cache table instance for specified table and table index.
ScXMLImport & GetScImport()
virtual ~ScXMLTableContext() override
Definition: xmltabi.cxx:209
SvXMLImportContext(SvXMLImport &rImport, sal_uInt16 nPrfx, const OUString &rLName)
XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
ScXMLTableProtectionContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:423
void DeleteTable()
Definition: xmlsubti.cxx:184
virtual SvXMLImportContextRef CreateChildContext(sal_uInt16 nPrefix, const OUString &rLocalName, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList) override
Definition: xmltabi.cxx:213
TABLE
DefTokenId nToken
Definition: qproform.cxx:400
virtual css::uno::Reference< css::xml::sax::XFastContextHandler > SAL_CALL createFastChildContext(sal_Int32 nElement, const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList) override
Definition: xmltabi.cxx:243
XML_TABLE_COLUMNS
css::uno::Reference< css::drawing::XShapes > const & GetCurrentXShapes()
Definition: xmlsubti.cxx:231
#define XML_ELEMENT(prefix, name)
OUString sPrintRanges
Definition: xmltabi.hxx:43
const css::uno::Reference< css::frame::XModel > & GetModel() const
void * p
XML_NAMED_EXPRESSIONS
XML_TABLE_COLUMN
ScXMLTabProtectionData & GetCurrentProtectionData()
Definition: xmlsubti.hxx:83
XML_TABLE_PROTECTION
static bool GetRangeListFromString(ScRangeList &rRangeList, const OUString &rRangeListStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator= ' ', sal_Unicode cQuote= '\'')
Definition: rangeutl.cxx:526
XML_TRUE
XML_SCENARIO
XML_PROTECTION_KEY_DIGEST_ALGORITHM
#define SAL_WARN(area, stream)
XML_PRINT_RANGES
sal_Int32 mnRow
sal_Int32 GetByteOffset() const
Definition: xmlimprt.cxx:1728
XML_DELETE_COLUMNS
void ProgressBarIncrement()
Definition: xmlimprt.cxx:1748
XML_TABLE_HEADER_ROWS
XML_TABLE_ROWS
ScPasswordHash meHash2
Definition: xmlsubti.hxx:38
sal_Int16 SCTAB
Definition: types.hxx:23
static INetProtocol CompareProtocolScheme(OUString const &rTheAbsURIRef)
rtl::Reference< XMLShapeImportHelper > const & GetShapeImport()
static bool lcl_isExternalRefCache(const OUString &rName, OUString &rUrl, OUString &rExtTabName)
Determine whether this table is an external reference cache from its name.
Definition: xmltabi.cxx:67