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 
43 #include <tools/urlobj.hxx>
44 #include <sax/fastattribs.hxx>
45 #include <com/sun/star/sheet/XSpreadsheet.hpp>
47 
48 using namespace com::sun::star;
49 using namespace xmloff::token;
50 using ::com::sun::star::uno::Reference;
51 using ::com::sun::star::uno::UNO_QUERY;
52 using ::com::sun::star::xml::sax::XAttributeList;
53 
66 static bool lcl_isExternalRefCache(const OUString& rName, OUString& rUrl, OUString& rExtTabName)
67 {
68  // 'file:///path/to/file.ods'#MySheet
69  // 'file:///path/to/file.ods'#MySheet with space
70  // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
71  // That's allowed.)
72 
73  if ( rName.toChar() != '\'' ) // initial quote
74  return false;
75 
76  // #i114504# Other schemes besides "file:" are also allowed.
77  // CompareProtocolScheme is quick, only looks at the start of the string.
78  INetProtocol eProt = INetURLObject::CompareProtocolScheme( rName.copy(1) );
79  if ( eProt == INetProtocol::NotValid )
80  return false;
81 
82  OUString aPrefix = INetURLObject::GetScheme( eProt );
83  sal_Int32 nPrefLen = aPrefix.getLength();
84 
85  OUStringBuffer aUrlBuf, aTabNameBuf;
86  aUrlBuf.append( aPrefix );
87  sal_Int32 n = rName.getLength();
88  const sal_Unicode* p = rName.getStr();
89 
90  bool bInUrl = true;
91  sal_Unicode cPrev = 0;
92  for (sal_Int32 i = nPrefLen+1; i < n; ++i) // start the loop after quote and prefix
93  {
94  const sal_Unicode c = p[i];
95  if (bInUrl)
96  {
97  // parsing file URL
98  if (c == '#')
99  {
100  if (cPrev != '\'')
101  return false;
102 
103  rUrl = aUrlBuf.makeStringAndClear();
104  rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
105  bInUrl = false;
106  }
107  else
108  aUrlBuf.append(c);
109  }
110  else
111  // parsing sheet name.
112  aTabNameBuf.append(c);
113 
114  cPrev = c;
115  }
116 
117  if (bInUrl)
118  return false;
119 
120  if (aTabNameBuf.isEmpty())
121  return false;
122 
123  rExtTabName = aTabNameBuf.makeStringAndClear();
124 
125  return true;
126 }
127 
129  mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
130 {
131 }
132 
135  ScXMLImportContext( rImport ),
136  nStartOffset(-1),
137  bStartFormPage(false),
138  bPrintEntireSheet(true)
139 {
140  // get start offset in file (if available)
142 
143  ScXMLTabProtectionData aProtectData;
144  OUString sName;
145  OUString sStyleName;
146 
147  if ( rAttrList.is() )
148  {
149  for (auto &it : *rAttrList)
150  {
151  switch (it.getToken())
152  {
153  case XML_ELEMENT( TABLE, XML_NAME ):
154  sName = it.toString();
155  break;
157  sStyleName = it.toString();
158  break;
160  aProtectData.mbProtected = IsXMLToken( it, XML_TRUE );
161  break;
163  sPrintRanges = it.toString();
164  break;
166  aProtectData.maPassword = it.toString();
167  break;
169  aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
170  break;
173  aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
174  break;
175  case XML_ELEMENT( TABLE, XML_PRINT ):
176  {
177  if ( IsXMLToken( it, XML_FALSE) )
178  bPrintEntireSheet = false;
179  }
180  break;
181  }
182 
183  }
184  }
185 
186  OUString aExtUrl, aExtTabName;
187  if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName))
188  {
189  // This is an external ref cache table.
191  ScDocument* pDoc = GetScImport().GetDocument();
192  if (pDoc)
193  {
194  ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
195  pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
196  pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true,
197  nullptr, &aExtUrl);
198  pExternalRefInfo->mpCacheTable->setWholeTableCached();
199  }
200  }
201  else
202  {
203  // This is a regular table.
204  GetScImport().GetTables().NewSheet(sName, sStyleName, aProtectData);
205  }
206 }
207 
209 {
210 }
211 
212 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
214  const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
215 {
216  sax_fastparser::FastAttributeList *pAttribList =
218 
219  if (pExternalRefInfo)
220  {
221  // We only care about the table-row and table-source elements for
222  // external cache data.
223  switch ( nElement )
224  {
228  // #i101319# don't discard rows in groups or header (repeat range)
229  return new ScXMLExternalRefRowsContext(
232  return new ScXMLExternalRefRowContext(
233  GetScImport(), pAttribList, *pExternalRefInfo);
236  GetScImport(), pAttribList, *pExternalRefInfo);
237  default:
238  ;
239  }
240  return nullptr;
241  }
242 
243  SvXMLImportContext *pContext(nullptr);
244 
245  switch ( nElement )
246  {
248  {
250  pContext = new ScXMLNamedExpressionsContext(
251  GetScImport(),
252  std::make_shared<ScXMLNamedExpressionsContext::SheetLocalInserter>(GetScImport(), nTab));
253  }
254  break;
256  pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
257  false, true );
258  break;
260  pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
261  true, false );
262  break;
264  pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
265  false, false );
266  break;
268  pContext = new ScXMLTableColContext( GetScImport(), pAttribList );
269  break;
271  case XML_ELEMENT( LO_EXT, XML_TABLE_PROTECTION ):
272  case XML_ELEMENT( OFFICE_EXT, XML_TABLE_PROTECTION ):
273  pContext = new ScXMLTableProtectionContext( GetScImport(), pAttribList );
274  break;
276  pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
277  false, true );
278  break;
280  pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
281  true, false );
282  break;
284  pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
285  false, false );
286  break;
288  pContext = new ScXMLTableRowContext( GetScImport(), pAttribList );
289  break;
291  pContext = new ScXMLTableSourceContext( GetScImport(), pAttribList);
292  break;
293  case XML_ELEMENT( TABLE, XML_SCENARIO ):
294  pContext = new ScXMLTableScenarioContext( GetScImport(), pAttribList);
295  break;
296  case XML_ELEMENT( TABLE, XML_SHAPES ):
297  pContext = new ScXMLTableShapesContext( GetScImport() );
298  break;
299  case XML_ELEMENT( CALC_EXT, XML_CONDITIONAL_FORMATS ):
300  pContext = new ScXMLConditionalFormatsContext( GetScImport() );
301  break;
303  case XML_ELEMENT(OFFICE_EXT, XML_EVENT_LISTENERS):
304  {
305  // use XEventsSupplier interface of the sheet
306  uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
307  pContext = new XMLEventsImportContext( GetImport(), xSupplier );
308  }
309  break;
311  {
312  GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
313  bStartFormPage = true;
315  }
316  break;
317  default:
318  XMLOFF_WARN_UNKNOWN_ELEMENT("sc", nElement);
319  }
320 
321  return pContext;
322 }
323 
324 void SAL_CALL ScXMLTableContext::endFastElement(sal_Int32 /*nElement*/)
325 {
326  ScXMLImport::MutexGuard aMutexGuard(GetScImport());
327  ScXMLImport& rImport = GetScImport();
328  rImport.GetStylesImportHelper()->EndTable();
329  ScDocument* pDoc(rImport.GetDocument());
330  if (!pDoc)
331  return;
332 
333  ScMyTables& rTables = rImport.GetTables();
334  SCTAB nCurTab = rTables.GetCurrentSheet();
335  if (!sPrintRanges.isEmpty())
336  {
337  ScRangeList aRangeList;
339  size_t nCount = aRangeList.size();
340  for (size_t i=0; i< nCount; i++ )
341  {
342  pDoc->AddPrintRange( nCurTab, aRangeList[i] );
343  }
344  }
345  else if (!bPrintEntireSheet)
346  // Sheet has "print entire sheet" option by default. Remove it.
347  pDoc->ClearPrintRanges(nCurTab);
348 
349  ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(nCurTab));
350  if (pOutlineTable)
351  {
352  ScOutlineArray& rColArray(pOutlineTable->GetColArray());
353  size_t nDepth = rColArray.GetDepth();
354  for (size_t i = 0; i < nDepth; ++i)
355  {
356  size_t nCount = rColArray.GetCount(i);
357  for (size_t j = 0; j < nCount; ++j)
358  {
359  const ScOutlineEntry* pEntry = rColArray.GetEntry(i, j);
360  if (pEntry->IsHidden())
361  rColArray.SetVisibleBelow(i, j, false);
362  }
363  }
364  ScOutlineArray& rRowArray(pOutlineTable->GetRowArray());
365  nDepth = rRowArray.GetDepth();
366  for (size_t i = 0; i < nDepth; ++i)
367  {
368  size_t nCount = rRowArray.GetCount(i);
369  for (size_t j = 0; j < nCount; ++j)
370  {
371  const ScOutlineEntry* pEntry = rRowArray.GetEntry(i, j);
372  if (pEntry->IsHidden())
373  rRowArray.SetVisibleBelow(i, j, false);
374  }
375  }
376  }
377  if (rTables.HasDrawPage())
378  {
379  if (rTables.HasXShapes())
380  {
381  rImport.GetShapeImport()->popGroupAndPostProcess();
382  uno::Reference < drawing::XShapes > xTempShapes(rTables.GetCurrentXShapes());
383  rImport.GetShapeImport()->endPage(xTempShapes);
384  }
385  if (bStartFormPage)
386  rImport.GetFormImport()->endPage();
387  }
388 
389  rTables.DeleteTable();
390  rImport.ProgressBarIncrement();
391 
392  // store stream positions
393  if (!pExternalRefInfo && nStartOffset >= 0 /* && nEndOffset >= 0 */)
394  {
395  ScSheetSaveData* pSheetData = comphelper::getUnoTunnelImplementation<ScModelObj>(rImport.GetModel())->GetSheetSaveData();
396  SCTAB nTab = rTables.GetCurrentSheet();
397  // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
398  pSheetData->StartStreamPos( nTab, nStartOffset );
399  }
400 }
401 
403  ScXMLImport& rImport,
405  ScXMLImportContext( rImport )
406 {
407  bool bSelectProtectedCells = false;
408  bool bSelectUnprotectedCells = false;
409  bool bInsertColumns = false;
410  bool bInsertRows = false;
411  bool bDeleteColumns = false;
412  bool bDeleteRows = false;
413 
414  if ( rAttrList.is() )
415  {
416  for (auto &aIter : *rAttrList)
417  {
418  sal_Int32 nToken = aIter.getToken();
419  switch (nToken)
420  {
422  case XML_ELEMENT( OFFICE_EXT, XML_SELECT_PROTECTED_CELLS ):
423  case XML_ELEMENT( LO_EXT, XML_SELECT_PROTECTED_CELLS ):
424  bSelectProtectedCells = IsXMLToken(aIter, XML_TRUE);
425  break;
427  case XML_ELEMENT( OFFICE_EXT, XML_SELECT_UNPROTECTED_CELLS ):
429  bSelectUnprotectedCells = IsXMLToken(aIter, XML_TRUE);
430  break;
431  case XML_ELEMENT( LO_EXT, XML_INSERT_COLUMNS ):
432  bInsertColumns = IsXMLToken(aIter, XML_TRUE);
433  break;
434  case XML_ELEMENT( LO_EXT, XML_INSERT_ROWS ):
435  bInsertRows = IsXMLToken(aIter, XML_TRUE);
436  break;
437  case XML_ELEMENT( LO_EXT, XML_DELETE_COLUMNS ):
438  bDeleteColumns = IsXMLToken(aIter, XML_TRUE);
439  break;
440  case XML_ELEMENT( LO_EXT, XML_DELETE_ROWS ):
441  bDeleteRows = IsXMLToken(aIter, XML_TRUE);
442  break;
443  default:
444  XMLOFF_WARN_UNKNOWN("sc", aIter);
445  }
446  }
447  }
448 
450  rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
451  rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
452  rProtectData.mbInsertColumns = bInsertColumns;
453  rProtectData.mbInsertRows = bInsertRows;
454  rProtectData.mbDeleteColumns = bDeleteColumns;
455  rProtectData.mbDeleteRows = bDeleteRows;
456 }
457 
459 {
460 }
461 
462 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void NewSheet(const OUString &sTableName, const OUString &sStyleName, const ScXMLTabProtectionData &rProtectData)
Definition: xmlsubti.cxx:95
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
SCTAB GetCurrentSheet() const
Definition: xmlsubti.hxx:85
XML_NAME
ScDocument * GetDocument()
Definition: xmlimprt.hxx:206
void StartStreamPos(SCTAB nTab, sal_Int32 nStartOffset)
Definition: sheetdata.cxx:116
XML_EVENT_LISTENERS
ScMyTables & GetTables()
Definition: xmlimprt.hxx:209
SvXMLImport & GetImport()
XML_DELETE_ROWS
bool HasDrawPage() const
Definition: xmlsubti.cxx:243
sal_Int64 n
sal_Int32 mnCol
XML_TABLE_ROW_GROUP
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
sal_uInt16 getExternalFileId(const OUString &rFile)
ScMyStylesImportHelper * GetStylesImportHelper()
Definition: xmlimprt.hxx:256
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:324
size_t GetDepth() const
Definition: olinetab.hxx:111
int nCount
#define XMLOFF_WARN_UNKNOWN(area, rIter)
XML_PROTECTED
XML_INSERT_COLUMNS
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:617
INetProtocol
ScXMLTableContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:133
bool HasXShapes() const
Definition: xmlsubti.cxx:248
XML_FALSE
const char * sName
virtual ~ScXMLTableProtectionContext() override
Definition: xmltabi.cxx:458
XML_FORMS
static SvXMLImportContext * createOfficeFormsContext(SvXMLImport &_rImport)
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
XML_SELECT_PROTECTED_CELLS
XML_CONDITIONAL_FORMATS
static OUString GetScheme(INetProtocol eTheScheme)
Use this class to manage solar mutex locking instead of calling LockSolarMutex() and UnlockSolarMutex...
Definition: xmlimprt.hxx:294
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:208
XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
ScXMLTableProtectionContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:402
void DeleteTable()
Definition: xmlsubti.cxx:184
ScPasswordHash getHashTypeFromURI(std::u16string_view rURI)
TABLE
DefTokenId nToken
Definition: qproform.cxx:399
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:213
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 XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
XML_PRINT_RANGES
sal_Int32 mnRow
sal_Int32 GetByteOffset() const
Definition: xmlimprt.cxx:1549
XML_DELETE_COLUMNS
void ProgressBarIncrement()
Definition: xmlimprt.cxx:1569
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:66