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"
54 #include <xmloff/xmltkmap.hxx>
55 #include <xmloff/nmspmap.hxx>
56 #include <xmloff/formsimp.hxx>
57 #include <xmloff/xmltoken.hxx>
59 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
60 #include <com/sun/star/sheet/XSpreadsheets.hpp>
61 #include <com/sun/star/sheet/XSpreadsheet.hpp>
62 #include <com/sun/star/sheet/XPrintAreas.hpp>
63 #include <com/sun/star/table/CellAddress.hpp>
65 using namespace com::sun::star
;
66 using namespace xmloff::token
;
67 using ::com::sun::star::uno::Reference
;
68 using ::com::sun::star::xml::sax::XAttributeList
;
69 using ::rtl::OUString
;
72 * Determine whether this table is an external reference cache from its
73 * name. There is currently no way of determining whether a table is a
74 * regular table or an external reference cache other than examining the
75 * name itself. We should probably introduce a new boolean value for
76 * table:table element and use it instead of doing this, to make it more
77 * reliable and future-proof.
83 static bool lcl_isExternalRefCache(const rtl::OUString
& rName
, rtl::OUString
& rUrl
, rtl::OUString
& rExtTabName
)
85 // 'file:///path/to/file.ods'#MySheet
86 // 'file:///path/to/file.ods'#MySheet with space
87 // 'file:///path/to/file's.ods'#Sheet (Notice the quote in the file name.
90 static const sal_Unicode aPrefix
[] = {
91 '\'', 'f', 'i', 'l', 'e', ':', '/', '/'
94 rtl::OUStringBuffer aUrlBuf
, aTabNameBuf
;
95 aUrlBuf
.appendAscii("file://");
96 sal_Int32 n
= rName
.getLength();
97 const sal_Unicode
* p
= rName
.getStr();
100 sal_Unicode cPrev
= 0;
101 for (sal_Int32 i
= 0; i
< n
; ++i
)
103 const sal_Unicode c
= p
[i
];
114 rUrl
= aUrlBuf
.makeStringAndClear();
115 rUrl
= rUrl
.copy(0, rUrl
.getLength()-1); // remove the trailing single-quote.
121 aTabNameBuf
.append(c
);
129 if (aTabNameBuf
.getLength() == 0)
132 rExtTabName
= aTabNameBuf
.makeStringAndClear();
137 ScXMLExternalTabData::ScXMLExternalTabData() :
138 mpCacheTable(), mnRow(0), mnCol(0), mnFileId(0)
142 //------------------------------------------------------------------
144 ScXMLTableContext::ScXMLTableContext( ScXMLImport
& rImport
,
146 const ::rtl::OUString
& rLName
,
147 const ::com::sun::star::uno::Reference
<
148 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
,
149 const sal_Bool bTempIsSubTable
,
150 const sal_Int32 nSpannedCols
) :
151 SvXMLImportContext( rImport
, nPrfx
, rLName
),
152 pExternalRefInfo(NULL
),
153 bStartFormPage(sal_False
),
154 bPrintEntireSheet(sal_True
)
156 if (!bTempIsSubTable
)
158 ScXMLTabProtectionData aProtectData
;
160 rtl::OUString sStyleName
;
161 sal_Int16
nAttrCount(xAttrList
.is() ? xAttrList
->getLength() : 0);
162 const SvXMLTokenMap
& rAttrTokenMap
= GetScImport().GetTableAttrTokenMap();
163 for( sal_Int16 i
=0; i
< nAttrCount
; ++i
)
165 const rtl::OUString
& sAttrName(xAttrList
->getNameByIndex( i
));
166 rtl::OUString aLocalName
;
167 USHORT
nPrefix(GetScImport().GetNamespaceMap().GetKeyByAttrName(
168 sAttrName
, &aLocalName
));
169 const rtl::OUString
& sValue(xAttrList
->getValueByIndex( i
));
171 switch( rAttrTokenMap
.Get( nPrefix
, aLocalName
) )
173 case XML_TOK_TABLE_NAME
:
176 case XML_TOK_TABLE_STYLE_NAME
:
179 case XML_TOK_TABLE_PROTECTED
:
180 aProtectData
.mbProtected
= IsXMLToken(sValue
, XML_TRUE
);
182 case XML_TOK_TABLE_PRINT_RANGES
:
183 sPrintRanges
= sValue
;
185 case XML_TOK_TABLE_PASSWORD
:
186 aProtectData
.maPassword
= sValue
;
188 case XML_TOK_TABLE_PASSHASH
:
189 aProtectData
.meHash1
= ScPassHashHelper::getHashTypeFromURI(sValue
);
191 case XML_TOK_TABLE_PASSHASH_2
:
192 aProtectData
.meHash2
= ScPassHashHelper::getHashTypeFromURI(sValue
);
194 case XML_TOK_TABLE_PRINT
:
196 if (IsXMLToken(sValue
, XML_FALSE
))
197 bPrintEntireSheet
= sal_False
;
203 rtl::OUString aExtUrl
, aExtTabName
;
204 if (lcl_isExternalRefCache(sName
, aExtUrl
, aExtTabName
))
206 // This is an external ref cache table.
207 pExternalRefInfo
.reset(new ScXMLExternalTabData
);
208 pExternalRefInfo
->maFileUrl
= aExtUrl
;
209 ScDocument
* pDoc
= GetScImport().GetDocument();
212 ScExternalRefManager
* pRefMgr
= pDoc
->GetExternalRefManager();
213 pExternalRefInfo
->mnFileId
= pRefMgr
->getExternalFileId(aExtUrl
);
214 pExternalRefInfo
->mpCacheTable
= pRefMgr
->getCacheTable(pExternalRefInfo
->mnFileId
, aExtTabName
, true);
219 // This is a regular table.
220 GetScImport().GetTables().NewSheet(sName
, sStyleName
, aProtectData
);
225 GetScImport().GetTables().NewTable(nSpannedCols
);
229 ScXMLTableContext::~ScXMLTableContext()
233 SvXMLImportContext
*ScXMLTableContext::CreateChildContext( USHORT nPrefix
,
234 const ::rtl::OUString
& rLName
,
235 const ::com::sun::star::uno::Reference
<
236 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
238 const SvXMLTokenMap
& rTokenMap(GetScImport().GetTableElemTokenMap());
239 sal_uInt16 nToken
= rTokenMap
.Get(nPrefix
, rLName
);
240 if (pExternalRefInfo
.get())
242 // We only care about the table-row and table-source elements for
243 // external cache data.
246 case XML_TOK_TABLE_ROW_GROUP
:
247 case XML_TOK_TABLE_HEADER_ROWS
:
248 case XML_TOK_TABLE_ROWS
:
249 // #i101319# don't discard rows in groups or header (repeat range)
250 return new ScXMLExternalRefRowsContext(
251 GetScImport(), nPrefix
, rLName
, xAttrList
, *pExternalRefInfo
);
252 case XML_TOK_TABLE_ROW
:
253 return new ScXMLExternalRefRowContext(
254 GetScImport(), nPrefix
, rLName
, xAttrList
, *pExternalRefInfo
);
255 case XML_TOK_TABLE_SOURCE
:
256 return new ScXMLExternalRefTabSourceContext(
257 GetScImport(), nPrefix
, rLName
, xAttrList
, *pExternalRefInfo
);
262 return new SvXMLImportContext(GetImport(), nPrefix
, rLName
);
265 SvXMLImportContext
*pContext(0);
269 case XML_TOK_TABLE_COL_GROUP
:
270 pContext
= new ScXMLTableColsContext( GetScImport(), nPrefix
,
272 sal_False
, sal_True
);
274 case XML_TOK_TABLE_HEADER_COLS
:
275 pContext
= new ScXMLTableColsContext( GetScImport(), nPrefix
,
277 sal_True
, sal_False
);
279 case XML_TOK_TABLE_COLS
:
280 pContext
= new ScXMLTableColsContext( GetScImport(), nPrefix
,
282 sal_False
, sal_False
);
284 case XML_TOK_TABLE_COL
:
285 pContext
= new ScXMLTableColContext( GetScImport(), nPrefix
,
288 case XML_TOK_TABLE_PROTECTION
:
289 pContext
= new ScXMLTableProtectionContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
291 case XML_TOK_TABLE_ROW_GROUP
:
292 pContext
= new ScXMLTableRowsContext( GetScImport(), nPrefix
,
294 sal_False
, sal_True
);
296 case XML_TOK_TABLE_HEADER_ROWS
:
297 pContext
= new ScXMLTableRowsContext( GetScImport(), nPrefix
,
299 sal_True
, sal_False
);
301 case XML_TOK_TABLE_ROWS
:
302 pContext
= new ScXMLTableRowsContext( GetScImport(), nPrefix
,
304 sal_False
, sal_False
);
306 case XML_TOK_TABLE_ROW
:
307 pContext
= new ScXMLTableRowContext( GetScImport(), nPrefix
,
312 case XML_TOK_TABLE_SOURCE
:
313 pContext
= new ScXMLTableSourceContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
315 case XML_TOK_TABLE_SCENARIO
:
316 pContext
= new ScXMLTableScenarioContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
318 case XML_TOK_TABLE_SHAPES
:
319 pContext
= new ScXMLTableShapesContext( GetScImport(), nPrefix
, rLName
, xAttrList
);
321 case XML_TOK_TABLE_FORMS
:
323 GetScImport().GetFormImport()->startPage(GetScImport().GetTables().GetCurrentXDrawPage());
324 bStartFormPage
= sal_True
;
325 pContext
= GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix
, rLName
);
333 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
338 void ScXMLTableContext::EndElement()
340 GetScImport().LockSolarMutex();
341 GetScImport().GetStylesImportHelper()->EndTable();
342 ScDocument
* pDoc(GetScImport().GetDocument());
345 if (sPrintRanges
.getLength())
347 uno::Reference
< sheet::XPrintAreas
> xPrintAreas( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY
);
348 if( xPrintAreas
.is() )
350 uno::Sequence
< table::CellRangeAddress
> aRangeList
;
351 ScRangeStringConverter::GetRangeListFromString( aRangeList
, sPrintRanges
, pDoc
, ::formula::FormulaGrammar::CONV_OOO
);
352 xPrintAreas
->setPrintAreas( aRangeList
);
355 else if (bPrintEntireSheet
) pDoc
->SetPrintEntireSheet(static_cast<SCTAB
>(GetScImport().GetTables().GetCurrentSheet()));
357 ScOutlineTable
* pOutlineTable(pDoc
->GetOutlineTable(static_cast<SCTAB
>(GetScImport().GetTables().GetCurrentSheet()), sal_False
));
360 ScOutlineArray
* pColArray(pOutlineTable
->GetColArray());
361 sal_Int32
nDepth(pColArray
->GetDepth());
363 for (i
= 0; i
< nDepth
; ++i
)
365 sal_Int32
nCount(pColArray
->GetCount(static_cast<USHORT
>(i
)));
366 for (sal_Int32 j
= 0; j
< nCount
; ++j
)
368 ScOutlineEntry
* pEntry(pColArray
->GetEntry(static_cast<USHORT
>(i
), static_cast<USHORT
>(j
)));
369 if (pEntry
->IsHidden())
370 pColArray
->SetVisibleBelow(static_cast<USHORT
>(i
), static_cast<USHORT
>(j
), sal_False
);
373 ScOutlineArray
* pRowArray(pOutlineTable
->GetRowArray());
374 nDepth
= pRowArray
->GetDepth();
375 for (i
= 0; i
< nDepth
; ++i
)
377 sal_Int32
nCount(pRowArray
->GetCount(static_cast<USHORT
>(i
)));
378 for (sal_Int32 j
= 0; j
< nCount
; ++j
)
380 ScOutlineEntry
* pEntry(pRowArray
->GetEntry(static_cast<USHORT
>(i
), static_cast<USHORT
>(j
)));
381 if (pEntry
->IsHidden())
382 pRowArray
->SetVisibleBelow(static_cast<USHORT
>(i
), static_cast<USHORT
>(j
), sal_False
);
386 if (GetScImport().GetTables().HasDrawPage())
388 if (GetScImport().GetTables().HasXShapes())
390 GetScImport().GetShapeImport()->popGroupAndSort();
391 uno::Reference
< drawing::XShapes
> xTempShapes(GetScImport().GetTables().GetCurrentXShapes());
392 GetScImport().GetShapeImport()->endPage(xTempShapes
);
395 GetScImport().GetFormImport()->endPage();
398 GetScImport().GetTables().DeleteTable();
399 GetScImport().ProgressBarIncrement(sal_False
);
401 GetScImport().UnlockSolarMutex();
404 // ============================================================================
406 ScXMLImport
& ScXMLTableProtectionContext::GetScImport()
408 return static_cast<ScXMLImport
&>(GetImport());
411 ScXMLTableProtectionContext::ScXMLTableProtectionContext(
412 ScXMLImport
& rImport
, USHORT nPrefix
, const OUString
& rLName
,
413 const Reference
<XAttributeList
>& xAttrList
) :
414 SvXMLImportContext( rImport
, nPrefix
, rLName
)
416 const SvXMLTokenMap
& rAttrTokenMap
= GetScImport().GetTableProtectionAttrTokenMap();
417 bool bSelectProtectedCells
= false;
418 bool bSelectUnprotectedCells
= false;
420 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
422 for (sal_Int16 i
= 0; i
< nAttrCount
; ++i
)
424 const OUString
& aAttrName
= xAttrList
->getNameByIndex(i
);
425 const OUString aValue
= xAttrList
->getValueByIndex(i
);
428 USHORT nLocalPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName(
429 aAttrName
, &aLocalName
);
431 switch (rAttrTokenMap
.Get(nLocalPrefix
, aLocalName
))
433 case XML_TOK_TABLE_SELECT_PROTECTED_CELLS
:
434 bSelectProtectedCells
= IsXMLToken(aValue
, XML_TRUE
);
436 case XML_TOK_TABLE_SELECT_UNPROTECTED_CELLS
:
437 bSelectUnprotectedCells
= IsXMLToken(aValue
, XML_TRUE
);
444 ScXMLTabProtectionData
& rProtectData
= GetScImport().GetTables().GetCurrentProtectionData();
445 rProtectData
.mbSelectProtectedCells
= bSelectProtectedCells
;
446 rProtectData
.mbSelectUnprotectedCells
= bSelectUnprotectedCells
;
449 ScXMLTableProtectionContext::~ScXMLTableProtectionContext()
453 SvXMLImportContext
* ScXMLTableProtectionContext::CreateChildContext(
454 USHORT
/*nPrefix*/, const OUString
& /*rLocalName*/, const Reference
<XAttributeList
>& /*xAttrList*/ )
459 void ScXMLTableProtectionContext::EndElement()