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"
38
39#include <xmloff/xmltoken.hxx>
42
43#include <tools/urlobj.hxx>
44#include <sax/fastattribs.hxx>
45#include <com/sun/star/sheet/XSpreadsheet.hpp>
47
48using namespace com::sun::star;
49using namespace xmloff::token;
50using ::com::sun::star::uno::Reference;
51using ::com::sun::star::uno::UNO_QUERY;
52using ::com::sun::star::xml::sax::XAttributeList;
53
66static 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.subView(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 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.
192 if (pDoc)
193 {
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
212uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
214 const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
215{
218
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)
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;
294 pContext = new ScXMLTableScenarioContext( GetScImport(), pAttribList);
295 break;
297 pContext = new ScXMLTableShapesContext( GetScImport() );
298 break;
299 case XML_ELEMENT( CALC_EXT, XML_CONDITIONAL_FORMATS ):
301 break;
302 case XML_ELEMENT(CALC_EXT, XML_SPARKLINE_GROUPS):
304 break;
306 case XML_ELEMENT(OFFICE_EXT, XML_EVENT_LISTENERS):
307 {
308 // use XEventsSupplier interface of the sheet
309 uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
310 pContext = new XMLEventsImportContext( GetImport(), xSupplier );
311 }
312 break;
314 {
315 GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
316 bStartFormPage = true;
318 }
319 break;
320 default:
321 XMLOFF_WARN_UNKNOWN_ELEMENT("sc", nElement);
322 break;
323 }
324
325 return pContext;
326}
327
328void SAL_CALL ScXMLTableContext::endFastElement(sal_Int32 /*nElement*/)
329{
331 ScXMLImport& rImport = GetScImport();
332 rImport.GetStylesImportHelper()->EndTable();
333 ScDocument* pDoc(rImport.GetDocument());
334 if (!pDoc)
335 return;
336
337 ScMyTables& rTables = rImport.GetTables();
338 SCTAB nCurTab = rTables.GetCurrentSheet();
339 // tdf#51022 process only print ranges of internal sheets
340 if (!pExternalRefInfo)
341 {
342 if (!sPrintRanges.isEmpty())
343 {
344 ScRangeList aRangeList;
346 size_t nCount = aRangeList.size();
347 for (size_t i = 0; i < nCount; i++)
348 {
349 pDoc->AddPrintRange(nCurTab, aRangeList[i]);
350 }
351 }
352 else if (!bPrintEntireSheet)
353 // Sheet has "print entire sheet" option by default. Remove it.
354 pDoc->ClearPrintRanges(nCurTab);
355 }
356
357 ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(nCurTab));
358 if (pOutlineTable)
359 {
360 ScOutlineArray& rColArray(pOutlineTable->GetColArray());
361 size_t nDepth = rColArray.GetDepth();
362 for (size_t i = 0; i < nDepth; ++i)
363 {
364 size_t nCount = rColArray.GetCount(i);
365 for (size_t j = 0; j < nCount; ++j)
366 {
367 const ScOutlineEntry* pEntry = rColArray.GetEntry(i, j);
368 if (pEntry->IsHidden())
369 rColArray.SetVisibleBelow(i, j, false);
370 }
371 }
372 ScOutlineArray& rRowArray(pOutlineTable->GetRowArray());
373 nDepth = rRowArray.GetDepth();
374 for (size_t i = 0; i < nDepth; ++i)
375 {
376 size_t nCount = rRowArray.GetCount(i);
377 for (size_t j = 0; j < nCount; ++j)
378 {
379 const ScOutlineEntry* pEntry = rRowArray.GetEntry(i, j);
380 if (pEntry->IsHidden())
381 rRowArray.SetVisibleBelow(i, j, false);
382 }
383 }
384 }
385 if (rTables.HasDrawPage())
386 {
387 if (rTables.HasXShapes())
388 {
389 rImport.GetShapeImport()->popGroupAndPostProcess();
390 uno::Reference < drawing::XShapes > xTempShapes(rTables.GetCurrentXShapes());
391 rImport.GetShapeImport()->endPage(xTempShapes);
392 }
393 if (bStartFormPage)
394 rImport.GetFormImport()->endPage();
395 }
396
397 rTables.DeleteTable();
398 rImport.ProgressBarIncrement();
399
400 // store stream positions
401 if (!pExternalRefInfo && nStartOffset >= 0 /* && nEndOffset >= 0 */)
402 {
403 ScSheetSaveData* pSheetData = comphelper::getFromUnoTunnel<ScModelObj>(rImport.GetModel())->GetSheetSaveData();
404 SCTAB nTab = rTables.GetCurrentSheet();
405 // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
406 pSheetData->StartStreamPos( nTab, nStartOffset );
407 }
408}
409
411 ScXMLImport& rImport,
413 ScXMLImportContext( rImport )
414{
415 bool bSelectProtectedCells = false;
416 bool bSelectUnprotectedCells = false;
417 bool bInsertColumns = false;
418 bool bInsertRows = false;
419 bool bDeleteColumns = false;
420 bool bDeleteRows = false;
421
422 if ( rAttrList.is() )
423 {
424 for (auto &aIter : *rAttrList)
425 {
426 sal_Int32 nToken = aIter.getToken();
427 switch (nToken)
428 {
430 case XML_ELEMENT( OFFICE_EXT, XML_SELECT_PROTECTED_CELLS ):
432 bSelectProtectedCells = IsXMLToken(aIter, XML_TRUE);
433 break;
435 case XML_ELEMENT( OFFICE_EXT, XML_SELECT_UNPROTECTED_CELLS ):
437 bSelectUnprotectedCells = IsXMLToken(aIter, XML_TRUE);
438 break;
439 case XML_ELEMENT( LO_EXT, XML_INSERT_COLUMNS ):
440 bInsertColumns = IsXMLToken(aIter, XML_TRUE);
441 break;
442 case XML_ELEMENT( LO_EXT, XML_INSERT_ROWS ):
443 bInsertRows = IsXMLToken(aIter, XML_TRUE);
444 break;
445 case XML_ELEMENT( LO_EXT, XML_DELETE_COLUMNS ):
446 bDeleteColumns = IsXMLToken(aIter, XML_TRUE);
447 break;
448 case XML_ELEMENT( LO_EXT, XML_DELETE_ROWS ):
449 bDeleteRows = IsXMLToken(aIter, XML_TRUE);
450 break;
451 default:
452 XMLOFF_WARN_UNKNOWN("sc", aIter);
453 }
454 }
455 }
456
458 rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
459 rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
460 rProtectData.mbInsertColumns = bInsertColumns;
461 rProtectData.mbInsertRows = bInsertRows;
462 rProtectData.mbDeleteColumns = bDeleteColumns;
463 rProtectData.mbDeleteRows = bDeleteRows;
464}
465
467{
468}
469
470/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static OUString GetScheme(INetProtocol eTheScheme)
static INetProtocol CompareProtocolScheme(std::u16string_view aTheAbsURIRef)
SC_DLLPUBLIC void AddPrintRange(SCTAB nTab, const ScRange &rNew)
Adds a new print ranges.
Definition: document.cxx:6424
SC_DLLPUBLIC void ClearPrintRanges(SCTAB nTab)
Removes all print ranges.
Definition: document.cxx:6418
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:633
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:745
sal_uInt16 getExternalFileId(const OUString &rFile)
ScExternalRefCache::TableTypeRef getCacheTable(sal_uInt16 nFileId, size_t nTabIndex) const
Get a cache table instance for specified table and table index.
SCTAB GetCurrentSheet() const
Definition: xmlsubti.hxx:84
css::uno::Reference< css::drawing::XShapes > const & GetCurrentXShapes()
Definition: xmlsubti.cxx:230
void NewSheet(const OUString &sTableName, const OUString &sStyleName, const ScXMLTabProtectionData &rProtectData)
Definition: xmlsubti.cxx:93
ScXMLTabProtectionData & GetCurrentProtectionData()
Definition: xmlsubti.hxx:82
void DeleteTable()
Definition: xmlsubti.cxx:182
bool HasDrawPage() const
Definition: xmlsubti.cxx:242
bool HasXShapes() const
Definition: xmlsubti.cxx:247
size_t GetCount(size_t nLevel) const
Definition: olinetab.cxx:456
ScOutlineEntry * GetEntry(size_t nLevel, size_t nIndex)
Definition: olinetab.cxx:428
size_t GetDepth() const
Definition: olinetab.hxx:110
void SetVisibleBelow(size_t nLevel, size_t nEntry, bool bValue, bool bSkipHidden=false)
Definition: olinetab.cxx:522
SC_DLLPUBLIC bool IsHidden() const
Definition: olinetab.hxx:49
const ScOutlineArray & GetColArray() const
Definition: olinetab.hxx:158
const ScOutlineArray & GetRowArray() const
Definition: olinetab.hxx:160
size_t size() const
Definition: rangelst.hxx:89
static bool GetRangeListFromString(ScRangeList &rRangeList, const OUString &rRangeListStr, const ScDocument &rDocument, formula::FormulaGrammar::AddressConvention eConv, sal_Unicode cSeparator=' ', sal_Unicode cQuote='\'')
Definition: rangeutl.cxx:552
void StartStreamPos(SCTAB nTab, sal_Int32 nStartOffset)
Definition: sheetdata.cxx:116
This class exists only to provide GetScImport() to its derived classes.
ScXMLImport & GetScImport()
Use this class to manage solar mutex locking instead of calling LockSolarMutex() and UnlockSolarMutex...
Definition: xmlimprt.hxx:289
void ProgressBarIncrement()
Definition: xmlimprt.cxx:1571
ScMyStylesImportHelper * GetStylesImportHelper()
Definition: xmlimprt.hxx:250
ScDocument * GetDocument()
Definition: xmlimprt.hxx:205
ScMyTables & GetTables()
Definition: xmlimprt.hxx:208
sal_Int32 GetByteOffset() const
Definition: xmlimprt.cxx:1551
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
virtual ~ScXMLTableContext() override
Definition: xmltabi.cxx:208
ScXMLTableContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:133
bool bPrintEntireSheet
Definition: xmltabi.hxx:45
sal_Int32 nStartOffset
Definition: xmltabi.hxx:43
::std::unique_ptr< ScXMLExternalTabData > pExternalRefInfo
Definition: xmltabi.hxx:42
OUString sPrintRanges
Definition: xmltabi.hxx:41
virtual void SAL_CALL endFastElement(sal_Int32 nElement) override
Definition: xmltabi.cxx:328
virtual ~ScXMLTableProtectionContext() override
Definition: xmltabi.cxx:466
ScXMLTableProtectionContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:410
SvXMLImport & GetImport()
rtl::Reference< ::xmloff::OFormLayerXMLImport > const & GetFormImport()
rtl::Reference< XMLShapeImportHelper > const & GetShapeImport()
const css::uno::Reference< css::frame::XModel > & GetModel() const
Handle the import of sparkline groups and sparklines.
static SvXMLImportContext * createOfficeFormsContext(SvXMLImport &_rImport)
int nCount
sal_Int32 mnRow
sal_Int32 mnCol
void * p
sal_Int64 n
const char * sName
ScPasswordHash getHashTypeFromURI(std::u16string_view rURI)
TABLE
int i
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
XML_TABLE_ROW
XML_TABLE_COLUMN_GROUP
XML_TABLE_COLUMNS
XML_SELECT_UNPROTECTED_CELLS
XML_NAMED_EXPRESSIONS
XML_EVENT_LISTENERS
XML_TRUE
XML_TABLE_PROTECTION
XML_TABLE_COLUMN
XML_DELETE_COLUMNS
XML_INSERT_COLUMNS
XML_TABLE_ROW_GROUP
XML_PROTECTION_KEY_DIGEST_ALGORITHM
XML_TABLE_HEADER_COLUMNS
XML_SCENARIO
XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
XML_PRINT_RANGES
XML_FALSE
XML_STYLE_NAME
XML_NAME
XML_DELETE_ROWS
XML_TABLE_HEADER_ROWS
XML_TABLE_ROWS
XML_PROTECTION_KEY
XML_PRINT
XML_TABLE_SOURCE
XML_SHAPES
XML_PROTECTED
XML_CONDITIONAL_FORMATS
XML_INSERT_ROWS
XML_FORMS
XML_SELECT_PROTECTED_CELLS
XML_SPARKLINE_GROUPS
bool IsXMLToken(std::u16string_view rString, enum XMLTokenEnum eToken)
DefTokenId nToken
Definition: qproform.cxx:397
ScPasswordHash meHash1
Definition: xmlsubti.hxx:36
ScPasswordHash meHash2
Definition: xmlsubti.hxx:37
sal_uInt16 sal_Unicode
sal_Int16 SCTAB
Definition: types.hxx:22
INetProtocol
#define XMLOFF_WARN_UNKNOWN_ELEMENT(area, token)
#define XMLOFF_WARN_UNKNOWN(area, rIter)
#define XML_ELEMENT(prefix, name)
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