merge the formfield patch from ooo-build
[ooovba.git] / sc / source / filter / xml / xmlbodyi.cxx
blob835cb834c457a154210586f5a897abdcf382e44e
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 $
10 * $Revision: 1.32 $
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 ---------------------------------------------------------------
36 #include <cstdio>
38 #include "document.hxx"
39 #include "docuno.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>
68 #include <memory>
70 using rtl::OUString;
72 using namespace com::sun::star;
73 using namespace xmloff::token;
75 //------------------------------------------------------------------
77 ScXMLBodyContext::ScXMLBodyContext( ScXMLImport& rImport,
78 USHORT nPrfx,
79 const ::rtl::OUString& rLName,
80 const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
81 SvXMLImportContext( rImport, nPrfx, rLName ),
82 sPassword(),
83 meHash1(PASSHASH_SHA1),
84 meHash2(PASSHASH_UNSPECIFIED),
85 bProtected(sal_False),
86 bHadCalculationSettings(sal_False),
87 pChangeTrackingImportHelper(NULL)
89 ScDocument* pDoc = GetScImport().GetDocument();
90 if (pDoc)
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());
100 #endif
101 if (!nLen)
102 eGrammar = formula::FormulaGrammar::GRAM_PODF;
103 else
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);
109 if (fVer < 1.2)
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))
129 sPassword = sValue;
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:
163 // bHeading = TRUE;
164 // case XML_TOK_TEXT_P:
165 // pContext = new SwXMLParaContext( GetSwImport(),nPrefix, rLocalName,
166 // xAttrList, bHeading );
167 // break;
168 // case XML_TOK_TEXT_ORDERED_LIST:
169 // bOrdered = TRUE;
170 // case XML_TOK_TEXT_UNORDERED_LIST:
171 // pContext = new SwXMLListBlockContext( GetSwImport(),nPrefix, rLocalName,
172 // xAttrList, bOrdered );
173 // break;
174 case XML_TOK_BODY_TRACKED_CHANGES :
176 pChangeTrackingImportHelper = GetScImport().GetChangeTrackingImportHelper();
177 if (pChangeTrackingImportHelper)
178 pContext = new ScXMLTrackedChangesContext( GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
180 break;
181 case XML_TOK_BODY_CALCULATION_SETTINGS :
182 pContext = new ScXMLCalculationSettingsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
183 bHadCalculationSettings = sal_True;
184 break;
185 case XML_TOK_BODY_CONTENT_VALIDATIONS :
186 pContext = new ScXMLContentValidationsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
187 break;
188 case XML_TOK_BODY_LABEL_RANGES:
189 pContext = new ScXMLLabelRangesContext( GetScImport(), nPrefix, rLocalName, xAttrList );
190 break;
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);
198 else
200 pContext = new ScXMLTableContext( GetScImport(),nPrefix, rLocalName,
201 xAttrList );
204 break;
205 case XML_TOK_BODY_NAMED_EXPRESSIONS:
206 pContext = new ScXMLNamedExpressionsContext ( GetScImport(), nPrefix, rLocalName,
207 xAttrList );
208 break;
209 case XML_TOK_BODY_DATABASE_RANGES:
210 pContext = new ScXMLDatabaseRangesContext ( GetScImport(), nPrefix, rLocalName,
211 xAttrList );
212 break;
213 case XML_TOK_BODY_DATABASE_RANGE:
214 pContext = new ScXMLDatabaseRangeContext ( GetScImport(), nPrefix, rLocalName,
215 xAttrList );
216 break;
217 case XML_TOK_BODY_DATA_PILOT_TABLES:
218 pContext = new ScXMLDataPilotTablesContext ( GetScImport(), nPrefix, rLocalName,
219 xAttrList );
220 break;
221 case XML_TOK_BODY_CONSOLIDATION:
222 pContext = new ScXMLConsolidationContext ( GetScImport(), nPrefix, rLocalName,
223 xAttrList );
224 break;
225 case XML_TOK_BODY_DDE_LINKS:
226 pContext = new ScXMLDDELinksContext ( GetScImport(), nPrefix, rLocalName,
227 xAttrList );
228 break;
231 if( !pContext )
232 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
234 return pContext;
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 );
246 // otherwise ignore
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 );
259 if ( pSheetData )
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())
280 if (pDetOpArray)
282 pDetOpArray->Sort();
283 while( pDetOpArray->GetFirstOp( aDetOp ) )
285 ScDetOpData aOpData( aDetOp.aPosition, aDetOp.eOpType );
286 pDoc->AddDetectiveOperation( aOpData );
290 if (pChangeTrackingImportHelper)
291 pChangeTrackingImportHelper->CreateChangeTrack(GetScImport().GetDocument());
293 #if 0
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 );
301 if ( xIndex.is() )
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++)
308 if (i < nSize)
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);
319 if (pStyle)
320 pStyle->FillPropertySet(xProperties);
327 #endif
329 // #i37959# handle document protection after the sheet settings
330 if (bProtected)
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();