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: xmlbodyi.cxx,v $
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"
35 // INCLUDE ---------------------------------------------------------------
38 #include "document.hxx"
40 #include "sheetdata.hxx"
42 #include "xmlbodyi.hxx"
43 #include "xmltabi.hxx"
44 #include "xmlnexpi.hxx"
45 #include "xmldrani.hxx"
46 #include "xmlimprt.hxx"
47 #include "xmldpimp.hxx"
48 #include "xmlcvali.hxx"
49 #include "xmlstyli.hxx"
50 #include "xmllabri.hxx"
51 #include "XMLConsolidationContext.hxx"
52 #include "XMLDDELinksContext.hxx"
53 #include "XMLCalculationSettingsContext.hxx"
54 #include "XMLTrackedChangesContext.hxx"
55 #include "XMLEmptyContext.hxx"
56 #include "scerrors.hxx"
57 #include "tabprotection.hxx"
59 #include <xmloff/xmltkmap.hxx>
60 #include <xmloff/xmltoken.hxx>
61 #include <xmloff/xmlnmspe.hxx>
62 #include <xmloff/nmspmap.hxx>
63 #include <xmloff/xmluconv.hxx>
64 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
65 #include <sal/types.h>
66 #include <tools/debug.hxx>
72 using namespace com::sun::star
;
73 using namespace xmloff::token
;
75 //------------------------------------------------------------------
77 ScXMLBodyContext::ScXMLBodyContext( ScXMLImport
& rImport
,
79 const ::rtl::OUString
& rLName
,
80 const uno::Reference
<xml::sax::XAttributeList
>& xAttrList
) :
81 SvXMLImportContext( rImport
, nPrfx
, rLName
),
83 meHash1(PASSHASH_SHA1
),
84 meHash2(PASSHASH_UNSPECIFIED
),
85 bProtected(sal_False
),
86 bHadCalculationSettings(sal_False
),
87 pChangeTrackingImportHelper(NULL
)
89 ScDocument
* pDoc
= GetScImport().GetDocument();
92 // ODF 1.1 and earlier => GRAM_PODF; ODF 1.2 and later => GRAM_ODFF;
93 // no version => earlier than 1.2 => GRAM_PODF.
94 formula::FormulaGrammar::Grammar eGrammar
= formula::FormulaGrammar::GRAM_ODFF
;
95 OUString
aVer( rImport
.GetODFVersion());
96 sal_Int32 nLen
= aVer
.getLength();
97 #if OSL_DEBUG_LEVEL > 1
98 fprintf( stderr
, "\n ScXMLBodyContext ODFVersion: nLen: %d, str: %s\n",
99 (int)nLen
, OUStringToOString( aVer
, RTL_TEXTENCODING_UTF8
).getStr());
102 eGrammar
= formula::FormulaGrammar::GRAM_PODF
;
105 // In case there was a micro version, e.g. "1.2.3", this would
106 // still yield major.minor, but pParsedEnd (5th parameter, not
107 // passed here) would point before string end upon return.
108 double fVer
= ::rtl::math::stringToDouble( aVer
, '.', 0, NULL
, NULL
);
110 eGrammar
= formula::FormulaGrammar::GRAM_PODF
;
112 pDoc
->SetStorageGrammar( eGrammar
);
115 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
116 for( sal_Int16 i
=0; i
< nAttrCount
; ++i
)
118 const rtl::OUString
& sAttrName(xAttrList
->getNameByIndex( i
));
119 rtl::OUString aLocalName
;
120 USHORT nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName(
121 sAttrName
, &aLocalName
);
122 const rtl::OUString
& sValue(xAttrList
->getValueByIndex( i
));
124 if (nPrefix
== XML_NAMESPACE_TABLE
)
126 if (IsXMLToken(aLocalName
, XML_STRUCTURE_PROTECTED
))
127 bProtected
= IsXMLToken(sValue
, XML_TRUE
);
128 else if (IsXMLToken(aLocalName
, XML_PROTECTION_KEY
))
130 else if (IsXMLToken(aLocalName
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
))
131 meHash1
= ScPassHashHelper::getHashTypeFromURI(sValue
);
132 else if (IsXMLToken(aLocalName
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
))
133 meHash2
= ScPassHashHelper::getHashTypeFromURI(sValue
);
138 ScXMLBodyContext::~ScXMLBodyContext()
142 SvXMLImportContext
*ScXMLBodyContext::CreateChildContext( USHORT nPrefix
,
143 const ::rtl::OUString
& rLocalName
,
144 const ::com::sun::star::uno::Reference
<
145 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
147 ScSheetSaveData
* pSheetData
= ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
148 if ( pSheetData
&& pSheetData
->HasStartPos() )
150 // stream part to copy ends before the next child element
151 sal_Int32 nEndOffset
= GetScImport().GetByteOffset();
152 pSheetData
->EndStreamPos( nEndOffset
);
155 SvXMLImportContext
*pContext
= 0;
157 const SvXMLTokenMap
& rTokenMap
= GetScImport().GetBodyElemTokenMap();
158 // sal_Bool bOrdered = sal_False;
159 // sal_Bool bHeading = sal_False;
160 switch( rTokenMap
.Get( nPrefix
, rLocalName
) )
162 // case XML_TOK_TEXT_H:
164 // case XML_TOK_TEXT_P:
165 // pContext = new SwXMLParaContext( GetSwImport(),nPrefix, rLocalName,
166 // xAttrList, bHeading );
168 // case XML_TOK_TEXT_ORDERED_LIST:
170 // case XML_TOK_TEXT_UNORDERED_LIST:
171 // pContext = new SwXMLListBlockContext( GetSwImport(),nPrefix, rLocalName,
172 // xAttrList, bOrdered );
174 case XML_TOK_BODY_TRACKED_CHANGES
:
176 pChangeTrackingImportHelper
= GetScImport().GetChangeTrackingImportHelper();
177 if (pChangeTrackingImportHelper
)
178 pContext
= new ScXMLTrackedChangesContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
, pChangeTrackingImportHelper
);
181 case XML_TOK_BODY_CALCULATION_SETTINGS
:
182 pContext
= new ScXMLCalculationSettingsContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
);
183 bHadCalculationSettings
= sal_True
;
185 case XML_TOK_BODY_CONTENT_VALIDATIONS
:
186 pContext
= new ScXMLContentValidationsContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
);
188 case XML_TOK_BODY_LABEL_RANGES
:
189 pContext
= new ScXMLLabelRangesContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
);
191 case XML_TOK_BODY_TABLE
:
193 if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB
)
195 GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW
);
196 pContext
= new ScXMLEmptyContext(GetScImport(), nPrefix
, rLocalName
);
200 pContext
= new ScXMLTableContext( GetScImport(),nPrefix
, rLocalName
,
205 case XML_TOK_BODY_NAMED_EXPRESSIONS
:
206 pContext
= new ScXMLNamedExpressionsContext ( GetScImport(), nPrefix
, rLocalName
,
209 case XML_TOK_BODY_DATABASE_RANGES
:
210 pContext
= new ScXMLDatabaseRangesContext ( GetScImport(), nPrefix
, rLocalName
,
213 case XML_TOK_BODY_DATABASE_RANGE
:
214 pContext
= new ScXMLDatabaseRangeContext ( GetScImport(), nPrefix
, rLocalName
,
217 case XML_TOK_BODY_DATA_PILOT_TABLES
:
218 pContext
= new ScXMLDataPilotTablesContext ( GetScImport(), nPrefix
, rLocalName
,
221 case XML_TOK_BODY_CONSOLIDATION
:
222 pContext
= new ScXMLConsolidationContext ( GetScImport(), nPrefix
, rLocalName
,
225 case XML_TOK_BODY_DDE_LINKS
:
226 pContext
= new ScXMLDDELinksContext ( GetScImport(), nPrefix
, rLocalName
,
232 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
237 void ScXMLBodyContext::Characters( const OUString
& )
239 ScSheetSaveData
* pSheetData
= ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
240 if ( pSheetData
&& pSheetData
->HasStartPos() )
242 // stream part to copy ends before any content (whitespace) within the spreadsheet element
243 sal_Int32 nEndOffset
= GetScImport().GetByteOffset();
244 pSheetData
->EndStreamPos( nEndOffset
);
249 void ScXMLBodyContext::EndElement()
251 ScSheetSaveData
* pSheetData
= ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
252 if ( pSheetData
&& pSheetData
->HasStartPos() )
254 // stream part to copy ends before the closing tag of spreadsheet element
255 sal_Int32 nEndOffset
= GetScImport().GetByteOffset();
256 pSheetData
->EndStreamPos( nEndOffset
);
261 // store the loaded namespaces (for the office:spreadsheet element),
262 // so the prefixes in copied stream fragments remain valid
263 const SvXMLNamespaceMap
& rNamespaces
= GetImport().GetNamespaceMap();
264 pSheetData
->StoreLoadedNamespaces( rNamespaces
);
267 if (!bHadCalculationSettings
)
269 // #111055#; set calculation settings defaults if there is no calculation settings element
270 SvXMLImportContext
*pContext
= new ScXMLCalculationSettingsContext( GetScImport(), XML_NAMESPACE_TABLE
, GetXMLToken(XML_CALCULATION_SETTINGS
), NULL
);
271 pContext
->EndElement();
273 GetScImport().LockSolarMutex();
274 ScMyImpDetectiveOpArray
* pDetOpArray
= GetScImport().GetDetectiveOpArray();
275 ScDocument
* pDoc
= GetScImport().GetDocument();
276 ScMyImpDetectiveOp aDetOp
;
278 if (pDoc
&& GetScImport().GetModel().is())
283 while( pDetOpArray
->GetFirstOp( aDetOp
) )
285 ScDetOpData
aOpData( aDetOp
.aPosition
, aDetOp
.eOpType
);
286 pDoc
->AddDetectiveOperation( aOpData
);
290 if (pChangeTrackingImportHelper
)
291 pChangeTrackingImportHelper
->CreateChangeTrack(GetScImport().GetDocument());
294 // #i57869# table styles are applied before the contents now
296 std::vector
<rtl::OUString
> aTableStyleNames(GetScImport().GetTableStyle());
297 uno::Reference
<sheet::XSpreadsheetDocument
> xSpreadDoc( GetScImport().GetModel(), uno::UNO_QUERY
);
298 if ( xSpreadDoc
.is() && !aTableStyleNames
.empty())
300 uno::Reference
<container::XIndexAccess
> xIndex( xSpreadDoc
->getSheets(), uno::UNO_QUERY
);
303 sal_Int32 nTableCount
= xIndex
->getCount();
304 sal_Int32
nSize(aTableStyleNames
.size());
305 DBG_ASSERT(nTableCount
== nSize
, "every table should have a style name");
306 for(sal_uInt32 i
= 0; i
< nTableCount
; i
++)
310 uno::Reference
<beans::XPropertySet
> xProperties(xIndex
->getByIndex(i
), uno::UNO_QUERY
);
311 if (xProperties
.is())
313 rtl::OUString
sTableStyleName(aTableStyleNames
[i
]);
314 XMLTableStylesContext
*pStyles
= (XMLTableStylesContext
*)GetScImport().GetAutoStyles();
315 if ( pStyles
&& sTableStyleName
.getLength() )
317 XMLTableStyleContext
* pStyle
= (XMLTableStyleContext
*)pStyles
->FindStyleChildContext(
318 XML_STYLE_FAMILY_TABLE_TABLE
, sTableStyleName
, sal_True
);
320 pStyle
->FillPropertySet(xProperties
);
329 // #i37959# handle document protection after the sheet settings
332 ::std::auto_ptr
<ScDocProtection
> pProtection(new ScDocProtection
);
333 pProtection
->setProtected(true);
335 uno::Sequence
<sal_Int8
> aPass
;
336 if (sPassword
.getLength())
338 SvXMLUnitConverter::decodeBase64(aPass
, sPassword
);
339 pProtection
->setPasswordHash(aPass
, meHash1
, meHash2
);
342 pDoc
->SetDocProtection(pProtection
.get());
345 GetScImport().UnlockSolarMutex();