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;
52
65static bool lcl_isExternalRefCache(const OUString& rName, OUString& rUrl, OUString& rExtTabName)
66{
67 // 'file:///path/to/file.ods'#MySheet
68 // 'file:///path/to/file.ods'#MySheet with space
69 // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
70 // That's allowed.)
71
72 if ( rName.toChar() != '\'' ) // initial quote
73 return false;
74
75 // #i114504# Other schemes besides "file:" are also allowed.
76 // CompareProtocolScheme is quick, only looks at the start of the string.
77 INetProtocol eProt = INetURLObject::CompareProtocolScheme( rName.subView(1) );
78 if ( eProt == INetProtocol::NotValid )
79 return false;
80
81 OUString aPrefix = INetURLObject::GetScheme( eProt );
82 sal_Int32 nPrefLen = aPrefix.getLength();
83
84 OUStringBuffer aUrlBuf, aTabNameBuf;
85 aUrlBuf.append( aPrefix );
86 sal_Int32 n = rName.getLength();
87 const sal_Unicode* p = rName.getStr();
88
89 bool bInUrl = true;
90 sal_Unicode cPrev = 0;
91 for (sal_Int32 i = nPrefLen+1; i < n; ++i) // start the loop after quote and prefix
92 {
93 const sal_Unicode c = p[i];
94 if (bInUrl)
95 {
96 // parsing file URL
97 if (c == '#')
98 {
99 if (cPrev != '\'')
100 return false;
101
102 rUrl = aUrlBuf.makeStringAndClear();
103 rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
104 bInUrl = false;
105 }
106 else
107 aUrlBuf.append(c);
108 }
109 else
110 // parsing sheet name.
111 aTabNameBuf.append(c);
112
113 cPrev = c;
114 }
115
116 if (bInUrl)
117 return false;
118
119 if (aTabNameBuf.isEmpty())
120 return false;
121
122 rExtTabName = aTabNameBuf.makeStringAndClear();
123
124 return true;
125}
126
128 mnRow(0), mnCol(0), mnFileId(0)
129{
130}
131
134 ScXMLImportContext( rImport ),
135 nStartOffset(-1),
136 bStartFormPage(false),
137 bPrintEntireSheet(true)
138{
139 // get start offset in file (if available)
141
142 ScXMLTabProtectionData aProtectData;
143 OUString sName;
144 OUString sStyleName;
145
146 if ( rAttrList.is() )
147 {
148 for (auto &it : *rAttrList)
149 {
150 switch (it.getToken())
151 {
152 case XML_ELEMENT( TABLE, XML_NAME ):
153 sName = it.toString();
154 break;
156 sStyleName = it.toString();
157 break;
159 aProtectData.mbProtected = IsXMLToken( it, XML_TRUE );
160 break;
162 sPrintRanges = it.toString();
163 break;
165 aProtectData.maPassword = it.toString();
166 break;
168 aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
169 break;
172 aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
173 break;
174 case XML_ELEMENT( TABLE, XML_PRINT ):
175 {
176 if ( IsXMLToken( it, XML_FALSE) )
177 bPrintEntireSheet = false;
178 }
179 break;
180 }
181
182 }
183 }
184
185 OUString aExtUrl, aExtTabName;
186 if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName))
187 {
188 // This is an external ref cache table.
191 if (pDoc)
192 {
194 pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
195 pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true,
196 nullptr, &aExtUrl);
197 pExternalRefInfo->mpCacheTable->setWholeTableCached();
198 }
199 }
200 else
201 {
202 // This is a regular table.
203 GetScImport().GetTables().NewSheet(sName, sStyleName, aProtectData);
204 }
205}
206
208{
209}
210
211uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
213 const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
214{
217
219 {
220 // We only care about the table-row and table-source elements for
221 // external cache data.
222 switch ( nElement )
223 {
227 // #i101319# don't discard rows in groups or header (repeat range)
232 GetScImport(), pAttribList, *pExternalRefInfo);
235 GetScImport(), pAttribList, *pExternalRefInfo);
236 default:
237 ;
238 }
239 return nullptr;
240 }
241
242 SvXMLImportContext *pContext(nullptr);
243
244 switch ( nElement )
245 {
247 {
249 pContext = new ScXMLNamedExpressionsContext(
250 GetScImport(),
251 std::make_shared<ScXMLNamedExpressionsContext::SheetLocalInserter>(GetScImport(), nTab));
252 }
253 break;
255 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
256 false, true );
257 break;
259 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
260 true, false );
261 break;
263 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
264 false, false );
265 break;
267 pContext = new ScXMLTableColContext( GetScImport(), pAttribList );
268 break;
270 case XML_ELEMENT( LO_EXT, XML_TABLE_PROTECTION ):
271 case XML_ELEMENT( OFFICE_EXT, XML_TABLE_PROTECTION ):
272 pContext = new ScXMLTableProtectionContext( GetScImport(), pAttribList );
273 break;
275 pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
276 false, true );
277 break;
279 pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
280 true, false );
281 break;
283 pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
284 false, false );
285 break;
287 pContext = new ScXMLTableRowContext( GetScImport(), pAttribList );
288 break;
290 pContext = new ScXMLTableSourceContext( GetScImport(), pAttribList);
291 break;
293 pContext = new ScXMLTableScenarioContext( GetScImport(), pAttribList);
294 break;
296 pContext = new ScXMLTableShapesContext( GetScImport() );
297 break;
298 case XML_ELEMENT( CALC_EXT, XML_CONDITIONAL_FORMATS ):
300 break;
301 case XML_ELEMENT(CALC_EXT, XML_SPARKLINE_GROUPS):
303 break;
305 case XML_ELEMENT(OFFICE_EXT, XML_EVENT_LISTENERS):
306 {
307 // use XEventsSupplier interface of the sheet
308 uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
309 pContext = new XMLEventsImportContext( GetImport(), xSupplier );
310 }
311 break;
313 {
314 GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
315 bStartFormPage = true;
317 }
318 break;
319 default:
320 XMLOFF_WARN_UNKNOWN_ELEMENT("sc", nElement);
321 break;
322 }
323
324 return pContext;
325}
326
327void SAL_CALL ScXMLTableContext::endFastElement(sal_Int32 /*nElement*/)
328{
330 ScXMLImport& rImport = GetScImport();
331 rImport.GetStylesImportHelper()->EndTable();
332 ScDocument* pDoc(rImport.GetDocument());
333 if (!pDoc)
334 return;
335
336 ScMyTables& rTables = rImport.GetTables();
337 SCTAB nCurTab = rTables.GetCurrentSheet();
338 // tdf#51022 process only print ranges of internal sheets
339 if (!pExternalRefInfo)
340 {
341 if (!sPrintRanges.isEmpty())
342 {
343 ScRangeList aRangeList;
345 size_t nCount = aRangeList.size();
346 for (size_t i = 0; i < nCount; i++)
347 {
348 pDoc->AddPrintRange(nCurTab, aRangeList[i]);
349 }
350 }
351 else if (!bPrintEntireSheet)
352 // Sheet has "print entire sheet" option by default. Remove it.
353 pDoc->ClearPrintRanges(nCurTab);
354 }
355
356 ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(nCurTab));
357 if (pOutlineTable)
358 {
359 ScOutlineArray& rColArray(pOutlineTable->GetColArray());
360 size_t nDepth = rColArray.GetDepth();
361 for (size_t i = 0; i < nDepth; ++i)
362 {
363 size_t nCount = rColArray.GetCount(i);
364 for (size_t j = 0; j < nCount; ++j)
365 {
366 const ScOutlineEntry* pEntry = rColArray.GetEntry(i, j);
367 if (pEntry->IsHidden())
368 rColArray.SetVisibleBelow(i, j, false);
369 }
370 }
371 ScOutlineArray& rRowArray(pOutlineTable->GetRowArray());
372 nDepth = rRowArray.GetDepth();
373 for (size_t i = 0; i < nDepth; ++i)
374 {
375 size_t nCount = rRowArray.GetCount(i);
376 for (size_t j = 0; j < nCount; ++j)
377 {
378 const ScOutlineEntry* pEntry = rRowArray.GetEntry(i, j);
379 if (pEntry->IsHidden())
380 rRowArray.SetVisibleBelow(i, j, false);
381 }
382 }
383 }
384 if (rTables.HasDrawPage())
385 {
386 if (rTables.HasXShapes())
387 {
388 rImport.GetShapeImport()->popGroupAndPostProcess();
389 uno::Reference < drawing::XShapes > xTempShapes(rTables.GetCurrentXShapes());
390 rImport.GetShapeImport()->endPage(xTempShapes);
391 }
392 if (bStartFormPage)
393 rImport.GetFormImport()->endPage();
394 }
395
396 rTables.DeleteTable();
397 rImport.ProgressBarIncrement();
398
399 // store stream positions
400 if (!pExternalRefInfo && nStartOffset >= 0 /* && nEndOffset >= 0 */)
401 {
402 ScSheetSaveData* pSheetData = comphelper::getFromUnoTunnel<ScModelObj>(rImport.GetModel())->GetSheetSaveData();
403 SCTAB nTab = rTables.GetCurrentSheet();
404 // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
405 pSheetData->StartStreamPos( nTab, nStartOffset );
406 }
407}
408
410 ScXMLImport& rImport,
412 ScXMLImportContext( rImport )
413{
414 bool bSelectProtectedCells = false;
415 bool bSelectUnprotectedCells = false;
416 bool bInsertColumns = false;
417 bool bInsertRows = false;
418 bool bDeleteColumns = false;
419 bool bDeleteRows = false;
420
421 if ( rAttrList.is() )
422 {
423 for (auto &aIter : *rAttrList)
424 {
425 sal_Int32 nToken = aIter.getToken();
426 switch (nToken)
427 {
429 case XML_ELEMENT( OFFICE_EXT, XML_SELECT_PROTECTED_CELLS ):
431 bSelectProtectedCells = IsXMLToken(aIter, XML_TRUE);
432 break;
434 case XML_ELEMENT( OFFICE_EXT, XML_SELECT_UNPROTECTED_CELLS ):
436 bSelectUnprotectedCells = IsXMLToken(aIter, XML_TRUE);
437 break;
438 case XML_ELEMENT( LO_EXT, XML_INSERT_COLUMNS ):
439 bInsertColumns = IsXMLToken(aIter, XML_TRUE);
440 break;
441 case XML_ELEMENT( LO_EXT, XML_INSERT_ROWS ):
442 bInsertRows = IsXMLToken(aIter, XML_TRUE);
443 break;
444 case XML_ELEMENT( LO_EXT, XML_DELETE_COLUMNS ):
445 bDeleteColumns = IsXMLToken(aIter, XML_TRUE);
446 break;
447 case XML_ELEMENT( LO_EXT, XML_DELETE_ROWS ):
448 bDeleteRows = IsXMLToken(aIter, XML_TRUE);
449 break;
450 default:
451 XMLOFF_WARN_UNKNOWN("sc", aIter);
452 }
453 }
454 }
455
457 rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
458 rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
459 rProtectData.mbInsertColumns = bInsertColumns;
460 rProtectData.mbInsertRows = bInsertRows;
461 rProtectData.mbDeleteColumns = bDeleteColumns;
462 rProtectData.mbDeleteRows = bDeleteRows;
463}
464
466{
467}
468
469/* 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:6297
SC_DLLPUBLIC void ClearPrintRanges(SCTAB nTab)
Removes all print ranges.
Definition: document.cxx:6291
SC_DLLPUBLIC ScExternalRefManager * GetExternalRefManager() const
Definition: documen3.cxx:625
SC_DLLPUBLIC ScOutlineTable * GetOutlineTable(SCTAB nTab, bool bCreate=false)
Definition: documen3.cxx:737
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, std::u16string_view 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:1570
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:1550
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:212
virtual ~ScXMLTableContext() override
Definition: xmltabi.cxx:207
ScXMLTableContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:132
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:327
virtual ~ScXMLTableProtectionContext() override
Definition: xmltabi.cxx:465
ScXMLTableProtectionContext(ScXMLImport &rImport, const rtl::Reference< sax_fastparser::FastAttributeList > &rAttrList)
Definition: xmltabi.cxx:409
SvXMLImport & GetImport()
Handle the import of sparkline groups and sparklines.
static SvXMLImportContext * createOfficeFormsContext(SvXMLImport &_rImport)
int nCount
sal_Int32 mnRow
sal_Int32 mnCol
OUString sName
void * p
sal_Int64 n
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:65