Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <cstdio>
30 : :
31 : : #include "document.hxx"
32 : : #include "docuno.hxx"
33 : : #include "sheetdata.hxx"
34 : :
35 : : #include "xmlbodyi.hxx"
36 : : #include "xmltabi.hxx"
37 : : #include "xmlnexpi.hxx"
38 : : #include "xmldrani.hxx"
39 : : #include "xmlimprt.hxx"
40 : : #include "xmldpimp.hxx"
41 : : #include "xmlcvali.hxx"
42 : : #include "xmlstyli.hxx"
43 : : #include "xmllabri.hxx"
44 : : #include "XMLConsolidationContext.hxx"
45 : : #include "XMLDDELinksContext.hxx"
46 : : #include "XMLCalculationSettingsContext.hxx"
47 : : #include "XMLTrackedChangesContext.hxx"
48 : : #include "XMLEmptyContext.hxx"
49 : : #include "scerrors.hxx"
50 : : #include "tabprotection.hxx"
51 : :
52 : : #include <xmloff/xmltkmap.hxx>
53 : : #include <xmloff/xmltoken.hxx>
54 : : #include <xmloff/xmlnmspe.hxx>
55 : : #include <xmloff/nmspmap.hxx>
56 : :
57 : : #include <sax/tools/converter.hxx>
58 : : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
59 : : #include <sal/types.h>
60 : :
61 : : #include <memory>
62 : :
63 : : using rtl::OUString;
64 : :
65 : : using namespace com::sun::star;
66 : : using namespace xmloff::token;
67 : :
68 : : //------------------------------------------------------------------
69 : :
70 : 93 : ScXMLBodyContext::ScXMLBodyContext( ScXMLImport& rImport,
71 : : sal_uInt16 nPrfx,
72 : : const ::rtl::OUString& rLName,
73 : : const uno::Reference<xml::sax::XAttributeList>& xAttrList ) :
74 : : SvXMLImportContext( rImport, nPrfx, rLName ),
75 : : sPassword(),
76 : : meHash1(PASSHASH_SHA1),
77 : : meHash2(PASSHASH_UNSPECIFIED),
78 : : bProtected(false),
79 : : bHadCalculationSettings(false),
80 : 93 : pChangeTrackingImportHelper(NULL)
81 : : {
82 : 93 : ScDocument* pDoc = GetScImport().GetDocument();
83 [ + - ]: 93 : if (pDoc)
84 : : {
85 : : // ODF 1.1 and earlier => GRAM_PODF; ODF 1.2 and later => GRAM_ODFF;
86 : : // no version => earlier than 1.2 => GRAM_PODF.
87 : 93 : formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_ODFF;
88 [ + - ]: 93 : OUString aVer( rImport.GetODFVersion());
89 : 93 : sal_Int32 nLen = aVer.getLength();
90 : : #if OSL_DEBUG_LEVEL > 1
91 : : fprintf( stderr, "\n ScXMLBodyContext ODFVersion: nLen: %d, str: %s\n",
92 : : (int)nLen, OUStringToOString( aVer, RTL_TEXTENCODING_UTF8).getStr());
93 : : #endif
94 [ - + ]: 93 : if (!nLen)
95 : 0 : eGrammar = formula::FormulaGrammar::GRAM_PODF;
96 : : else
97 : : {
98 : : // In case there was a micro version, e.g. "1.2.3", this would
99 : : // still yield major.minor, but pParsedEnd (5th parameter, not
100 : : // passed here) would point before string end upon return.
101 : 93 : double fVer = ::rtl::math::stringToDouble( aVer, '.', 0, NULL, NULL);
102 [ + + ]: 93 : if (fVer < 1.2)
103 : 6 : eGrammar = formula::FormulaGrammar::GRAM_PODF;
104 : : }
105 [ + - ]: 93 : pDoc->SetStorageGrammar( eGrammar);
106 : : }
107 : :
108 [ + - ][ + - ]: 93 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
[ + - ]
109 [ - + ]: 93 : for( sal_Int16 i=0; i < nAttrCount; ++i )
110 : : {
111 [ # # ][ # # ]: 0 : const rtl::OUString& sAttrName(xAttrList->getNameByIndex( i ));
112 : 0 : rtl::OUString aLocalName;
113 : 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName(
114 [ # # ]: 0 : sAttrName, &aLocalName );
115 [ # # ][ # # ]: 0 : const rtl::OUString& sValue(xAttrList->getValueByIndex( i ));
116 : :
117 [ # # ]: 0 : if (nPrefix == XML_NAMESPACE_TABLE)
118 : : {
119 [ # # ][ # # ]: 0 : if (IsXMLToken(aLocalName, XML_STRUCTURE_PROTECTED))
120 [ # # ]: 0 : bProtected = IsXMLToken(sValue, XML_TRUE);
121 [ # # ][ # # ]: 0 : else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY))
122 : 0 : sPassword = sValue;
123 [ # # ][ # # ]: 0 : else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY_DIGEST_ALGORITHM))
124 [ # # ]: 0 : meHash1 = ScPassHashHelper::getHashTypeFromURI(sValue);
125 [ # # ][ # # ]: 0 : else if (IsXMLToken(aLocalName, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2))
126 [ # # ]: 0 : meHash2 = ScPassHashHelper::getHashTypeFromURI(sValue);
127 : : }
128 : 0 : }
129 : 93 : }
130 : :
131 : 93 : ScXMLBodyContext::~ScXMLBodyContext()
132 : : {
133 [ - + ]: 186 : }
134 : :
135 : 294 : SvXMLImportContext *ScXMLBodyContext::CreateChildContext( sal_uInt16 nPrefix,
136 : : const ::rtl::OUString& rLocalName,
137 : : const ::com::sun::star::uno::Reference<
138 : : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
139 : : {
140 [ + - ][ + - ]: 294 : ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
141 [ + + ][ + + ]: 294 : if ( pSheetData && pSheetData->HasStartPos() )
[ + - ]
142 : : {
143 : : // stream part to copy ends before the next child element
144 : 167 : sal_Int32 nEndOffset = GetScImport().GetByteOffset();
145 : 167 : pSheetData->EndStreamPos( nEndOffset );
146 : : }
147 : :
148 : 294 : SvXMLImportContext *pContext = 0;
149 : :
150 : 294 : const SvXMLTokenMap& rTokenMap = GetScImport().GetBodyElemTokenMap();
151 [ - + + - : 294 : switch( rTokenMap.Get( nPrefix, rLocalName ) )
+ + + - +
- - - ]
152 : : {
153 : : case XML_TOK_BODY_TRACKED_CHANGES :
154 : 0 : pChangeTrackingImportHelper = GetScImport().GetChangeTrackingImportHelper();
155 [ # # ]: 0 : if (pChangeTrackingImportHelper)
156 [ # # ]: 0 : pContext = new ScXMLTrackedChangesContext( GetScImport(), nPrefix, rLocalName, xAttrList, pChangeTrackingImportHelper);
157 : 0 : break;
158 : : case XML_TOK_BODY_CALCULATION_SETTINGS :
159 [ + - ]: 4 : pContext = new ScXMLCalculationSettingsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
160 : 4 : bHadCalculationSettings = true;
161 : 4 : break;
162 : : case XML_TOK_BODY_CONTENT_VALIDATIONS :
163 [ + - ]: 3 : pContext = new ScXMLContentValidationsContext( GetScImport(), nPrefix, rLocalName, xAttrList );
164 : 3 : break;
165 : : case XML_TOK_BODY_LABEL_RANGES:
166 [ # # ]: 0 : pContext = new ScXMLLabelRangesContext( GetScImport(), nPrefix, rLocalName, xAttrList );
167 : 0 : break;
168 : : case XML_TOK_BODY_TABLE:
169 [ - + ]: 224 : if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB)
170 : : {
171 : 0 : GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW);
172 [ # # ]: 0 : pContext = new ScXMLEmptyContext(GetScImport(), nPrefix, rLocalName);
173 : : }
174 : : else
175 : : {
176 : : pContext = new ScXMLTableContext( GetScImport(),nPrefix, rLocalName,
177 [ + - ]: 224 : xAttrList );
178 : : }
179 : 224 : break;
180 : : case XML_TOK_BODY_NAMED_EXPRESSIONS:
181 : : pContext = new ScXMLNamedExpressionsContext (
182 : : GetScImport(), nPrefix, rLocalName, xAttrList,
183 [ + - ][ + - ]: 51 : new ScXMLNamedExpressionsContext::GlobalInserter(GetScImport()) );
184 : 51 : break;
185 : : case XML_TOK_BODY_DATABASE_RANGES:
186 : : pContext = new ScXMLDatabaseRangesContext ( GetScImport(), nPrefix, rLocalName,
187 [ + - ]: 8 : xAttrList );
188 : 8 : break;
189 : : case XML_TOK_BODY_DATABASE_RANGE:
190 : : pContext = new ScXMLDatabaseRangeContext ( GetScImport(), nPrefix, rLocalName,
191 [ # # ]: 0 : xAttrList );
192 : 0 : break;
193 : : case XML_TOK_BODY_DATA_PILOT_TABLES:
194 : : pContext = new ScXMLDataPilotTablesContext ( GetScImport(), nPrefix, rLocalName,
195 [ + - ]: 4 : xAttrList );
196 : 4 : break;
197 : : case XML_TOK_BODY_CONSOLIDATION:
198 : : pContext = new ScXMLConsolidationContext ( GetScImport(), nPrefix, rLocalName,
199 [ # # ]: 0 : xAttrList );
200 : 0 : break;
201 : : case XML_TOK_BODY_DDE_LINKS:
202 : : pContext = new ScXMLDDELinksContext ( GetScImport(), nPrefix, rLocalName,
203 [ # # ]: 0 : xAttrList );
204 : 0 : break;
205 : : }
206 : :
207 [ - + ]: 294 : if( !pContext )
208 [ # # ]: 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
209 : :
210 : 294 : return pContext;
211 : : }
212 : :
213 : 24 : void ScXMLBodyContext::Characters( const OUString& )
214 : : {
215 [ + - ][ + - ]: 24 : ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
216 [ + + ][ + + ]: 24 : if ( pSheetData && pSheetData->HasStartPos() )
[ + - ]
217 : : {
218 : : // stream part to copy ends before any content (whitespace) within the spreadsheet element
219 : 9 : sal_Int32 nEndOffset = GetScImport().GetByteOffset();
220 : 9 : pSheetData->EndStreamPos( nEndOffset );
221 : : }
222 : : // otherwise ignore
223 : 24 : }
224 : :
225 : 93 : void ScXMLBodyContext::EndElement()
226 : : {
227 [ + - ][ + - ]: 93 : ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
228 [ + + ][ + + ]: 93 : if ( pSheetData && pSheetData->HasStartPos() )
[ + - ]
229 : : {
230 : : // stream part to copy ends before the closing tag of spreadsheet element
231 [ + - ]: 28 : sal_Int32 nEndOffset = GetScImport().GetByteOffset();
232 [ + - ]: 28 : pSheetData->EndStreamPos( nEndOffset );
233 : : }
234 : :
235 [ + - ]: 93 : if ( pSheetData )
236 : : {
237 : : // store the loaded namespaces (for the office:spreadsheet element),
238 : : // so the prefixes in copied stream fragments remain valid
239 : 93 : const SvXMLNamespaceMap& rNamespaces = GetImport().GetNamespaceMap();
240 [ + - ]: 93 : pSheetData->StoreLoadedNamespaces( rNamespaces );
241 : : }
242 : :
243 [ + + ]: 93 : if (!bHadCalculationSettings)
244 : : {
245 : : // #111055#; set calculation settings defaults if there is no calculation settings element
246 [ + - ][ + - ]: 89 : SvXMLImportContext *pContext = new ScXMLCalculationSettingsContext( GetScImport(), XML_NAMESPACE_TABLE, GetXMLToken(XML_CALCULATION_SETTINGS), NULL );
[ + - ][ + - ]
247 [ + - ]: 89 : pContext->EndElement();
248 : : }
249 : :
250 [ + - ]: 93 : ScXMLImport::MutexGuard aGuard(GetScImport());
251 : :
252 [ + - ]: 93 : ScMyImpDetectiveOpArray* pDetOpArray = GetScImport().GetDetectiveOpArray();
253 : 93 : ScDocument* pDoc = GetScImport().GetDocument();
254 : 93 : ScMyImpDetectiveOp aDetOp;
255 : :
256 [ + - ][ + - ]: 93 : if (pDoc && GetScImport().GetModel().is())
[ + - ]
257 : : {
258 [ + - ]: 93 : if (pDetOpArray)
259 : : {
260 [ + - ]: 93 : pDetOpArray->Sort();
261 [ + - ][ - + ]: 93 : while( pDetOpArray->GetFirstOp( aDetOp ) )
262 : : {
263 : 0 : ScDetOpData aOpData( aDetOp.aPosition, aDetOp.eOpType );
264 [ # # ]: 0 : pDoc->AddDetectiveOperation( aOpData );
265 : : }
266 : : }
267 : :
268 [ - + ]: 93 : if (pChangeTrackingImportHelper)
269 [ # # ]: 0 : pChangeTrackingImportHelper->CreateChangeTrack(GetScImport().GetDocument());
270 : :
271 : : // #i37959# handle document protection after the sheet settings
272 [ - + ]: 93 : if (bProtected)
273 : : {
274 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
275 [ # # ][ # # ]: 0 : ::std::auto_ptr<ScDocProtection> pProtection(new ScDocProtection);
276 : : SAL_WNODEPRECATED_DECLARATIONS_POP
277 [ # # ]: 0 : pProtection->setProtected(true);
278 : :
279 [ # # ]: 0 : uno::Sequence<sal_Int8> aPass;
280 [ # # ]: 0 : if (!sPassword.isEmpty())
281 : : {
282 [ # # ]: 0 : ::sax::Converter::decodeBase64(aPass, sPassword);
283 [ # # ]: 0 : pProtection->setPasswordHash(aPass, meHash1, meHash2);
284 : : }
285 : :
286 [ # # ][ # # ]: 0 : pDoc->SetDocProtection(pProtection.get());
[ # # ]
287 : : }
288 [ + - ]: 93 : }
289 : 93 : }
290 : :
291 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|