1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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"
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
;
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.
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.
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();
101 sal_Unicode cPrev
= 0;
102 for (sal_Int32 i
= 0; i
< n
; ++i
)
104 const sal_Unicode c
= p
[i
];
115 rUrl
= aUrlBuf
.makeStringAndClear();
116 rUrl
= rUrl
.copy(0, rUrl
.getLength()-1); // remove the trailing single-quote.
122 aTabNameBuf
.append(c
);
130 if (aTabNameBuf
.getLength() == 0)
133 rExtTabName
= aTabNameBuf
.makeStringAndClear();
138 ScXMLExternalTabData::ScXMLExternalTabData() :
139 mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
143 //------------------------------------------------------------------
145 ScXMLTableContext::ScXMLTableContext( ScXMLImport
& rImport
,
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
),
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
;
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
:
181 case XML_TOK_TABLE_STYLE_NAME
:
184 case XML_TOK_TABLE_PROTECTED
:
185 aProtectData
.mbProtected
= IsXMLToken(sValue
, XML_TRUE
);
187 case XML_TOK_TABLE_PRINT_RANGES
:
188 sPrintRanges
= sValue
;
190 case XML_TOK_TABLE_PASSWORD
:
191 aProtectData
.maPassword
= sValue
;
193 case XML_TOK_TABLE_PASSHASH
:
194 aProtectData
.meHash1
= ScPassHashHelper::getHashTypeFromURI(sValue
);
196 case XML_TOK_TABLE_PASSHASH_2
:
197 aProtectData
.meHash2
= ScPassHashHelper::getHashTypeFromURI(sValue
);
199 case XML_TOK_TABLE_PRINT
:
201 if (IsXMLToken(sValue
, XML_FALSE
))
202 bPrintEntireSheet
= sal_False
;
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();
217 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
218 pExternalRefInfo
->mnFileId
= pRefMgr
->getExternalFileId(aExtUrl
);
219 pExternalRefInfo
->mpCacheTable
= pRefMgr
->getCacheTable(pExternalRefInfo
->mnFileId
, aExtTabName
, true);
224 // This is a regular table.
225 GetScImport().GetTables().NewSheet(sName
, sStyleName
, aProtectData
);
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.
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
);
267 return new SvXMLImportContext(GetImport(), nPrefix
, rLName
);
270 SvXMLImportContext
*pContext(0);
274 case XML_TOK_TABLE_COL_GROUP
:
275 pContext
= new ScXMLTableColsContext( GetScImport(), nPrefix
,
277 sal_False
, sal_True
);
279 case XML_TOK_TABLE_HEADER_COLS
:
280 pContext
= new ScXMLTableColsContext( GetScImport(), nPrefix
,
282 sal_True
, sal_False
);
284 case XML_TOK_TABLE_COLS
:
285 pContext
= new ScXMLTableColsContext( GetScImport(), nPrefix
,
287 sal_False
, sal_False
);
289 case XML_TOK_TABLE_COL
:
290 pContext
= new ScXMLTableColContext( GetScImport(), nPrefix
,
293 case XML_TOK_TABLE_PROTECTION
:
294 pContext
= new ScXMLTableProtectionContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
296 case XML_TOK_TABLE_ROW_GROUP
:
297 pContext
= new ScXMLTableRowsContext( GetScImport(), nPrefix
,
299 sal_False
, sal_True
);
301 case XML_TOK_TABLE_HEADER_ROWS
:
302 pContext
= new ScXMLTableRowsContext( GetScImport(), nPrefix
,
304 sal_True
, sal_False
);
306 case XML_TOK_TABLE_ROWS
:
307 pContext
= new ScXMLTableRowsContext( GetScImport(), nPrefix
,
309 sal_False
, sal_False
);
311 case XML_TOK_TABLE_ROW
:
312 pContext
= new ScXMLTableRowContext( GetScImport(), nPrefix
,
317 case XML_TOK_TABLE_SOURCE
:
318 pContext
= new ScXMLTableSourceContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
320 case XML_TOK_TABLE_SCENARIO
:
321 pContext
= new ScXMLTableScenarioContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
323 case XML_TOK_TABLE_SHAPES
:
324 pContext
= new ScXMLTableShapesContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
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
);
338 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
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());
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
));
368 ScOutlineArray
* pColArray(pOutlineTable
->GetColArray());
369 sal_Int32
nDepth(pColArray
->GetDepth());
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
);
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
);
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
);
453 case XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS
:
454 bSelectUnprotectedCells
= IsXMLToken(aValue
, XML_TRUE
);
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*/ )
476 void ScXMLTableProtectionContext::EndElement()