tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / sc / source / filter / xml / xmltabi.cxx
blob5010c70b5e11578a624c5e2e1f9747cf5e6f4150
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
30 #include "XMLTableShapesContext.hxx"
31 #include "XMLTableSourceContext.hxx"
32 #include "XMLStylesImportHelper.hxx"
33 #include <rangeutl.hxx>
34 #include <externalrefmgr.hxx>
35 #include <sheetdata.hxx>
36 #include "xmlcondformat.hxx"
37 #include "SparklineGroupsImportContext.hxx"
39 #include <xmloff/xmltoken.hxx>
40 #include <xmloff/xmlnamespace.hxx>
41 #include <xmloff/XMLEventsImportContext.hxx>
43 #include <tools/urlobj.hxx>
44 #include <sax/fastattribs.hxx>
45 #include <com/sun/star/sheet/XSpreadsheet.hpp>
46 #include <comphelper/servicehelper.hxx>
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;
53 /**
54 * Determine whether this table is an external reference cache from its
55 * name. There is currently no way of determining whether a table is a
56 * regular table or an external reference cache other than examining the
57 * name itself. We should probably introduce a new boolean value for
58 * table:table element and use it instead of doing this, to make it more
59 * reliable and future-proof.
61 * @param rName
63 * @return
65 static bool lcl_isExternalRefCache(const OUString& rName, OUString& rUrl, OUString& rExtTabName)
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.)
72 if ( rName.toChar() != '\'' ) // initial quote
73 return false;
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;
81 OUString aPrefix = INetURLObject::GetScheme( eProt );
82 sal_Int32 nPrefLen = aPrefix.getLength();
84 OUStringBuffer aUrlBuf, aTabNameBuf;
85 aUrlBuf.append( aPrefix );
86 sal_Int32 n = rName.getLength();
87 const sal_Unicode* p = rName.getStr();
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
93 const sal_Unicode c = p[i];
94 if (bInUrl)
96 // parsing file URL
97 if (c == '#')
99 if (cPrev != '\'')
100 return false;
102 rUrl = aUrlBuf.makeStringAndClear();
103 rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
104 bInUrl = false;
106 else
107 aUrlBuf.append(c);
109 else
110 // parsing sheet name.
111 aTabNameBuf.append(c);
113 cPrev = c;
116 if (bInUrl)
117 return false;
119 if (aTabNameBuf.isEmpty())
120 return false;
122 rExtTabName = aTabNameBuf.makeStringAndClear();
124 return true;
127 ScXMLExternalTabData::ScXMLExternalTabData() :
128 mnRow(0), mnCol(0), mnFileId(0)
132 ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
133 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList ) :
134 ScXMLImportContext( rImport ),
135 nStartOffset(-1),
136 bStartFormPage(false),
137 bPrintEntireSheet(true)
139 // get start offset in file (if available)
140 nStartOffset = GetScImport().GetByteOffset();
142 ScXMLTabProtectionData aProtectData;
143 OUString sName;
144 OUString sStyleName;
146 if ( rAttrList.is() )
148 for (auto &it : *rAttrList)
150 switch (it.getToken())
152 case XML_ELEMENT( TABLE, XML_NAME ):
153 sName = it.toString();
154 break;
155 case XML_ELEMENT( TABLE, XML_STYLE_NAME ):
156 sStyleName = it.toString();
157 break;
158 case XML_ELEMENT( TABLE, XML_PROTECTED ):
159 aProtectData.mbProtected = IsXMLToken( it, XML_TRUE );
160 break;
161 case XML_ELEMENT( TABLE, XML_PRINT_RANGES ):
162 sPrintRanges = it.toString();
163 break;
164 case XML_ELEMENT( TABLE, XML_PROTECTION_KEY ):
165 aProtectData.maPassword = it.toString();
166 break;
167 case XML_ELEMENT( TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM ):
168 aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
169 break;
170 case XML_ELEMENT( TABLE, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2 ):
171 case XML_ELEMENT( LO_EXT, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2 ):
172 aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI( it.toString() );
173 break;
174 case XML_ELEMENT( TABLE, XML_PRINT ):
176 if ( IsXMLToken( it, XML_FALSE) )
177 bPrintEntireSheet = false;
179 break;
185 OUString aExtUrl, aExtTabName;
186 if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName))
188 // This is an external ref cache table.
189 pExternalRefInfo.reset(new ScXMLExternalTabData);
190 ScDocument* pDoc = GetScImport().GetDocument();
191 if (pDoc)
193 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
194 pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
195 pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true,
196 nullptr, &aExtUrl);
197 pExternalRefInfo->mpCacheTable->setWholeTableCached();
200 else
202 // This is a regular table.
203 GetScImport().GetTables().NewSheet(sName, sStyleName, aProtectData);
207 ScXMLTableContext::~ScXMLTableContext()
211 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL
212 ScXMLTableContext::createFastChildContext( sal_Int32 nElement,
213 const uno::Reference< xml::sax::XFastAttributeList > & xAttrList )
215 sax_fastparser::FastAttributeList *pAttribList =
216 &sax_fastparser::castToFastAttributeList( xAttrList );
218 if (pExternalRefInfo)
220 // We only care about the table-row and table-source elements for
221 // external cache data.
222 switch ( nElement )
224 case XML_ELEMENT( TABLE, XML_TABLE_ROW_GROUP ):
225 case XML_ELEMENT( TABLE, XML_TABLE_HEADER_ROWS ):
226 case XML_ELEMENT( TABLE, XML_TABLE_ROWS ):
227 // #i101319# don't discard rows in groups or header (repeat range)
228 return new ScXMLExternalRefRowsContext(
229 GetScImport(), *pExternalRefInfo);
230 case XML_ELEMENT( TABLE, XML_TABLE_ROW ):
231 return new ScXMLExternalRefRowContext(
232 GetScImport(), pAttribList, *pExternalRefInfo);
233 case XML_ELEMENT( TABLE, XML_TABLE_SOURCE ):
234 return new ScXMLExternalRefTabSourceContext(
235 GetScImport(), pAttribList, *pExternalRefInfo);
236 default:
239 return nullptr;
242 SvXMLImportContext *pContext(nullptr);
244 switch ( nElement )
246 case XML_ELEMENT( TABLE, XML_NAMED_EXPRESSIONS ):
248 SCTAB nTab = GetScImport().GetTables().GetCurrentSheet();
249 pContext = new ScXMLNamedExpressionsContext(
250 GetScImport(),
251 std::make_shared<ScXMLNamedExpressionsContext::SheetLocalInserter>(GetScImport(), nTab));
253 break;
254 case XML_ELEMENT( TABLE, XML_TABLE_COLUMN_GROUP ):
255 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
256 false, true );
257 break;
258 case XML_ELEMENT( TABLE, XML_TABLE_HEADER_COLUMNS ):
259 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
260 true, false );
261 break;
262 case XML_ELEMENT( TABLE, XML_TABLE_COLUMNS ):
263 pContext = new ScXMLTableColsContext( GetScImport(), pAttribList,
264 false, false );
265 break;
266 case XML_ELEMENT( TABLE, XML_TABLE_COLUMN ):
267 pContext = new ScXMLTableColContext( GetScImport(), pAttribList );
268 break;
269 case XML_ELEMENT( TABLE, XML_TABLE_PROTECTION ):
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;
274 case XML_ELEMENT( TABLE, XML_TABLE_ROW_GROUP ):
275 pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
276 false, true );
277 break;
278 case XML_ELEMENT( TABLE, XML_TABLE_HEADER_ROWS ):
279 pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
280 true, false );
281 break;
282 case XML_ELEMENT( TABLE, XML_TABLE_ROWS ):
283 pContext = new ScXMLTableRowsContext( GetScImport(), pAttribList,
284 false, false );
285 break;
286 case XML_ELEMENT( TABLE, XML_TABLE_ROW ):
287 pContext = new ScXMLTableRowContext( GetScImport(), pAttribList );
288 break;
289 case XML_ELEMENT( TABLE, XML_TABLE_SOURCE ):
290 pContext = new ScXMLTableSourceContext( GetScImport(), pAttribList);
291 break;
292 case XML_ELEMENT( TABLE, XML_SCENARIO ):
293 pContext = new ScXMLTableScenarioContext( GetScImport(), pAttribList);
294 break;
295 case XML_ELEMENT( TABLE, XML_SHAPES ):
296 pContext = new ScXMLTableShapesContext( GetScImport() );
297 break;
298 case XML_ELEMENT( CALC_EXT, XML_CONDITIONAL_FORMATS ):
299 pContext = new ScXMLConditionalFormatsContext( GetScImport() );
300 break;
301 case XML_ELEMENT(CALC_EXT, XML_SPARKLINE_GROUPS):
302 pContext = new sc::SparklineGroupsImportContext(GetScImport());
303 break;
304 case XML_ELEMENT(OFFICE, XML_EVENT_LISTENERS):
305 case XML_ELEMENT(OFFICE_EXT, XML_EVENT_LISTENERS):
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 );
311 break;
312 case XML_ELEMENT(OFFICE, XML_FORMS):
314 GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
315 bStartFormPage = true;
316 pContext = xmloff::OFormLayerXMLImport::createOfficeFormsContext( GetScImport() );
318 break;
319 default:
320 XMLOFF_WARN_UNKNOWN_ELEMENT("sc", nElement);
321 break;
324 return pContext;
327 void SAL_CALL ScXMLTableContext::endFastElement(sal_Int32 /*nElement*/)
329 ScXMLImport::MutexGuard aMutexGuard(GetScImport());
330 ScXMLImport& rImport = GetScImport();
331 rImport.GetStylesImportHelper()->EndTable();
332 ScDocument* pDoc(rImport.GetDocument());
333 if (!pDoc)
334 return;
336 ScMyTables& rTables = rImport.GetTables();
337 SCTAB nCurTab = rTables.GetCurrentSheet();
338 // tdf#51022 process only print ranges of internal sheets
339 if (!pExternalRefInfo)
341 if (!sPrintRanges.isEmpty())
343 ScRangeList aRangeList;
344 ScRangeStringConverter::GetRangeListFromString(aRangeList, sPrintRanges, *pDoc, ::formula::FormulaGrammar::CONV_OOO);
345 size_t nCount = aRangeList.size();
346 for (size_t i = 0; i < nCount; i++)
348 pDoc->AddPrintRange(nCurTab, aRangeList[i]);
351 else if (!bPrintEntireSheet)
352 // Sheet has "print entire sheet" option by default. Remove it.
353 pDoc->ClearPrintRanges(nCurTab);
356 ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(nCurTab));
357 if (pOutlineTable)
359 ScOutlineArray& rColArray(pOutlineTable->GetColArray());
360 size_t nDepth = rColArray.GetDepth();
361 for (size_t i = 0; i < nDepth; ++i)
363 size_t nCount = rColArray.GetCount(i);
364 for (size_t j = 0; j < nCount; ++j)
366 const ScOutlineEntry* pEntry = rColArray.GetEntry(i, j);
367 if (pEntry->IsHidden())
368 rColArray.SetVisibleBelow(i, j, false);
371 ScOutlineArray& rRowArray(pOutlineTable->GetRowArray());
372 nDepth = rRowArray.GetDepth();
373 for (size_t i = 0; i < nDepth; ++i)
375 size_t nCount = rRowArray.GetCount(i);
376 for (size_t j = 0; j < nCount; ++j)
378 const ScOutlineEntry* pEntry = rRowArray.GetEntry(i, j);
379 if (pEntry->IsHidden())
380 rRowArray.SetVisibleBelow(i, j, false);
384 if (rTables.HasDrawPage())
386 if (rTables.HasXShapes())
388 rImport.GetShapeImport()->popGroupAndPostProcess();
389 uno::Reference < drawing::XShapes > xTempShapes(rTables.GetCurrentXShapes());
390 rImport.GetShapeImport()->endPage(xTempShapes);
392 if (bStartFormPage)
393 rImport.GetFormImport()->endPage();
396 rTables.DeleteTable();
397 rImport.ProgressBarIncrement();
399 // store stream positions
400 if (!pExternalRefInfo && nStartOffset >= 0 /* && nEndOffset >= 0 */)
402 ScSheetSaveData* pSheetData = rImport.GetScModel()->GetSheetSaveData();
403 SCTAB nTab = rTables.GetCurrentSheet();
404 // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
405 pSheetData->StartStreamPos( nTab, nStartOffset );
409 ScXMLTableProtectionContext::ScXMLTableProtectionContext(
410 ScXMLImport& rImport,
411 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList ) :
412 ScXMLImportContext( rImport )
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 bool bUseAutoFilter = false;
421 bool bUsePivot = false;
423 if ( rAttrList.is() )
425 for (auto &aIter : *rAttrList)
427 sal_Int32 nToken = aIter.getToken();
428 switch (nToken)
430 case XML_ELEMENT( TABLE, XML_SELECT_PROTECTED_CELLS ):
431 case XML_ELEMENT( OFFICE_EXT, XML_SELECT_PROTECTED_CELLS ):
432 case XML_ELEMENT( LO_EXT, XML_SELECT_PROTECTED_CELLS ):
433 bSelectProtectedCells = IsXMLToken(aIter, XML_TRUE);
434 break;
435 case XML_ELEMENT( TABLE, XML_SELECT_UNPROTECTED_CELLS ):
436 case XML_ELEMENT( OFFICE_EXT, XML_SELECT_UNPROTECTED_CELLS ):
437 case XML_ELEMENT( LO_EXT, XML_SELECT_UNPROTECTED_CELLS ):
438 bSelectUnprotectedCells = IsXMLToken(aIter, XML_TRUE);
439 break;
440 case XML_ELEMENT( LO_EXT, XML_INSERT_COLUMNS ):
441 bInsertColumns = IsXMLToken(aIter, XML_TRUE);
442 break;
443 case XML_ELEMENT( LO_EXT, XML_INSERT_ROWS ):
444 bInsertRows = IsXMLToken(aIter, XML_TRUE);
445 break;
446 case XML_ELEMENT( LO_EXT, XML_DELETE_COLUMNS ):
447 bDeleteColumns = IsXMLToken(aIter, XML_TRUE);
448 break;
449 case XML_ELEMENT( LO_EXT, XML_DELETE_ROWS ):
450 bDeleteRows = IsXMLToken(aIter, XML_TRUE);
451 break;
452 case XML_ELEMENT( LO_EXT, XML_USE_AUTOFILTER ):
453 bUseAutoFilter = IsXMLToken(aIter, XML_TRUE);
454 break;
455 case XML_ELEMENT( LO_EXT, XML_USE_PIVOT ):
456 bUsePivot = IsXMLToken(aIter, XML_TRUE);
457 break;
458 default:
459 XMLOFF_WARN_UNKNOWN("sc", aIter);
464 ScXMLTabProtectionData& rProtectData = GetScImport().GetTables().GetCurrentProtectionData();
465 rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
466 rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
467 rProtectData.mbInsertColumns = bInsertColumns;
468 rProtectData.mbInsertRows = bInsertRows;
469 rProtectData.mbDeleteColumns = bDeleteColumns;
470 rProtectData.mbDeleteRows = bDeleteRows;
471 rProtectData.mbUseAutoFilter = bUseAutoFilter;
472 rProtectData.mbUsePivot = bUsePivot;
475 ScXMLTableProtectionContext::~ScXMLTableProtectionContext()
479 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */