Update ooo320-m1
[ooovba.git] / sc / source / filter / xml / xmltabi.cxx
bloba2995a60595ae998e16761b1eb48f4cd289b1ffc
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmltabi.cxx,v $
10 * $Revision: 1.40.134.4 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
38 #include "xmltabi.hxx"
39 #include "xmlimprt.hxx"
40 #include "xmlrowi.hxx"
41 #include "xmlcoli.hxx"
42 #include "xmlsceni.hxx"
43 #include "xmlexternaltabi.hxx"
44 #include "document.hxx"
45 #include "docuno.hxx"
46 #include "olinetab.hxx"
47 #include "XMLConverter.hxx"
48 #include "XMLTableShapesContext.hxx"
49 #include "XMLTableSourceContext.hxx"
50 #include "XMLStylesImportHelper.hxx"
51 #include "rangeutl.hxx"
52 #include "externalrefmgr.hxx"
53 #include "sheetdata.hxx"
55 #include <xmloff/xmltkmap.hxx>
56 #include <xmloff/nmspmap.hxx>
57 #include <xmloff/formsimp.hxx>
58 #include <xmloff/xmltoken.hxx>
60 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
61 #include <com/sun/star/sheet/XSpreadsheets.hpp>
62 #include <com/sun/star/sheet/XSpreadsheet.hpp>
63 #include <com/sun/star/sheet/XPrintAreas.hpp>
64 #include <com/sun/star/table/CellAddress.hpp>
66 using namespace com::sun::star;
67 using namespace xmloff::token;
68 using ::com::sun::star::uno::Reference;
69 using ::com::sun::star::xml::sax::XAttributeList;
70 using ::rtl::OUString;
72 /**
73 * Determine whether this table is an external reference cache from its
74 * name. There is currently no way of determining whether a table is a
75 * regular table or an external reference cache other than examining the
76 * name itself. We should probably introduce a new boolean value for
77 * table:table element and use it instead of doing this, to make it more
78 * reliable and future-proof.
80 * @param rName
82 * @return
84 static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rUrl, rtl::OUString& rExtTabName)
86 // 'file:///path/to/file.ods'#MySheet
87 // 'file:///path/to/file.ods'#MySheet with space
88 // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
89 // That's allowed.)
91 static const sal_Unicode aPrefix[] = {
92 '\'', 'f', 'i', 'l', 'e', ':', '/', '/'
95 rtl::OUStringBuffer aUrlBuf, aTabNameBuf;
96 aUrlBuf.appendAscii("file://");
97 sal_Int32 n = rName.getLength();
98 const sal_Unicode* p = rName.getStr();
100 bool bInUrl = true;
101 sal_Unicode cPrev = 0;
102 for (sal_Int32 i = 0; i < n; ++i)
104 const sal_Unicode c = p[i];
105 if (i <= 7)
107 if (c != aPrefix[i])
108 return false;
110 else if (c == '#')
112 if (cPrev != '\'')
113 return false;
115 rUrl = aUrlBuf.makeStringAndClear();
116 rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote.
117 bInUrl = false;
119 else if (bInUrl)
120 aUrlBuf.append(c);
121 else
122 aTabNameBuf.append(c);
124 cPrev = c;
127 if (bInUrl)
128 return false;
130 if (aTabNameBuf.getLength() == 0)
131 return false;
133 rExtTabName = aTabNameBuf.makeStringAndClear();
135 return true;
138 ScXMLExternalTabData::ScXMLExternalTabData() :
139 mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
143 //------------------------------------------------------------------
145 ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
146 USHORT nPrfx,
147 const ::rtl::OUString& rLName,
148 const ::com::sun::star::uno::Reference<
149 ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
150 const sal_Bool bTempIsSubTable,
151 const sal_Int32 nSpannedCols) :
152 SvXMLImportContext( rImport, nPrfx, rLName ),
153 pExternalRefInfo(NULL),
154 nStartOffset(-1),
155 bStartFormPage(sal_False),
156 bPrintEntireSheet(sal_True)
158 // get start offset in file (if available)
159 nStartOffset = GetScImport().GetByteOffset();
161 if (!bTempIsSubTable)
163 ScXMLTabProtectionData aProtectData;
164 rtl::OUString sName;
165 rtl::OUString sStyleName;
166 sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
167 const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableAttrTokenMap();
168 for( sal_Int16 i=0; i < nAttrCount; ++i )
170 const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
171 rtl::OUString aLocalName;
172 USHORT nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
173 sAttrName, &aLocalName ));
174 const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
176 switch( rAttrTokenMap.Get( nPrefix, aLocalName ) )
178 case XML_TOK_TABLE_NAME:
179 sName = sValue;
180 break;
181 case XML_TOK_TABLE_STYLE_NAME:
182 sStyleName = sValue;
183 break;
184 case XML_TOK_TABLE_PROTECTED:
185 aProtectData.mbProtected = IsXMLToken(sValue, XML_TRUE);
186 break;
187 case XML_TOK_TABLE_PRINT_RANGES:
188 sPrintRanges = sValue;
189 break;
190 case XML_TOK_TABLE_PASSWORD:
191 aProtectData.maPassword = sValue;
192 break;
193 case XML_TOK_TABLE_PASSHASH:
194 aProtectData.meHash1 = ScPassHashHelper::getHashTypeFromURI(sValue);
195 break;
196 case XML_TOK_TABLE_PASSHASH_2:
197 aProtectData.meHash2 = ScPassHashHelper::getHashTypeFromURI(sValue);
198 break;
199 case XML_TOK_TABLE_PRINT:
201 if (IsXMLToken(sValue, XML_FALSE))
202 bPrintEntireSheet = sal_False;
204 break;
208 rtl::OUString aExtUrl, aExtTabName;
209 if (lcl_isExternalRefCache(sName, aExtUrl, aExtTabName))
211 // This is an external ref cache table.
212 pExternalRefInfo.reset(new ScXMLExternalTabData);
213 pExternalRefInfo->maFileUrl = aExtUrl;
214 ScDocument* pDoc = GetScImport().GetDocument();
215 if (pDoc)
217 ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
218 pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl);
219 pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true);
222 else
224 // This is a regular table.
225 GetScImport().GetTables().NewSheet(sName, sStyleName, aProtectData);
228 else
230 GetScImport().GetTables().NewTable(nSpannedCols);
234 ScXMLTableContext::~ScXMLTableContext()
238 SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
239 const ::rtl::OUString& rLName,
240 const ::com::sun::star::uno::Reference<
241 ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
243 const SvXMLTokenMap& rTokenMap(GetScImport().GetTableElemTokenMap());
244 sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLName);
245 if (pExternalRefInfo.get())
247 // We only care about the table-row and table-source elements for
248 // external cache data.
249 switch (nToken)
251 case XML_TOK_TABLE_ROW_GROUP:
252 case XML_TOK_TABLE_HEADER_ROWS:
253 case XML_TOK_TABLE_ROWS:
254 // #i101319# don't discard rows in groups or header (repeat range)
255 return new ScXMLExternalRefRowsContext(
256 GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
257 case XML_TOK_TABLE_ROW:
258 return new ScXMLExternalRefRowContext(
259 GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
260 case XML_TOK_TABLE_SOURCE:
261 return new ScXMLExternalRefTabSourceContext(
262 GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
263 default:
267 return new SvXMLImportContext(GetImport(), nPrefix, rLName);
270 SvXMLImportContext *pContext(0);
272 switch (nToken)
274 case XML_TOK_TABLE_COL_GROUP:
275 pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
276 rLName, xAttrList,
277 sal_False, sal_True );
278 break;
279 case XML_TOK_TABLE_HEADER_COLS:
280 pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
281 rLName, xAttrList,
282 sal_True, sal_False );
283 break;
284 case XML_TOK_TABLE_COLS:
285 pContext = new ScXMLTableColsContext( GetScImport(), nPrefix,
286 rLName, xAttrList,
287 sal_False, sal_False );
288 break;
289 case XML_TOK_TABLE_COL:
290 pContext = new ScXMLTableColContext( GetScImport(), nPrefix,
291 rLName, xAttrList );
292 break;
293 case XML_TOK_TABLE_PROTECTION:
294 pContext = new ScXMLTableProtectionContext( GetScImport(), nPrefix, rLName, xAttrList );
295 break;
296 case XML_TOK_TABLE_ROW_GROUP:
297 pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
298 rLName, xAttrList,
299 sal_False, sal_True );
300 break;
301 case XML_TOK_TABLE_HEADER_ROWS:
302 pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
303 rLName, xAttrList,
304 sal_True, sal_False );
305 break;
306 case XML_TOK_TABLE_ROWS:
307 pContext = new ScXMLTableRowsContext( GetScImport(), nPrefix,
308 rLName, xAttrList,
309 sal_False, sal_False );
310 break;
311 case XML_TOK_TABLE_ROW:
312 pContext = new ScXMLTableRowContext( GetScImport(), nPrefix,
313 rLName, xAttrList//,
314 //this
316 break;
317 case XML_TOK_TABLE_SOURCE:
318 pContext = new ScXMLTableSourceContext( GetScImport(), nPrefix, rLName, xAttrList);
319 break;
320 case XML_TOK_TABLE_SCENARIO:
321 pContext = new ScXMLTableScenarioContext( GetScImport(), nPrefix, rLName, xAttrList);
322 break;
323 case XML_TOK_TABLE_SHAPES:
324 pContext = new ScXMLTableShapesContext( GetScImport(), nPrefix, rLName, xAttrList);
325 break;
326 case XML_TOK_TABLE_FORMS:
328 GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
329 bStartFormPage = sal_True;
330 pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName );
332 break;
333 default:
337 if( !pContext )
338 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
340 return pContext;
343 void ScXMLTableContext::EndElement()
345 // get end offset in file (if available)
346 // sal_Int32 nEndOffset = GetScImport().GetByteOffset();
348 GetScImport().LockSolarMutex();
349 GetScImport().GetStylesImportHelper()->EndTable();
350 ScDocument* pDoc(GetScImport().GetDocument());
351 if (pDoc)
353 if (sPrintRanges.getLength())
355 uno::Reference< sheet::XPrintAreas > xPrintAreas( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY );
356 if( xPrintAreas.is() )
358 uno::Sequence< table::CellRangeAddress > aRangeList;
359 ScRangeStringConverter::GetRangeListFromString( aRangeList, sPrintRanges, pDoc, ::formula::FormulaGrammar::CONV_OOO );
360 xPrintAreas->setPrintAreas( aRangeList );
363 else if (bPrintEntireSheet) pDoc->SetPrintEntireSheet(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()));
365 ScOutlineTable* pOutlineTable(pDoc->GetOutlineTable(static_cast<SCTAB>(GetScImport().GetTables().GetCurrentSheet()), sal_False));
366 if (pOutlineTable)
368 ScOutlineArray* pColArray(pOutlineTable->GetColArray());
369 sal_Int32 nDepth(pColArray->GetDepth());
370 sal_Int32 i;
371 for (i = 0; i < nDepth; ++i)
373 sal_Int32 nCount(pColArray->GetCount(static_cast<USHORT>(i)));
374 for (sal_Int32 j = 0; j < nCount; ++j)
376 ScOutlineEntry* pEntry(pColArray->GetEntry(static_cast<USHORT>(i), static_cast<USHORT>(j)));
377 if (pEntry->IsHidden())
378 pColArray->SetVisibleBelow(static_cast<USHORT>(i), static_cast<USHORT>(j), sal_False);
381 ScOutlineArray* pRowArray(pOutlineTable->GetRowArray());
382 nDepth = pRowArray->GetDepth();
383 for (i = 0; i < nDepth; ++i)
385 sal_Int32 nCount(pRowArray->GetCount(static_cast<USHORT>(i)));
386 for (sal_Int32 j = 0; j < nCount; ++j)
388 ScOutlineEntry* pEntry(pRowArray->GetEntry(static_cast<USHORT>(i), static_cast<USHORT>(j)));
389 if (pEntry->IsHidden())
390 pRowArray->SetVisibleBelow(static_cast<USHORT>(i), static_cast<USHORT>(j), sal_False);
394 if (GetScImport().GetTables().HasDrawPage())
396 if (GetScImport().GetTables().HasXShapes())
398 GetScImport().GetShapeImport()->popGroupAndSort();
399 uno::Reference < drawing::XShapes > xTempShapes(GetScImport().GetTables().GetCurrentXShapes());
400 GetScImport().GetShapeImport()->endPage(xTempShapes);
402 if (bStartFormPage)
403 GetScImport().GetFormImport()->endPage();
406 GetScImport().GetTables().DeleteTable();
407 GetScImport().ProgressBarIncrement(sal_False);
409 // store stream positions
410 if (!pExternalRefInfo.get() && nStartOffset >= 0 /* && nEndOffset >= 0 */)
412 ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
413 sal_Int32 nTab = GetScImport().GetTables().GetCurrentSheet();
414 // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
415 pSheetData->StartStreamPos( nTab, nStartOffset );
418 GetScImport().UnlockSolarMutex();
421 // ============================================================================
423 ScXMLImport& ScXMLTableProtectionContext::GetScImport()
425 return static_cast<ScXMLImport&>(GetImport());
428 ScXMLTableProtectionContext::ScXMLTableProtectionContext(
429 ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
430 const Reference<XAttributeList>& xAttrList ) :
431 SvXMLImportContext( rImport, nPrefix, rLName )
433 const SvXMLTokenMap& rAttrTokenMap = GetScImport().GetTableProtectionAttrTokenMap();
434 bool bSelectProtectedCells = false;
435 bool bSelectUnprotectedCells = false;
437 sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
439 for (sal_Int16 i = 0; i < nAttrCount; ++i)
441 const OUString& aAttrName = xAttrList->getNameByIndex(i);
442 const OUString aValue = xAttrList->getValueByIndex(i);
444 OUString aLocalName;
445 USHORT nLocalPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
446 aAttrName, &aLocalName);
448 switch (rAttrTokenMap.Get(nLocalPrefix, aLocalName))
450 case XML_TOK_TABLE_SELECT_PROTECTED_CELLS:
451 bSelectProtectedCells = IsXMLToken(aValue, XML_TRUE);
452 break;
453 case XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS:
454 bSelectUnprotectedCells = IsXMLToken(aValue, XML_TRUE);
455 break;
456 default:
461 ScXMLTabProtectionData& rProtectData = GetScImport().GetTables().GetCurrentProtectionData();
462 rProtectData.mbSelectProtectedCells = bSelectProtectedCells;
463 rProtectData.mbSelectUnprotectedCells = bSelectUnprotectedCells;
466 ScXMLTableProtectionContext::~ScXMLTableProtectionContext()
470 SvXMLImportContext* ScXMLTableProtectionContext::CreateChildContext(
471 USHORT /*nPrefix*/, const OUString& /*rLocalName*/, const Reference<XAttributeList>& /*xAttrList*/ )
473 return NULL;
476 void ScXMLTableProtectionContext::EndElement()