Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <rtl/random.h>
21 : #include <sfx2/docfile.hxx>
22 : #include <sfx2/request.hxx>
23 : #include <sfx2/frame.hxx>
24 : #include <sfx2/sfxsids.hrc>
25 : #include <unotools/saveopt.hxx>
26 : #include <svl/itemset.hxx>
27 : #include <svl/stritem.hxx>
28 : #include <svl/intitem.hxx>
29 : #include <svl/eitem.hxx>
30 : #include "xecontent.hxx"
31 : #include "xltracer.hxx"
32 : #include "xeescher.hxx"
33 : #include "xeformula.hxx"
34 : #include "xehelper.hxx"
35 : #include "xelink.hxx"
36 : #include "xename.hxx"
37 : #include "xepivot.hxx"
38 : #include "xestyle.hxx"
39 : #include "xeroot.hxx"
40 : #include <xepivotxml.hxx>
41 :
42 : #include "excrecds.hxx"
43 : #include "tabprotection.hxx"
44 : #include "document.hxx"
45 : #include "scextopt.hxx"
46 :
47 : #include "formulabase.hxx"
48 : #include <com/sun/star/sheet/FormulaOpCodeMapEntry.hpp>
49 :
50 : using namespace ::com::sun::star;
51 :
52 : // Global data ================================================================
53 :
54 72 : XclExpRootData::XclExpRootData( XclBiff eBiff, SfxMedium& rMedium,
55 : tools::SvRef<SotStorage> xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) :
56 72 : XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, true )
57 : {
58 72 : SvtSaveOptions aSaveOpt;
59 72 : mbRelUrl = mrMedium.IsRemote() ? aSaveOpt.IsSaveRelINet() : aSaveOpt.IsSaveRelFSys();
60 72 : maStringBuf = OStringBuffer();
61 72 : }
62 :
63 72 : XclExpRootData::~XclExpRootData()
64 : {
65 72 : }
66 :
67 72 : XclExpRoot::XclExpRoot( XclExpRootData& rExpRootData ) :
68 : XclRoot( rExpRootData ),
69 72 : mrExpData( rExpRootData )
70 : {
71 72 : }
72 :
73 2140 : XclExpTabInfo& XclExpRoot::GetTabInfo() const
74 : {
75 : OSL_ENSURE( mrExpData.mxTabInfo, "XclExpRoot::GetTabInfo - missing object (wrong BIFF?)" );
76 2140 : return *mrExpData.mxTabInfo;
77 : }
78 :
79 579 : XclExpAddressConverter& XclExpRoot::GetAddressConverter() const
80 : {
81 : OSL_ENSURE( mrExpData.mxAddrConv, "XclExpRoot::GetAddressConverter - missing object (wrong BIFF?)" );
82 579 : return *mrExpData.mxAddrConv;
83 : }
84 :
85 2763 : XclExpFormulaCompiler& XclExpRoot::GetFormulaCompiler() const
86 : {
87 : OSL_ENSURE( mrExpData.mxFmlaComp, "XclExpRoot::GetFormulaCompiler - missing object (wrong BIFF?)" );
88 2763 : return *mrExpData.mxFmlaComp;
89 : }
90 :
91 2168 : XclExpProgressBar& XclExpRoot::GetProgressBar() const
92 : {
93 : OSL_ENSURE( mrExpData.mxProgress, "XclExpRoot::GetProgressBar - missing object (wrong BIFF?)" );
94 2168 : return *mrExpData.mxProgress;
95 : }
96 :
97 449 : XclExpSst& XclExpRoot::GetSst() const
98 : {
99 : OSL_ENSURE( mrExpData.mxSst, "XclExpRoot::GetSst - missing object (wrong BIFF?)" );
100 449 : return *mrExpData.mxSst;
101 : }
102 :
103 5289 : XclExpPalette& XclExpRoot::GetPalette() const
104 : {
105 : OSL_ENSURE( mrExpData.mxPalette, "XclExpRoot::GetPalette - missing object (wrong BIFF?)" );
106 5289 : return *mrExpData.mxPalette;
107 : }
108 :
109 1394 : XclExpFontBuffer& XclExpRoot::GetFontBuffer() const
110 : {
111 : OSL_ENSURE( mrExpData.mxFontBfr, "XclExpRoot::GetFontBuffer - missing object (wrong BIFF?)" );
112 1394 : return *mrExpData.mxFontBfr;
113 : }
114 :
115 1459 : XclExpNumFmtBuffer& XclExpRoot::GetNumFmtBuffer() const
116 : {
117 : OSL_ENSURE( mrExpData.mxNumFmtBfr, "XclExpRoot::GetNumFmtBuffer - missing object (wrong BIFF?)" );
118 1459 : return *mrExpData.mxNumFmtBfr;
119 : }
120 :
121 232345 : XclExpXFBuffer& XclExpRoot::GetXFBuffer() const
122 : {
123 : OSL_ENSURE( mrExpData.mxXFBfr, "XclExpRoot::GetXFBuffer - missing object (wrong BIFF?)" );
124 232345 : return *mrExpData.mxXFBfr;
125 : }
126 :
127 4 : XclExpLinkManager& XclExpRoot::GetGlobalLinkManager() const
128 : {
129 : OSL_ENSURE( mrExpData.mxGlobLinkMgr, "XclExpRoot::GetGlobalLinkManager - missing object (wrong BIFF?)" );
130 4 : return *mrExpData.mxGlobLinkMgr;
131 : }
132 :
133 574 : XclExpLinkManager& XclExpRoot::GetLocalLinkManager() const
134 : {
135 : OSL_ENSURE( GetLocalLinkMgrRef(), "XclExpRoot::GetLocalLinkManager - missing object (wrong BIFF?)" );
136 574 : return *GetLocalLinkMgrRef();
137 : }
138 :
139 379 : XclExpNameManager& XclExpRoot::GetNameManager() const
140 : {
141 : OSL_ENSURE( mrExpData.mxNameMgr, "XclExpRoot::GetNameManager - missing object (wrong BIFF?)" );
142 379 : return *mrExpData.mxNameMgr;
143 : }
144 :
145 408 : XclExpObjectManager& XclExpRoot::GetObjectManager() const
146 : {
147 : OSL_ENSURE( mrExpData.mxObjMgr, "XclExpRoot::GetObjectManager - missing object (wrong BIFF?)" );
148 408 : return *mrExpData.mxObjMgr;
149 : }
150 :
151 358 : XclExpFilterManager& XclExpRoot::GetFilterManager() const
152 : {
153 : OSL_ENSURE( mrExpData.mxFilterMgr, "XclExpRoot::GetFilterManager - missing object (wrong BIFF?)" );
154 358 : return *mrExpData.mxFilterMgr;
155 : }
156 :
157 10 : XclExpDxfs& XclExpRoot::GetDxfs() const
158 : {
159 : OSL_ENSURE( mrExpData.mxDxfs, "XclExpRoot::GetDxfs - missing object ( wrong BIFF?)" );
160 10 : return *mrExpData.mxDxfs;
161 : }
162 :
163 63 : XclExpPivotTableManager& XclExpRoot::GetPivotTableManager() const
164 : {
165 : OSL_ENSURE( mrExpData.mxPTableMgr, "XclExpRoot::GetPivotTableManager - missing object (wrong BIFF?)" );
166 63 : return *mrExpData.mxPTableMgr;
167 : }
168 :
169 210 : XclExpXmlPivotTableManager& XclExpRoot::GetXmlPivotTableManager()
170 : {
171 : assert(mrExpData.mxXmlPTableMgr);
172 210 : return *mrExpData.mxXmlPTableMgr;
173 : }
174 :
175 72 : void XclExpRoot::InitializeConvert()
176 : {
177 72 : mrExpData.mxTabInfo.reset( new XclExpTabInfo( GetRoot() ) );
178 72 : mrExpData.mxAddrConv.reset( new XclExpAddressConverter( GetRoot() ) );
179 72 : mrExpData.mxFmlaComp.reset( new XclExpFormulaCompiler( GetRoot() ) );
180 72 : mrExpData.mxProgress.reset( new XclExpProgressBar( GetRoot() ) );
181 :
182 72 : GetProgressBar().Initialize();
183 72 : }
184 :
185 72 : void XclExpRoot::InitializeGlobals()
186 : {
187 72 : SetCurrScTab( SCTAB_GLOBAL );
188 :
189 72 : if( GetBiff() >= EXC_BIFF5 )
190 : {
191 72 : mrExpData.mxPalette.reset( new XclExpPalette( GetRoot() ) );
192 72 : mrExpData.mxFontBfr.reset( new XclExpFontBuffer( GetRoot() ) );
193 72 : mrExpData.mxNumFmtBfr.reset( new XclExpNumFmtBuffer( GetRoot() ) );
194 72 : mrExpData.mxXFBfr.reset( new XclExpXFBuffer( GetRoot() ) );
195 72 : mrExpData.mxGlobLinkMgr.reset( new XclExpLinkManager( GetRoot() ) );
196 72 : mrExpData.mxNameMgr.reset( new XclExpNameManager( GetRoot() ) );
197 : }
198 :
199 72 : if( GetBiff() == EXC_BIFF8 )
200 : {
201 72 : mrExpData.mxSst.reset( new XclExpSst );
202 72 : mrExpData.mxObjMgr.reset( new XclExpObjectManager( GetRoot() ) );
203 72 : mrExpData.mxFilterMgr.reset( new XclExpFilterManager( GetRoot() ) );
204 72 : mrExpData.mxPTableMgr.reset( new XclExpPivotTableManager( GetRoot() ) );
205 : // BIFF8: only one link manager for all sheets
206 72 : mrExpData.mxLocLinkMgr = mrExpData.mxGlobLinkMgr;
207 72 : mrExpData.mxDxfs.reset( new XclExpDxfs( GetRoot() ) );
208 : }
209 :
210 72 : if( GetOutput() == EXC_OUTPUT_XML_2007 )
211 : {
212 55 : mrExpData.mxXmlPTableMgr.reset(new XclExpXmlPivotTableManager(GetRoot()));
213 :
214 : do
215 : {
216 55 : ScDocument& rDoc = GetDoc();
217 : // Pass the model factory to OpCodeProvider, not the process
218 : // service factory, otherwise a FormulaOpCodeMapperObj would be
219 : // instantiated instead of a ScFormulaOpCodeMapperObj and the
220 : // ScCompiler virtuals not be called! Which would be the case with
221 : // the current (2013-01-24) rDoc.GetServiceManager()
222 55 : const SfxObjectShell* pShell = rDoc.GetDocumentShell();
223 55 : if (!pShell)
224 : {
225 : SAL_WARN( "sc", "XclExpRoot::InitializeGlobals - no object shell");
226 0 : break;
227 : }
228 55 : uno::Reference< lang::XComponent > xComponent( pShell->GetModel(), uno::UNO_QUERY);
229 55 : if (!xComponent.is())
230 : {
231 : SAL_WARN( "sc", "XclExpRoot::InitializeGlobals - no component");
232 0 : break;
233 : }
234 110 : uno::Reference< lang::XMultiServiceFactory > xModelFactory( xComponent, uno::UNO_QUERY);
235 : // OOXML is also BIFF8 function-wise
236 : oox::xls::OpCodeProvider aOpCodeProvider( xModelFactory,
237 110 : oox::xls::FILTER_OOXML, oox::xls::BIFF8, false, true);
238 : // Compiler mocks about non-matching ctor or conversion from
239 : // Sequence<...> to Sequence<const ...> if directly created or passed,
240 : // conversion through Any works around.
241 110 : uno::Any aAny( aOpCodeProvider.getOoxParserMap());
242 110 : uno::Sequence< const sheet::FormulaOpCodeMapEntry > aOpCodeMapping;
243 55 : if (!(aAny >>= aOpCodeMapping))
244 : {
245 : SAL_WARN( "sc", "XclExpRoot::InitializeGlobals - no OpCodeMap");
246 0 : break;
247 : }
248 110 : ScCompiler aCompiler( &rDoc, ScAddress());
249 55 : aCompiler.SetGrammar( rDoc.GetGrammar());
250 110 : mrExpData.mxOpCodeMap = formula::FormulaCompiler::CreateOpCodeMap( aOpCodeMapping, true);
251 : } while(false);
252 : }
253 :
254 72 : GetXFBuffer().Initialize();
255 72 : GetNameManager().Initialize();
256 72 : }
257 :
258 129 : void XclExpRoot::InitializeTable( SCTAB nScTab )
259 : {
260 129 : SetCurrScTab( nScTab );
261 129 : if( GetBiff() == EXC_BIFF5 )
262 : {
263 : // local link manager per sheet
264 0 : mrExpData.mxLocLinkMgr.reset( new XclExpLinkManager( GetRoot() ) );
265 : }
266 129 : }
267 :
268 72 : void XclExpRoot::InitializeSave()
269 : {
270 72 : GetPalette().Finalize();
271 72 : GetXFBuffer().Finalize();
272 72 : }
273 :
274 559 : XclExpRecordRef XclExpRoot::CreateRecord( sal_uInt16 nRecId ) const
275 : {
276 559 : XclExpRecordRef xRec;
277 559 : switch( nRecId )
278 : {
279 72 : case EXC_ID_PALETTE: xRec = mrExpData.mxPalette; break;
280 72 : case EXC_ID_FONTLIST: xRec = mrExpData.mxFontBfr; break;
281 72 : case EXC_ID_FORMATLIST: xRec = mrExpData.mxNumFmtBfr; break;
282 72 : case EXC_ID_XFLIST: xRec = mrExpData.mxXFBfr; break;
283 72 : case EXC_ID_SST: xRec = mrExpData.mxSst; break;
284 72 : case EXC_ID_EXTERNSHEET: xRec = GetLocalLinkMgrRef(); break;
285 72 : case EXC_ID_NAME: xRec = mrExpData.mxNameMgr; break;
286 55 : case EXC_ID_DXFS: xRec = mrExpData.mxDxfs; break;
287 : }
288 : OSL_ENSURE( xRec, "XclExpRoot::CreateRecord - unknown record ID or missing object" );
289 559 : return xRec;
290 : }
291 :
292 17 : bool XclExpRoot::IsDocumentEncrypted() const
293 : {
294 : // We need to encrypt the content when the document structure is protected.
295 17 : const ScDocProtection* pDocProt = GetDoc().GetDocProtection();
296 17 : if (pDocProt && pDocProt->isProtected() && pDocProt->isOptionEnabled(ScDocProtection::STRUCTURE))
297 0 : return true;
298 :
299 17 : if ( GetEncryptionData().getLength() > 0 )
300 : // Password is entered directly into the save dialog.
301 0 : return true;
302 :
303 17 : return false;
304 : }
305 :
306 0 : uno::Sequence< beans::NamedValue > XclExpRoot::GenerateEncryptionData( const OUString& aPass )
307 : {
308 0 : uno::Sequence< beans::NamedValue > aEncryptionData;
309 :
310 0 : if ( !aPass.isEmpty() && aPass.getLength() < 16 )
311 : {
312 : TimeValue aTime;
313 0 : osl_getSystemTime( &aTime );
314 0 : rtlRandomPool aRandomPool = rtl_random_createPool ();
315 0 : rtl_random_addBytes ( aRandomPool, &aTime, 8 );
316 :
317 : sal_uInt8 pnDocId[16];
318 0 : rtl_random_getBytes( aRandomPool, pnDocId, 16 );
319 :
320 0 : rtl_random_destroyPool( aRandomPool );
321 :
322 : sal_uInt16 pnPasswd[16];
323 0 : memset( pnPasswd, 0, sizeof( pnPasswd ) );
324 0 : for( sal_Int32 nChar = 0; nChar < aPass.getLength(); ++nChar )
325 0 : pnPasswd[nChar] = aPass[nChar];
326 :
327 0 : ::msfilter::MSCodec_Std97 aCodec;
328 0 : aCodec.InitKey( pnPasswd, pnDocId );
329 0 : aEncryptionData = aCodec.GetEncryptionData();
330 : }
331 :
332 0 : return aEncryptionData;
333 : }
334 :
335 17 : uno::Sequence< beans::NamedValue > XclExpRoot::GetEncryptionData() const
336 : {
337 17 : uno::Sequence< beans::NamedValue > aEncryptionData;
338 17 : SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, false );
339 17 : if ( pEncryptionDataItem )
340 0 : pEncryptionDataItem->GetValue() >>= aEncryptionData;
341 : else
342 : {
343 : // try to get the encryption data from the password
344 17 : SFX_ITEMSET_ARG( GetMedium().GetItemSet(), pPasswordItem, SfxStringItem, SID_PASSWORD, false );
345 17 : if ( pPasswordItem && !pPasswordItem->GetValue().isEmpty() )
346 0 : aEncryptionData = GenerateEncryptionData( pPasswordItem->GetValue() );
347 : }
348 :
349 17 : return aEncryptionData;
350 : }
351 :
352 0 : uno::Sequence< beans::NamedValue > XclExpRoot::GenerateDefaultEncryptionData() const
353 : {
354 0 : uno::Sequence< beans::NamedValue > aEncryptionData;
355 0 : if ( !GetDefaultPassword().isEmpty() )
356 0 : aEncryptionData = GenerateEncryptionData( GetDefaultPassword() );
357 :
358 0 : return aEncryptionData;
359 : }
360 :
361 646 : XclExpRootData::XclExpLinkMgrRef XclExpRoot::GetLocalLinkMgrRef() const
362 : {
363 646 : return IsInGlobals() ? mrExpData.mxGlobLinkMgr : mrExpData.mxLocLinkMgr;
364 30 : }
365 :
366 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|