1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include "document.hxx"
24 #include "sheetdata.hxx"
26 #include "xmlbodyi.hxx"
27 #include "xmltabi.hxx"
28 #include "xmlnexpi.hxx"
29 #include "xmldrani.hxx"
30 #include "xmlimprt.hxx"
31 #include "xmldpimp.hxx"
32 #include "xmlcvali.hxx"
33 #include "xmlstyli.hxx"
34 #include "xmllabri.hxx"
35 #include "XMLConsolidationContext.hxx"
36 #include "XMLDDELinksContext.hxx"
37 #include "XMLCalculationSettingsContext.hxx"
38 #include "XMLTrackedChangesContext.hxx"
39 #include "XMLEmptyContext.hxx"
40 #include "XMLDetectiveContext.hxx"
41 #include "scerrors.hxx"
42 #include "tabprotection.hxx"
43 #include "datastreamimport.hxx"
45 #include <xmloff/xmltkmap.hxx>
46 #include <xmloff/xmltoken.hxx>
47 #include <xmloff/xmlnmspe.hxx>
48 #include <xmloff/nmspmap.hxx>
50 #include <sax/tools/converter.hxx>
51 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
52 #include <sal/types.h>
54 #include <boost/scoped_ptr.hpp>
56 using namespace com::sun::star
;
57 using namespace xmloff::token
;
59 ScXMLBodyContext::ScXMLBodyContext( ScXMLImport
& rImport
,
61 const OUString
& rLName
,
62 const uno::Reference
<xml::sax::XAttributeList
>& xAttrList
) :
63 SvXMLImportContext( rImport
, nPrfx
, rLName
),
65 meHash1(PASSHASH_SHA1
),
66 meHash2(PASSHASH_UNSPECIFIED
),
68 bHadCalculationSettings(false),
69 pChangeTrackingImportHelper(NULL
)
71 ScDocument
* pDoc
= GetScImport().GetDocument();
74 // ODF 1.1 and earlier => GRAM_PODF; ODF 1.2 and later => GRAM_ODFF;
75 // no version => earlier than 1.2 => GRAM_PODF.
76 formula::FormulaGrammar::Grammar eGrammar
= formula::FormulaGrammar::GRAM_ODFF
;
77 OUString
aVer( rImport
.GetODFVersion());
78 sal_Int32 nLen
= aVer
.getLength();
79 #if OSL_DEBUG_LEVEL > 1
80 fprintf( stderr
, "\n ScXMLBodyContext ODFVersion: nLen: %d, str: %s\n",
81 (int)nLen
, OUStringToOString( aVer
, RTL_TEXTENCODING_UTF8
).getStr());
84 eGrammar
= formula::FormulaGrammar::GRAM_PODF
;
87 // In case there was a micro version, e.g. "1.2.3", this would
88 // still yield major.minor, but pParsedEnd (5th parameter, not
89 // passed here) would point before string end upon return.
90 double fVer
= ::rtl::math::stringToDouble( aVer
, '.', 0, NULL
, NULL
);
92 eGrammar
= formula::FormulaGrammar::GRAM_PODF
;
94 pDoc
->SetStorageGrammar( eGrammar
);
97 sal_Int16 nAttrCount
= xAttrList
.is() ? xAttrList
->getLength() : 0;
98 for( sal_Int16 i
=0; i
< nAttrCount
; ++i
)
100 const OUString
& sAttrName(xAttrList
->getNameByIndex( i
));
102 sal_uInt16 nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName(
103 sAttrName
, &aLocalName
);
104 const OUString
& sValue(xAttrList
->getValueByIndex( i
));
106 if (nPrefix
== XML_NAMESPACE_TABLE
)
108 if (IsXMLToken(aLocalName
, XML_STRUCTURE_PROTECTED
))
109 bProtected
= IsXMLToken(sValue
, XML_TRUE
);
110 else if (IsXMLToken(aLocalName
, XML_PROTECTION_KEY
))
112 else if (IsXMLToken(aLocalName
, XML_PROTECTION_KEY_DIGEST_ALGORITHM
))
113 meHash1
= ScPassHashHelper::getHashTypeFromURI(sValue
);
114 else if (IsXMLToken(aLocalName
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
))
115 meHash2
= ScPassHashHelper::getHashTypeFromURI(sValue
);
117 else if(nPrefix
== XML_NAMESPACE_LO_EXT
)
119 if (IsXMLToken(aLocalName
, XML_PROTECTION_KEY_DIGEST_ALGORITHM_2
))
120 meHash2
= ScPassHashHelper::getHashTypeFromURI(sValue
);
125 ScXMLBodyContext::~ScXMLBodyContext()
129 SvXMLImportContext
*ScXMLBodyContext::CreateChildContext( sal_uInt16 nPrefix
,
130 const OUString
& rLocalName
,
131 const ::com::sun::star::uno::Reference
<
132 ::com::sun::star::xml::sax::XAttributeList
>& xAttrList
)
134 ScSheetSaveData
* pSheetData
= ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
135 if ( pSheetData
&& pSheetData
->HasStartPos() )
137 // stream part to copy ends before the next child element
138 sal_Int32 nEndOffset
= GetScImport().GetByteOffset();
139 pSheetData
->EndStreamPos( nEndOffset
);
142 SvXMLImportContext
*pContext
= 0;
144 const SvXMLTokenMap
& rTokenMap
= GetScImport().GetBodyElemTokenMap();
145 switch( rTokenMap
.Get( nPrefix
, rLocalName
) )
147 case XML_TOK_BODY_TRACKED_CHANGES
:
148 pChangeTrackingImportHelper
= GetScImport().GetChangeTrackingImportHelper();
149 if (pChangeTrackingImportHelper
)
150 pContext
= new ScXMLTrackedChangesContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
, pChangeTrackingImportHelper
);
152 case XML_TOK_BODY_CALCULATION_SETTINGS
:
153 pContext
= new ScXMLCalculationSettingsContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
);
154 bHadCalculationSettings
= true;
156 case XML_TOK_BODY_CONTENT_VALIDATIONS
:
157 pContext
= new ScXMLContentValidationsContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
);
159 case XML_TOK_BODY_LABEL_RANGES
:
160 pContext
= new ScXMLLabelRangesContext( GetScImport(), nPrefix
, rLocalName
, xAttrList
);
162 case XML_TOK_BODY_TABLE
:
163 if (GetScImport().GetTables().GetCurrentSheet() >= MAXTAB
)
165 GetScImport().SetRangeOverflowType(SCWARN_IMPORT_SHEET_OVERFLOW
);
166 pContext
= new ScXMLEmptyContext(GetScImport(), nPrefix
, rLocalName
);
170 pContext
= new ScXMLTableContext( GetScImport(),nPrefix
, rLocalName
,
174 case XML_TOK_BODY_NAMED_EXPRESSIONS
:
175 pContext
= new ScXMLNamedExpressionsContext (
176 GetScImport(), nPrefix
, rLocalName
, xAttrList
,
177 new ScXMLNamedExpressionsContext::GlobalInserter(GetScImport()) );
179 case XML_TOK_BODY_DATABASE_RANGES
:
180 pContext
= new ScXMLDatabaseRangesContext ( GetScImport(), nPrefix
, rLocalName
,
183 case XML_TOK_BODY_DATABASE_RANGE
:
184 pContext
= new ScXMLDatabaseRangeContext ( GetScImport(), nPrefix
, rLocalName
,
187 case XML_TOK_BODY_DATA_PILOT_TABLES
:
188 pContext
= new ScXMLDataPilotTablesContext ( GetScImport(), nPrefix
, rLocalName
,
191 case XML_TOK_BODY_CONSOLIDATION
:
192 pContext
= new ScXMLConsolidationContext ( GetScImport(), nPrefix
, rLocalName
,
195 case XML_TOK_BODY_DDE_LINKS
:
196 pContext
= new ScXMLDDELinksContext ( GetScImport(), nPrefix
, rLocalName
,
199 case XML_TOK_BODY_DATA_STREAM_SOURCE
:
200 pContext
= new ScXMLDataStreamContext(GetScImport(), nPrefix
, rLocalName
, xAttrList
);
205 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLocalName
);
210 void ScXMLBodyContext::Characters( const OUString
& )
212 ScSheetSaveData
* pSheetData
= ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
213 if ( pSheetData
&& pSheetData
->HasStartPos() )
215 // stream part to copy ends before any content (whitespace) within the spreadsheet element
216 sal_Int32 nEndOffset
= GetScImport().GetByteOffset();
217 pSheetData
->EndStreamPos( nEndOffset
);
222 void ScXMLBodyContext::EndElement()
224 ScSheetSaveData
* pSheetData
= ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
225 if ( pSheetData
&& pSheetData
->HasStartPos() )
227 // stream part to copy ends before the closing tag of spreadsheet element
228 sal_Int32 nEndOffset
= GetScImport().GetByteOffset();
229 pSheetData
->EndStreamPos( nEndOffset
);
234 // store the loaded namespaces (for the office:spreadsheet element),
235 // so the prefixes in copied stream fragments remain valid
236 const SvXMLNamespaceMap
& rNamespaces
= GetImport().GetNamespaceMap();
237 pSheetData
->StoreLoadedNamespaces( rNamespaces
);
240 if (!bHadCalculationSettings
)
242 // #111055#; set calculation settings defaults if there is no calculation settings element
243 ScXMLCalculationSettingsContext
aContext( GetScImport(), XML_NAMESPACE_TABLE
, GetXMLToken(XML_CALCULATION_SETTINGS
), NULL
);
244 aContext
.EndElement();
247 ScXMLImport::MutexGuard
aGuard(GetScImport());
249 ScMyImpDetectiveOpArray
* pDetOpArray
= GetScImport().GetDetectiveOpArray();
250 ScDocument
* pDoc
= GetScImport().GetDocument();
251 ScMyImpDetectiveOp aDetOp
;
253 if (pDoc
&& GetScImport().GetModel().is())
258 while( pDetOpArray
->GetFirstOp( aDetOp
) )
260 ScDetOpData
aOpData( aDetOp
.aPosition
, aDetOp
.eOpType
);
261 pDoc
->AddDetectiveOperation( aOpData
);
265 if (pChangeTrackingImportHelper
)
266 pChangeTrackingImportHelper
->CreateChangeTrack(GetScImport().GetDocument());
268 // #i37959# handle document protection after the sheet settings
271 boost::scoped_ptr
<ScDocProtection
> pProtection(new ScDocProtection
);
272 pProtection
->setProtected(true);
274 uno::Sequence
<sal_Int8
> aPass
;
275 if (!sPassword
.isEmpty())
277 ::sax::Converter::decodeBase64(aPass
, sPassword
);
278 pProtection
->setPasswordHash(aPass
, meHash1
, meHash2
);
281 pDoc
->SetDocProtection(pProtection
.get());
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */