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 <stdarg.h>
21 : #include <stdio.h>
22 : #include <string.h>
23 : #include <utility>
24 :
25 : #include <rtl/ustring.hxx>
26 : #include <rtl/ustrbuf.hxx>
27 : #include <rtl/random.h>
28 : #include <sax/fshelper.hxx>
29 : #include <unotools/streamwrap.hxx>
30 :
31 : #include "docuno.hxx"
32 : #include "xestream.hxx"
33 : #include "xladdress.hxx"
34 : #include "xlstring.hxx"
35 : #include "xeroot.hxx"
36 : #include "xestyle.hxx"
37 : #include "xcl97rec.hxx"
38 : #include "rangelst.hxx"
39 : #include "compiler.hxx"
40 : #include "formulacell.hxx"
41 : #include "tokenarray.hxx"
42 : #include "tokenstringcontext.hxx"
43 : #include "refreshtimerprotector.hxx"
44 : #include "globstr.hrc"
45 :
46 : #include <../../ui/inc/docsh.hxx>
47 : #include <../../ui/inc/viewdata.hxx>
48 : #include <excdoc.hxx>
49 :
50 : #include <oox/token/tokens.hxx>
51 : #include <formula/grammar.hxx>
52 : #include <oox/export/drawingml.hxx>
53 : #include <excelvbaproject.hxx>
54 :
55 : #include <sfx2/docfile.hxx>
56 : #include <sfx2/objsh.hxx>
57 : #include <sfx2/app.hxx>
58 :
59 : #include <com/sun/star/task/XStatusIndicator.hpp>
60 : #include <boost/scoped_array.hpp>
61 :
62 : #define DEBUG_XL_ENCRYPTION 0
63 :
64 : using ::com::sun::star::embed::XStorage;
65 : using ::com::sun::star::lang::XSingleServiceFactory;
66 : using ::com::sun::star::registry::InvalidRegistryException;
67 : using ::com::sun::star::registry::XRegistryKey;
68 : using ::com::sun::star::uno::Exception;
69 : using ::com::sun::star::uno::XInterface;
70 : using ::utl::OStreamWrapper;
71 : using ::std::vector;
72 :
73 : using namespace com::sun::star;
74 : using namespace ::com::sun::star::beans;
75 : using namespace ::com::sun::star::io;
76 : using namespace ::com::sun::star::lang;
77 : using namespace ::com::sun::star::sheet;
78 : using namespace ::com::sun::star::uno;
79 : using namespace ::formula;
80 : using namespace ::oox;
81 :
82 44 : XclExpStream::XclExpStream( SvStream& rOutStrm, const XclExpRoot& rRoot, sal_uInt16 nMaxRecSize ) :
83 : mrStrm( rOutStrm ),
84 : mrRoot( rRoot ),
85 : mbUseEncrypter( false ),
86 : mnMaxRecSize( nMaxRecSize ),
87 : mnCurrMaxSize( 0 ),
88 : mnMaxSliceSize( 0 ),
89 : mnHeaderSize( 0 ),
90 : mnCurrSize( 0 ),
91 : mnSliceSize( 0 ),
92 : mnPredictSize( 0 ),
93 : mnLastSizePos( 0 ),
94 44 : mbInRec( false )
95 : {
96 44 : if( mnMaxRecSize == 0 )
97 42 : mnMaxRecSize = (mrRoot.GetBiff() <= EXC_BIFF5) ? EXC_MAXRECSIZE_BIFF5 : EXC_MAXRECSIZE_BIFF8;
98 44 : mnMaxContSize = mnMaxRecSize;
99 44 : }
100 :
101 88 : XclExpStream::~XclExpStream()
102 : {
103 44 : mrStrm.Flush();
104 44 : }
105 :
106 6754 : void XclExpStream::StartRecord( sal_uInt16 nRecId, sal_Size nRecSize )
107 : {
108 : OSL_ENSURE( !mbInRec, "XclExpStream::StartRecord - another record still open" );
109 6754 : DisableEncryption();
110 6754 : mnMaxContSize = mnCurrMaxSize = mnMaxRecSize;
111 6754 : mnPredictSize = nRecSize;
112 6754 : mbInRec = true;
113 6754 : InitRecord( nRecId );
114 6754 : SetSliceSize( 0 );
115 6754 : EnableEncryption();
116 6754 : }
117 :
118 6754 : void XclExpStream::EndRecord()
119 : {
120 : OSL_ENSURE( mbInRec, "XclExpStream::EndRecord - no record open" );
121 6754 : DisableEncryption();
122 6754 : UpdateRecSize();
123 6754 : mrStrm.Seek( STREAM_SEEK_TO_END );
124 6754 : mbInRec = false;
125 6754 : }
126 :
127 8890 : void XclExpStream::SetSliceSize( sal_uInt16 nSize )
128 : {
129 8890 : mnMaxSliceSize = nSize;
130 8890 : mnSliceSize = 0;
131 8890 : }
132 :
133 0 : XclExpStream& XclExpStream::operator<<( sal_Int8 nValue )
134 : {
135 0 : PrepareWrite( 1 );
136 0 : if (mbUseEncrypter && HasValidEncrypter())
137 0 : mxEncrypter->Encrypt(mrStrm, nValue);
138 : else
139 0 : mrStrm.WriteSChar( nValue );
140 0 : return *this;
141 : }
142 :
143 14630 : XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
144 : {
145 14630 : PrepareWrite( 1 );
146 14630 : if (mbUseEncrypter && HasValidEncrypter())
147 0 : mxEncrypter->Encrypt(mrStrm, nValue);
148 : else
149 14630 : mrStrm.WriteUChar( nValue );
150 14630 : return *this;
151 : }
152 :
153 60 : XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
154 : {
155 60 : PrepareWrite( 2 );
156 60 : if (mbUseEncrypter && HasValidEncrypter())
157 0 : mxEncrypter->Encrypt(mrStrm, nValue);
158 : else
159 60 : mrStrm.WriteInt16( nValue );
160 60 : return *this;
161 : }
162 :
163 24576 : XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
164 : {
165 24576 : PrepareWrite( 2 );
166 24576 : if (mbUseEncrypter && HasValidEncrypter())
167 0 : mxEncrypter->Encrypt(mrStrm, nValue);
168 : else
169 24576 : mrStrm.WriteUInt16( nValue );
170 24576 : return *this;
171 : }
172 :
173 728 : XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
174 : {
175 728 : PrepareWrite( 4 );
176 728 : if (mbUseEncrypter && HasValidEncrypter())
177 0 : mxEncrypter->Encrypt(mrStrm, nValue);
178 : else
179 728 : mrStrm.WriteInt32( nValue );
180 728 : return *this;
181 : }
182 :
183 4002 : XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
184 : {
185 4002 : PrepareWrite( 4 );
186 4002 : if (mbUseEncrypter && HasValidEncrypter())
187 0 : mxEncrypter->Encrypt(mrStrm, nValue);
188 : else
189 4002 : mrStrm.WriteUInt32( nValue );
190 4002 : return *this;
191 : }
192 :
193 0 : XclExpStream& XclExpStream::operator<<( float fValue )
194 : {
195 0 : PrepareWrite( 4 );
196 0 : if (mbUseEncrypter && HasValidEncrypter())
197 0 : mxEncrypter->Encrypt(mrStrm, fValue);
198 : else
199 0 : mrStrm.WriteFloat( fValue );
200 0 : return *this;
201 : }
202 :
203 1754 : XclExpStream& XclExpStream::operator<<( double fValue )
204 : {
205 1754 : PrepareWrite( 8 );
206 1754 : if (mbUseEncrypter && HasValidEncrypter())
207 0 : mxEncrypter->Encrypt(mrStrm, fValue);
208 : else
209 1754 : mrStrm.WriteDouble( fValue );
210 1754 : return *this;
211 : }
212 :
213 1530 : sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
214 : {
215 1530 : sal_Size nRet = 0;
216 1530 : if( pData && (nBytes > 0) )
217 : {
218 1530 : if( mbInRec )
219 : {
220 1530 : const sal_uInt8* pBuffer = reinterpret_cast< const sal_uInt8* >( pData );
221 1530 : sal_Size nBytesLeft = nBytes;
222 1530 : bool bValid = true;
223 :
224 4592 : while( bValid && (nBytesLeft > 0) )
225 : {
226 1532 : sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
227 1532 : sal_Size nWriteRet = nWriteLen;
228 1532 : if (mbUseEncrypter && HasValidEncrypter())
229 : {
230 : OSL_ENSURE(nWriteLen > 0, "XclExpStream::Write: write length is 0!");
231 0 : vector<sal_uInt8> aBytes(nWriteLen);
232 0 : memcpy(&aBytes[0], pBuffer, nWriteLen);
233 0 : mxEncrypter->EncryptBytes(mrStrm, aBytes);
234 : // TODO: How do I check if all the bytes have been successfully written ?
235 : }
236 : else
237 : {
238 1532 : nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
239 1532 : bValid = (nWriteLen == nWriteRet);
240 : OSL_ENSURE( bValid, "XclExpStream::Write - stream write error" );
241 : }
242 1532 : pBuffer += nWriteRet;
243 1532 : nRet += nWriteRet;
244 1532 : nBytesLeft -= nWriteRet;
245 1532 : UpdateSizeVars( nWriteRet );
246 : }
247 : }
248 : else
249 0 : nRet = mrStrm.Write( pData, nBytes );
250 : }
251 1530 : return nRet;
252 : }
253 :
254 56 : void XclExpStream::WriteZeroBytes( sal_Size nBytes )
255 : {
256 56 : if( mbInRec )
257 : {
258 56 : sal_Size nBytesLeft = nBytes;
259 168 : while( nBytesLeft > 0 )
260 : {
261 56 : sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
262 56 : WriteRawZeroBytes( nWriteLen );
263 56 : nBytesLeft -= nWriteLen;
264 56 : UpdateSizeVars( nWriteLen );
265 : }
266 : }
267 : else
268 0 : WriteRawZeroBytes( nBytes );
269 56 : }
270 :
271 0 : void XclExpStream::WriteZeroBytesToRecord( sal_Size nBytes )
272 : {
273 0 : if (!mbInRec)
274 : // not in record.
275 0 : return;
276 :
277 0 : sal_uInt8 nZero = 0;
278 0 : for (sal_Size i = 0; i < nBytes; ++i)
279 0 : *this << nZero;
280 : }
281 :
282 110 : void XclExpStream::CopyFromStream(SvStream& rInStrm, sal_uInt64 const nBytes)
283 : {
284 110 : sal_uInt64 const nRemaining(rInStrm.remainingSize());
285 110 : sal_uInt64 nBytesLeft = ::std::min(nBytes, nRemaining);
286 110 : if( nBytesLeft > 0 )
287 : {
288 96 : const sal_Size nMaxBuffer = 4096;
289 : boost::scoped_array<sal_uInt8> pBuffer(
290 96 : new sal_uInt8[ ::std::min<sal_Size>(nBytesLeft, nMaxBuffer) ]);
291 96 : bool bValid = true;
292 :
293 292 : while( bValid && (nBytesLeft > 0) )
294 : {
295 100 : sal_Size nWriteLen = ::std::min<sal_Size>(nBytesLeft, nMaxBuffer);
296 100 : rInStrm.Read( pBuffer.get(), nWriteLen );
297 100 : sal_Size nWriteRet = Write( pBuffer.get(), nWriteLen );
298 100 : bValid = (nWriteLen == nWriteRet);
299 100 : nBytesLeft -= nWriteRet;
300 96 : }
301 : }
302 110 : }
303 :
304 666 : void XclExpStream::WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags )
305 : {
306 666 : SetSliceSize( 0 );
307 666 : nFlags &= EXC_STRF_16BIT; // repeat only 16bit flag
308 666 : sal_uInt16 nCharLen = nFlags ? 2 : 1;
309 :
310 666 : ScfUInt16Vec::const_iterator aEnd = rBuffer.end();
311 8654 : for( ScfUInt16Vec::const_iterator aIter = rBuffer.begin(); aIter != aEnd; ++aIter )
312 : {
313 7988 : if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
314 : {
315 0 : StartContinue();
316 0 : operator<<( nFlags );
317 : }
318 7988 : if( nCharLen == 2 )
319 682 : operator<<( *aIter );
320 : else
321 7306 : operator<<( static_cast< sal_uInt8 >( *aIter ) );
322 : }
323 666 : }
324 :
325 : // Xcl has an obscure sense of whether starting a new record or not,
326 : // and crashes if it encounters the string header at the very end of a record.
327 : // Thus we add 1 to give some room, seems like they do it that way but with another count (10?)
328 0 : void XclExpStream::WriteByteString( const OString& rString, sal_uInt16 nMaxLen, bool b16BitCount )
329 : {
330 0 : SetSliceSize( 0 );
331 0 : sal_Size nLen = ::std::min< sal_Size >( rString.getLength(), nMaxLen );
332 0 : if( !b16BitCount )
333 0 : nLen = ::std::min< sal_Size >( nLen, 0xFF );
334 :
335 0 : sal_uInt16 nLeft = PrepareWrite();
336 0 : sal_uInt16 nLenFieldSize = b16BitCount ? 2 : 1;
337 0 : if( mbInRec && (nLeft <= nLenFieldSize) )
338 0 : StartContinue();
339 :
340 0 : if( b16BitCount )
341 0 : operator<<( static_cast< sal_uInt16 >( nLen ) );
342 : else
343 0 : operator<<( static_cast< sal_uInt8 >( nLen ) );
344 0 : Write( rString.getStr(), nLen );
345 0 : }
346 :
347 0 : void XclExpStream::WriteCharBuffer( const ScfUInt8Vec& rBuffer )
348 : {
349 0 : SetSliceSize( 0 );
350 0 : Write( &rBuffer[ 0 ], rBuffer.size() );
351 0 : }
352 :
353 0 : void XclExpStream::SetEncrypter( XclExpEncrypterRef xEncrypter )
354 : {
355 0 : mxEncrypter = xEncrypter;
356 0 : }
357 :
358 6912 : bool XclExpStream::HasValidEncrypter() const
359 : {
360 6912 : return mxEncrypter && mxEncrypter->IsValid();
361 : }
362 :
363 20622 : void XclExpStream::EnableEncryption( bool bEnable )
364 : {
365 20622 : mbUseEncrypter = bEnable && HasValidEncrypter();
366 20622 : }
367 :
368 13710 : void XclExpStream::DisableEncryption()
369 : {
370 13710 : EnableEncryption(false);
371 13710 : }
372 :
373 50 : sal_uInt64 XclExpStream::SetSvStreamPos(sal_uInt64 const nPos)
374 : {
375 : OSL_ENSURE( !mbInRec, "XclExpStream::SetSvStreamPos - not allowed inside of a record" );
376 50 : return mbInRec ? 0 : mrStrm.Seek( nPos );
377 : }
378 :
379 : // private --------------------------------------------------------------------
380 :
381 6756 : void XclExpStream::InitRecord( sal_uInt16 nRecId )
382 : {
383 6756 : mrStrm.Seek( STREAM_SEEK_TO_END );
384 6756 : mrStrm.WriteUInt16( nRecId );
385 :
386 6756 : mnLastSizePos = mrStrm.Tell();
387 6756 : mnHeaderSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( mnPredictSize, mnCurrMaxSize ) );
388 6756 : mrStrm.WriteUInt16( mnHeaderSize );
389 6756 : mnCurrSize = mnSliceSize = 0;
390 6756 : }
391 :
392 6756 : void XclExpStream::UpdateRecSize()
393 : {
394 6756 : if( mnCurrSize != mnHeaderSize )
395 : {
396 324 : mrStrm.Seek( mnLastSizePos );
397 324 : mrStrm.WriteUInt16( mnCurrSize );
398 : }
399 6756 : }
400 :
401 48876 : void XclExpStream::UpdateSizeVars( sal_Size nSize )
402 : {
403 : OSL_ENSURE( mnCurrSize + nSize <= mnCurrMaxSize, "XclExpStream::UpdateSizeVars - record overwritten" );
404 48876 : mnCurrSize = mnCurrSize + static_cast< sal_uInt16 >( nSize );
405 :
406 48876 : if( mnMaxSliceSize > 0 )
407 : {
408 : OSL_ENSURE( mnSliceSize + nSize <= mnMaxSliceSize, "XclExpStream::UpdateSizeVars - slice overwritten" );
409 1924 : mnSliceSize = mnSliceSize + static_cast< sal_uInt16 >( nSize );
410 1924 : if( mnSliceSize >= mnMaxSliceSize )
411 102 : mnSliceSize = 0;
412 : }
413 48876 : }
414 :
415 2 : void XclExpStream::StartContinue()
416 : {
417 2 : UpdateRecSize();
418 2 : mnCurrMaxSize = mnMaxContSize;
419 2 : mnPredictSize -= mnCurrSize;
420 2 : InitRecord( EXC_ID_CONT );
421 2 : }
422 :
423 45750 : void XclExpStream::PrepareWrite( sal_uInt16 nSize )
424 : {
425 45750 : if( mbInRec )
426 : {
427 91400 : if( (mnCurrSize + nSize > mnCurrMaxSize) ||
428 47624 : ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
429 0 : StartContinue();
430 45700 : UpdateSizeVars( nSize );
431 : }
432 45750 : }
433 :
434 1588 : sal_uInt16 XclExpStream::PrepareWrite()
435 : {
436 1588 : sal_uInt16 nRet = 0;
437 1588 : if( mbInRec )
438 : {
439 3174 : if( (mnCurrSize >= mnCurrMaxSize) ||
440 1586 : ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
441 2 : StartContinue();
442 1588 : UpdateSizeVars( 0 );
443 :
444 1588 : nRet = (mnMaxSliceSize > 0) ? (mnMaxSliceSize - mnSliceSize) : (mnCurrMaxSize - mnCurrSize);
445 : }
446 1588 : return nRet;
447 : }
448 :
449 56 : void XclExpStream::WriteRawZeroBytes( sal_Size nBytes )
450 : {
451 56 : const sal_uInt32 nData = 0;
452 56 : sal_Size nBytesLeft = nBytes;
453 800 : while( nBytesLeft >= sizeof( nData ) )
454 : {
455 688 : mrStrm.WriteUInt32( nData );
456 688 : nBytesLeft -= sizeof( nData );
457 : }
458 56 : if( nBytesLeft )
459 10 : mrStrm.Write( &nData, nBytesLeft );
460 56 : }
461 :
462 0 : XclExpBiff8Encrypter::XclExpBiff8Encrypter( const XclExpRoot& rRoot ) :
463 : mnOldPos(STREAM_SEEK_TO_END),
464 0 : mbValid(false)
465 : {
466 0 : Sequence< NamedValue > aEncryptionData = rRoot.GetEncryptionData();
467 0 : if( !aEncryptionData.hasElements() )
468 : // Empty password. Get the default biff8 password.
469 0 : aEncryptionData = rRoot.GenerateDefaultEncryptionData();
470 0 : Init( aEncryptionData );
471 0 : }
472 :
473 0 : XclExpBiff8Encrypter::~XclExpBiff8Encrypter()
474 : {
475 0 : }
476 :
477 0 : void XclExpBiff8Encrypter::GetSaltDigest( sal_uInt8 pnSaltDigest[16] ) const
478 : {
479 : if ( sizeof( mpnSaltDigest ) == 16 )
480 0 : memcpy( pnSaltDigest, mpnSaltDigest, 16 );
481 0 : }
482 :
483 0 : void XclExpBiff8Encrypter::GetSalt( sal_uInt8 pnSalt[16] ) const
484 : {
485 : if ( sizeof( mpnSalt ) == 16 )
486 0 : memcpy( pnSalt, mpnSalt, 16 );
487 0 : }
488 :
489 0 : void XclExpBiff8Encrypter::GetDocId( sal_uInt8 pnDocId[16] ) const
490 : {
491 : if ( sizeof( mpnDocId ) == 16 )
492 0 : memcpy( pnDocId, mpnDocId, 16 );
493 0 : }
494 :
495 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt8 nData )
496 : {
497 0 : vector<sal_uInt8> aByte(1);
498 0 : aByte[0] = nData;
499 0 : EncryptBytes(rStrm, aByte);
500 0 : }
501 :
502 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt16 nData )
503 : {
504 0 : ::std::vector<sal_uInt8> pnBytes(2);
505 0 : pnBytes[0] = nData & 0xFF;
506 0 : pnBytes[1] = (nData >> 8) & 0xFF;
507 0 : EncryptBytes(rStrm, pnBytes);
508 0 : }
509 :
510 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_uInt32 nData )
511 : {
512 0 : ::std::vector<sal_uInt8> pnBytes(4);
513 0 : pnBytes[0] = nData & 0xFF;
514 0 : pnBytes[1] = (nData >> 8) & 0xFF;
515 0 : pnBytes[2] = (nData >> 16) & 0xFF;
516 0 : pnBytes[3] = (nData >> 24) & 0xFF;
517 0 : EncryptBytes(rStrm, pnBytes);
518 0 : }
519 :
520 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, float fValue )
521 : {
522 0 : ::std::vector<sal_uInt8> pnBytes(4);
523 0 : memcpy(&pnBytes[0], &fValue, 4);
524 0 : EncryptBytes(rStrm, pnBytes);
525 0 : }
526 :
527 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, double fValue )
528 : {
529 0 : ::std::vector<sal_uInt8> pnBytes(8);
530 0 : memcpy(&pnBytes[0], &fValue, 8);
531 0 : EncryptBytes(rStrm, pnBytes);
532 0 : }
533 :
534 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int8 nData )
535 : {
536 0 : Encrypt(rStrm, static_cast<sal_uInt8>(nData));
537 0 : }
538 :
539 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int16 nData )
540 : {
541 0 : Encrypt(rStrm, static_cast<sal_uInt16>(nData));
542 0 : }
543 :
544 0 : void XclExpBiff8Encrypter::Encrypt( SvStream& rStrm, sal_Int32 nData )
545 : {
546 0 : Encrypt(rStrm, static_cast<sal_uInt32>(nData));
547 0 : }
548 :
549 0 : void XclExpBiff8Encrypter::Init( const Sequence< NamedValue >& rEncryptionData )
550 : {
551 0 : mbValid = false;
552 :
553 0 : if( maCodec.InitCodec( rEncryptionData ) )
554 : {
555 0 : maCodec.GetDocId( mpnDocId );
556 :
557 : // generate the salt here
558 : TimeValue aTime;
559 0 : osl_getSystemTime( &aTime );
560 0 : rtlRandomPool aRandomPool = rtl_random_createPool ();
561 0 : rtl_random_addBytes( aRandomPool, &aTime, 8 );
562 0 : rtl_random_getBytes( aRandomPool, mpnSalt, 16 );
563 0 : rtl_random_destroyPool( aRandomPool );
564 :
565 0 : memset( mpnSaltDigest, 0, sizeof( mpnSaltDigest ) );
566 :
567 : // generate salt hash.
568 0 : ::msfilter::MSCodec_Std97 aCodec;
569 0 : aCodec.InitCodec( rEncryptionData );
570 0 : aCodec.CreateSaltDigest( mpnSalt, mpnSaltDigest );
571 :
572 : // verify to make sure it's in good shape.
573 0 : mbValid = maCodec.VerifyKey( mpnSalt, mpnSaltDigest );
574 : }
575 0 : }
576 :
577 0 : sal_uInt32 XclExpBiff8Encrypter::GetBlockPos( sal_Size nStrmPos ) const
578 : {
579 0 : return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
580 : }
581 :
582 0 : sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( sal_Size nStrmPos ) const
583 : {
584 0 : return static_cast< sal_uInt16 >( nStrmPos % EXC_ENCR_BLOCKSIZE );
585 : }
586 :
587 0 : void XclExpBiff8Encrypter::EncryptBytes( SvStream& rStrm, vector<sal_uInt8>& aBytes )
588 : {
589 0 : sal_uInt64 nStrmPos = rStrm.Tell();
590 0 : sal_uInt16 nBlockOffset = GetOffsetInBlock(nStrmPos);
591 0 : sal_uInt32 nBlockPos = GetBlockPos(nStrmPos);
592 :
593 : #if DEBUG_XL_ENCRYPTION
594 : fprintf(stdout, "XclExpBiff8Encrypter::EncryptBytes: stream pos = %ld offset in block = %d block pos = %ld\n",
595 : nStrmPos, nBlockOffset, nBlockPos);
596 : #endif
597 :
598 0 : sal_uInt16 nSize = static_cast< sal_uInt16 >( aBytes.size() );
599 0 : if (nSize == 0)
600 0 : return;
601 :
602 : #if DEBUG_XL_ENCRYPTION
603 : fprintf(stdout, "RAW: ");
604 : for (sal_uInt16 i = 0; i < nSize; ++i)
605 : fprintf(stdout, "%2.2X ", aBytes[i]);
606 : fprintf(stdout, "\n");
607 : #endif
608 :
609 0 : if (mnOldPos != nStrmPos)
610 : {
611 0 : sal_uInt16 nOldOffset = GetOffsetInBlock(mnOldPos);
612 0 : sal_uInt32 nOldBlockPos = GetBlockPos(mnOldPos);
613 :
614 0 : if ( (nBlockPos != nOldBlockPos) || (nBlockOffset < nOldOffset) )
615 : {
616 0 : maCodec.InitCipher(nBlockPos);
617 0 : nOldOffset = 0;
618 : }
619 :
620 0 : if (nBlockOffset > nOldOffset)
621 0 : maCodec.Skip(nBlockOffset - nOldOffset);
622 : }
623 :
624 0 : sal_uInt16 nBytesLeft = nSize;
625 0 : sal_uInt16 nPos = 0;
626 0 : while (nBytesLeft > 0)
627 : {
628 0 : sal_uInt16 nBlockLeft = EXC_ENCR_BLOCKSIZE - nBlockOffset;
629 0 : sal_uInt16 nEncBytes = ::std::min(nBlockLeft, nBytesLeft);
630 :
631 0 : bool bRet = maCodec.Encode(&aBytes[nPos], nEncBytes, &aBytes[nPos], nEncBytes);
632 : OSL_ENSURE(bRet, "XclExpBiff8Encrypter::EncryptBytes: encryption failed!!");
633 : (void) bRet; // to remove a silly compiler warning.
634 :
635 0 : sal_Size nRet = rStrm.Write(&aBytes[nPos], nEncBytes);
636 : OSL_ENSURE(nRet == nEncBytes, "XclExpBiff8Encrypter::EncryptBytes: fail to write to stream!!");
637 : (void) nRet; // to remove a silly compiler warning.
638 :
639 0 : nStrmPos = rStrm.Tell();
640 0 : nBlockOffset = GetOffsetInBlock(nStrmPos);
641 0 : nBlockPos = GetBlockPos(nStrmPos);
642 0 : if (nBlockOffset == 0)
643 0 : maCodec.InitCipher(nBlockPos);
644 :
645 0 : nBytesLeft -= nEncBytes;
646 0 : nPos += nEncBytes;
647 : }
648 0 : mnOldPos = nStrmPos;
649 : }
650 :
651 2 : static const char* lcl_GetErrorString( sal_uInt16 nScErrCode )
652 : {
653 2 : sal_uInt8 nXclErrCode = XclTools::GetXclErrorCode( nScErrCode );
654 2 : switch( nXclErrCode )
655 : {
656 0 : case EXC_ERR_NULL: return "#NULL!";
657 2 : case EXC_ERR_DIV0: return "#DIV/0!";
658 0 : case EXC_ERR_VALUE: return "#VALUE!";
659 0 : case EXC_ERR_REF: return "#REF!";
660 0 : case EXC_ERR_NAME: return "#NAME?";
661 0 : case EXC_ERR_NUM: return "#NUM!";
662 : case EXC_ERR_NA:
663 0 : default: return "#N/A";
664 : }
665 : }
666 :
667 1100 : void XclXmlUtils::GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& rsType, OUString& rsValue )
668 : {
669 1100 : sc::FormulaResultValue aResValue = rCell.GetResult();
670 :
671 1100 : switch (aResValue.meType)
672 : {
673 : case sc::FormulaResultValue::Error:
674 2 : rsType = "e";
675 2 : rsValue = ToOUString(lcl_GetErrorString(aResValue.mnError));
676 2 : break;
677 : case sc::FormulaResultValue::Value:
678 1074 : rsType = "n";
679 1074 : rsValue = OUString::number(aResValue.mfValue);
680 1074 : break;
681 : case sc::FormulaResultValue::String:
682 24 : rsType = "str";
683 24 : rsValue = rCell.GetString().getString();
684 24 : break;
685 : case sc::FormulaResultValue::Invalid:
686 : default:
687 : // TODO : double-check this to see if this is correct.
688 0 : rsType = "inlineStr";
689 0 : rsValue = rCell.GetString().getString();
690 1100 : }
691 1100 : }
692 :
693 290 : OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId )
694 : {
695 290 : OUStringBuffer sBuf;
696 290 : if( sStreamDir )
697 198 : sBuf.appendAscii( sStreamDir );
698 290 : sBuf.appendAscii( sStream );
699 290 : if( nId )
700 290 : sBuf.append( nId );
701 290 : if( strstr(sStream, "vml") )
702 0 : sBuf.appendAscii( ".vml" );
703 : else
704 290 : sBuf.appendAscii( ".xml" );
705 290 : return sBuf.makeStringAndClear();
706 : }
707 :
708 804 : OString XclXmlUtils::ToOString( const Color& rColor )
709 : {
710 : char buf[9];
711 804 : sprintf( buf, "%.2X%.2X%.2X%.2X", 0xFF-rColor.GetTransparency(), rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() );
712 804 : buf[8] = '\0';
713 804 : return OString( buf );
714 : }
715 :
716 4360 : OString XclXmlUtils::ToOString( const OUString& s )
717 : {
718 4360 : return OUStringToOString( s, RTL_TEXTENCODING_UTF8 );
719 : }
720 :
721 3648 : OString XclXmlUtils::ToOString( const ScAddress& rAddress )
722 : {
723 3648 : OUString sAddress(rAddress.Format(SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1)));
724 3648 : return ToOString( sAddress );
725 : }
726 :
727 0 : OString XclXmlUtils::ToOString( const ScfUInt16Vec& rBuffer )
728 : {
729 0 : if(rBuffer.empty())
730 0 : return OString();
731 :
732 0 : const sal_uInt16* pBuffer = &rBuffer [0];
733 0 : return OString( pBuffer, rBuffer.size(), RTL_TEXTENCODING_UTF8 );
734 : }
735 :
736 100 : OString XclXmlUtils::ToOString( const ScRange& rRange )
737 : {
738 100 : OUString sRange(rRange.Format(SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1)));
739 100 : return ToOString( sRange );
740 : }
741 :
742 84 : OString XclXmlUtils::ToOString( const ScRangeList& rRangeList )
743 : {
744 84 : OUString s;
745 84 : rRangeList.Format(s, SCA_VALID, NULL, FormulaGrammar::CONV_XL_A1, ' ');
746 84 : return ToOString( s );
747 : }
748 :
749 3782 : static ScAddress lcl_ToAddress( const XclAddress& rAddress )
750 : {
751 3782 : ScAddress aAddress;
752 :
753 : // For some reason, ScRange::Format() returns omits row numbers if
754 : // the row is >= MAXROW or the column is >= MAXCOL, and Excel doesn't
755 : // like "A:IV" (i.e. no row numbers). Prevent this.
756 : // KOHEI: Find out if the above comment is still true.
757 3782 : aAddress.SetRow( std::min<sal_Int32>( rAddress.mnRow, MAXROW ) );
758 3782 : aAddress.SetCol( static_cast<sal_Int16>(std::min<sal_Int32>( rAddress.mnCol, MAXCOL )) );
759 :
760 3782 : return aAddress;
761 : }
762 :
763 3634 : OString XclXmlUtils::ToOString( const XclAddress& rAddress )
764 : {
765 3634 : return ToOString( lcl_ToAddress( rAddress ) );
766 : }
767 :
768 0 : OString XclXmlUtils::ToOString( const XclExpString& s )
769 : {
770 : OSL_ENSURE( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
771 0 : return ToOString( s.GetUnicodeBuffer() );
772 : }
773 :
774 74 : static ScRange lcl_ToRange( const XclRange& rRange )
775 : {
776 74 : ScRange aRange;
777 :
778 74 : aRange.aStart = lcl_ToAddress( rRange.maFirst );
779 74 : aRange.aEnd = lcl_ToAddress( rRange.maLast );
780 :
781 74 : return aRange;
782 : }
783 :
784 0 : OString XclXmlUtils::ToOString( const XclRange& rRange )
785 : {
786 0 : return ToOString( lcl_ToRange( rRange ) );
787 : }
788 :
789 74 : OString XclXmlUtils::ToOString( const XclRangeList& rRanges )
790 : {
791 74 : ScRangeList aRanges;
792 148 : for( XclRangeVector::const_iterator i = rRanges.begin(), end = rRanges.end();
793 : i != end; ++i )
794 : {
795 74 : aRanges.Append( lcl_ToRange( *i ) );
796 : }
797 74 : return ToOString( aRanges );
798 : }
799 :
800 2 : OUString XclXmlUtils::ToOUString( const char* s )
801 : {
802 2 : return OUString( s, (sal_Int32) strlen( s ), RTL_TEXTENCODING_ASCII_US );
803 : }
804 :
805 396 : OUString XclXmlUtils::ToOUString( const ScfUInt16Vec& rBuf, sal_Int32 nStart, sal_Int32 nLength )
806 : {
807 396 : if( nLength == -1 || ( nLength > ((sal_Int32)rBuf.size() - nStart) ) )
808 394 : nLength = (rBuf.size() - nStart);
809 :
810 396 : return (nLength > 0) ? OUString( &rBuf[nStart], nLength ) : OUString();
811 : }
812 :
813 1120 : OUString XclXmlUtils::ToOUString(
814 : sc::CompileFormulaContext& rCtx, const ScAddress& rAddress, const ScTokenArray* pTokenArray )
815 : {
816 1120 : ScCompiler aCompiler( rCtx, rAddress, const_cast<ScTokenArray&>(*pTokenArray));
817 :
818 1120 : aCompiler.SetGrammar(FormulaGrammar::GRAM_OOXML);
819 :
820 2240 : OUStringBuffer aBuffer( pTokenArray->GetLen() * 5 );
821 1120 : aCompiler.CreateStringFromTokenArray( aBuffer );
822 2240 : return aBuffer.makeStringAndClear();
823 : }
824 :
825 394 : OUString XclXmlUtils::ToOUString( const XclExpString& s )
826 : {
827 : OSL_ENSURE( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
828 394 : return ToOUString( s.GetUnicodeBuffer() );
829 : }
830 :
831 11006 : const char* XclXmlUtils::ToPsz( bool b )
832 : {
833 11006 : return b ? "true" : "false";
834 : }
835 :
836 12 : const char* XclXmlUtils::ToPsz10( bool b )
837 : {
838 : // xlsx seems to use "1" or "0" for boolean values. I wonder it ever uses
839 : // the "true" "false" variant.
840 12 : return b ? "1" : "0";
841 : }
842 :
843 64 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue )
844 : {
845 64 : pStream->startElement( nElement, FSEND );
846 64 : pStream->write( nValue );
847 64 : pStream->endElement( nElement );
848 :
849 64 : return pStream;
850 : }
851 :
852 64 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue )
853 : {
854 64 : pStream->startElement( nElement, FSEND );
855 64 : pStream->write( nValue );
856 64 : pStream->endElement( nElement );
857 :
858 64 : return pStream;
859 : }
860 :
861 0 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, const char* sValue )
862 : {
863 0 : pStream->startElement( nElement, FSEND );
864 0 : pStream->write( sValue );
865 0 : pStream->endElement( nElement );
866 :
867 0 : return pStream;
868 : }
869 :
870 2156 : static void lcl_WriteValue( sax_fastparser::FSHelperPtr& rStream, sal_Int32 nElement, const char* pValue )
871 : {
872 2156 : if( !pValue )
873 3644 : return;
874 : rStream->singleElement( nElement,
875 : XML_val, pValue,
876 668 : FSEND );
877 : }
878 :
879 196 : static const char* lcl_GetUnderlineStyle( FontUnderline eUnderline, bool& bHaveUnderline )
880 : {
881 196 : bHaveUnderline = true;
882 196 : switch( eUnderline )
883 : {
884 : // OOXTODO: doubleAccounting, singleAccounting
885 : // OOXTODO: what should be done with the other FontUnderline values?
886 0 : case UNDERLINE_SINGLE: return "single";
887 0 : case UNDERLINE_DOUBLE: return "double";
888 : case UNDERLINE_NONE:
889 196 : default: bHaveUnderline = false; return "none";
890 : }
891 : }
892 :
893 196 : static const char* lcl_ToVerticalAlignmentRun( SvxEscapement eEscapement, bool& bHaveAlignment )
894 : {
895 196 : bHaveAlignment = true;
896 196 : switch( eEscapement )
897 : {
898 0 : case SVX_ESCAPEMENT_SUPERSCRIPT: return "superscript";
899 0 : case SVX_ESCAPEMENT_SUBSCRIPT: return "subscript";
900 : case SVX_ESCAPEMENT_OFF:
901 196 : default: bHaveAlignment = false; return "baseline";
902 : }
903 : }
904 :
905 196 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nFontId )
906 : {
907 : bool bHaveUnderline, bHaveVertAlign;
908 196 : const char* pUnderline = lcl_GetUnderlineStyle( rFontData.GetScUnderline(), bHaveUnderline );
909 196 : const char* pVertAlign = lcl_ToVerticalAlignmentRun( rFontData.GetScEscapement(), bHaveVertAlign );
910 :
911 196 : lcl_WriteValue( pStream, XML_b, rFontData.mnWeight > 400 ? XclXmlUtils::ToPsz( rFontData.mnWeight > 400 ) : NULL );
912 196 : lcl_WriteValue( pStream, XML_i, rFontData.mbItalic ? XclXmlUtils::ToPsz( rFontData.mbItalic ) : NULL );
913 196 : lcl_WriteValue( pStream, XML_strike, rFontData.mbStrikeout ? XclXmlUtils::ToPsz( rFontData.mbStrikeout ) : NULL );
914 : // OOXTODO: lcl_WriteValue( rStream, XML_condense, ); // mac compatibility setting
915 : // OOXTODO: lcl_WriteValue( rStream, XML_extend, ); // compatibility setting
916 196 : lcl_WriteValue( pStream, XML_outline, rFontData.mbOutline ? XclXmlUtils::ToPsz( rFontData.mbOutline ) : NULL );
917 196 : lcl_WriteValue( pStream, XML_shadow, rFontData.mbShadow ? XclXmlUtils::ToPsz( rFontData.mbShadow ) : NULL );
918 196 : lcl_WriteValue( pStream, XML_u, bHaveUnderline ? pUnderline : NULL );
919 196 : lcl_WriteValue( pStream, XML_vertAlign, bHaveVertAlign ? pVertAlign : NULL );
920 196 : lcl_WriteValue( pStream, XML_sz, OString::number( (double) (rFontData.mnHeight / 20.0) ).getStr() ); // Twips->Pt
921 196 : if( rFontData.maColor != Color( 0xFF, 0xFF, 0xFF, 0xFF ) )
922 : pStream->singleElement( XML_color,
923 : // OOXTODO: XML_auto, bool
924 : // OOXTODO: XML_indexed, uint
925 : XML_rgb, XclXmlUtils::ToOString( rFontData.maColor ).getStr(),
926 : // OOXTODO: XML_theme, index into <clrScheme/>
927 : // OOXTODO: XML_tint, double
928 60 : FSEND );
929 196 : lcl_WriteValue( pStream, nFontId, XclXmlUtils::ToOString( rFontData.maName ).getStr() );
930 196 : lcl_WriteValue( pStream, XML_family, OString::number( rFontData.mnFamily ).getStr() );
931 196 : lcl_WriteValue( pStream, XML_charset, rFontData.mnCharSet != 0 ? OString::number( rFontData.mnCharSet ).getStr() : NULL );
932 :
933 196 : return pStream;
934 : }
935 :
936 38 : XclExpXmlStream::XclExpXmlStream( const Reference< XComponentContext >& rCC )
937 : : XmlFilterBase( rCC ),
938 38 : mpRoot( NULL )
939 : {
940 38 : }
941 :
942 76 : XclExpXmlStream::~XclExpXmlStream()
943 : {
944 : assert(maStreams.empty() && "Forgotten PopStream()?");
945 76 : }
946 :
947 11152 : sax_fastparser::FSHelperPtr& XclExpXmlStream::GetCurrentStream()
948 : {
949 : OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::GetCurrentStream - no current stream" );
950 11152 : return maStreams.top();
951 : }
952 :
953 214 : void XclExpXmlStream::PushStream( sax_fastparser::FSHelperPtr aStream )
954 : {
955 214 : maStreams.push( aStream );
956 214 : }
957 :
958 214 : void XclExpXmlStream::PopStream()
959 : {
960 : OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::PopStream - stack is empty!" );
961 214 : maStreams.pop();
962 214 : }
963 :
964 74 : sax_fastparser::FSHelperPtr XclExpXmlStream::GetStreamForPath( const OUString& sPath )
965 : {
966 74 : if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
967 0 : return sax_fastparser::FSHelperPtr();
968 74 : return maOpenedStreamMap[ sPath ].second;
969 : }
970 :
971 1158 : sax_fastparser::FSHelperPtr& XclExpXmlStream::WriteAttributesInternal( sal_Int32 nAttribute, ... )
972 : {
973 1158 : sax_fastparser::FSHelperPtr& rStream = GetCurrentStream();
974 :
975 : va_list args;
976 1158 : va_start( args, nAttribute );
977 : do {
978 1220 : const char* pValue = va_arg( args, const char* );
979 1220 : if( pValue )
980 : {
981 : rStream->write( " " )
982 : ->writeId( nAttribute )
983 : ->write( "=\"" )
984 1198 : ->writeEscaped( OUString(pValue, strlen(pValue), RTL_TEXTENCODING_UTF8) )
985 1198 : ->write( "\"" );
986 : }
987 :
988 1220 : nAttribute = va_arg( args, sal_Int32 );
989 1220 : if( nAttribute == FSEND_internal )
990 1158 : break;
991 : } while( true );
992 1158 : va_end( args );
993 :
994 1220 : return rStream;
995 : }
996 216 : sax_fastparser::FSHelperPtr XclExpXmlStream::CreateOutputStream (
997 : const OUString& sFullStream,
998 : const OUString& sRelativeStream,
999 : const Reference< XOutputStream >& xParentRelation,
1000 : const char* sContentType,
1001 : const char* sRelationshipType,
1002 : OUString* pRelationshipId )
1003 : {
1004 216 : OUString sRelationshipId;
1005 216 : if (xParentRelation.is())
1006 178 : sRelationshipId = addRelation( xParentRelation, OUString::createFromAscii( sRelationshipType), sRelativeStream );
1007 : else
1008 38 : sRelationshipId = addRelation( OUString::createFromAscii( sRelationshipType ), sRelativeStream );
1009 :
1010 216 : if( pRelationshipId )
1011 104 : *pRelationshipId = sRelationshipId;
1012 :
1013 216 : sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
1014 :
1015 216 : maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
1016 :
1017 216 : return p;
1018 : }
1019 :
1020 0 : bool XclExpXmlStream::importDocument() throw()
1021 : {
1022 0 : return false;
1023 : }
1024 :
1025 0 : oox::vml::Drawing* XclExpXmlStream::getVmlDrawing()
1026 : {
1027 0 : return 0;
1028 : }
1029 :
1030 0 : const oox::drawingml::Theme* XclExpXmlStream::getCurrentTheme() const
1031 : {
1032 0 : return 0;
1033 : }
1034 :
1035 0 : const oox::drawingml::table::TableStyleListPtr XclExpXmlStream::getTableStyles()
1036 : {
1037 0 : return oox::drawingml::table::TableStyleListPtr();
1038 : }
1039 :
1040 0 : oox::drawingml::chart::ChartConverter* XclExpXmlStream::getChartConverter()
1041 : {
1042 : // DO NOT CALL
1043 0 : return NULL;
1044 : }
1045 :
1046 38 : ScDocShell* XclExpXmlStream::getDocShell()
1047 : {
1048 38 : Reference< XInterface > xModel( getModel(), UNO_QUERY );
1049 :
1050 38 : ScModelObj *pObj = dynamic_cast < ScModelObj* >( xModel.get() );
1051 :
1052 38 : if ( pObj )
1053 38 : return static_cast < ScDocShell* >( pObj->GetEmbeddedObject() );
1054 :
1055 0 : return 0;
1056 : }
1057 :
1058 38 : bool XclExpXmlStream::exportDocument()
1059 : throw (css::uno::RuntimeException, std::exception)
1060 : {
1061 38 : ScDocShell* pShell = getDocShell();
1062 38 : ScDocument& rDoc = pShell->GetDocument();
1063 38 : ScRefreshTimerProtector aProt(rDoc.GetRefreshTimerControlAddress());
1064 :
1065 76 : uno::Reference<task::XStatusIndicator> xStatusIndicator = getStatusIndicator();
1066 :
1067 38 : if (xStatusIndicator.is())
1068 0 : xStatusIndicator->start(ScGlobal::GetRscString(STR_SAVE_DOC), 100);
1069 :
1070 : // NOTE: Don't use SotStorage or SvStream any more, and never call
1071 : // SfxMedium::GetOutStream() anywhere in the xlsx export filter code!
1072 : // Instead, write via XOutputStream instance.
1073 76 : SotStorageRef rStorage = static_cast<SotStorage*>(NULL);
1074 38 : XclExpObjList::ResetCounters();
1075 :
1076 76 : XclExpRootData aData( EXC_BIFF8, *pShell->GetMedium (), rStorage, rDoc, RTL_TEXTENCODING_DONTKNOW );
1077 38 : aData.meOutput = EXC_OUTPUT_XML_2007;
1078 38 : aData.maXclMaxPos.Set( EXC_MAXCOL_XML_2007, EXC_MAXROW_XML_2007, EXC_MAXTAB_XML_2007 );
1079 38 : aData.maMaxPos.SetCol( ::std::min( aData.maScMaxPos.Col(), aData.maXclMaxPos.Col() ) );
1080 38 : aData.maMaxPos.SetRow( ::std::min( aData.maScMaxPos.Row(), aData.maXclMaxPos.Row() ) );
1081 38 : aData.maMaxPos.SetTab( ::std::min( aData.maScMaxPos.Tab(), aData.maXclMaxPos.Tab() ) );
1082 38 : aData.mpCompileFormulaCxt.reset( new sc::CompileFormulaContext(&rDoc) );
1083 :
1084 76 : XclExpRoot aRoot( aData );
1085 :
1086 38 : mpRoot = &aRoot;
1087 38 : aRoot.GetOldRoot().pER = &aRoot;
1088 38 : aRoot.GetOldRoot().eDateiTyp = Biff8;
1089 : // Get the viewsettings before processing
1090 38 : if( ScDocShell::GetViewData() )
1091 10 : ScDocShell::GetViewData()->WriteExtOptions( mpRoot->GetExtDocOptions() );
1092 :
1093 76 : OUString const workbook = "xl/workbook.xml";
1094 : PushStream( CreateOutputStream( workbook, workbook,
1095 : Reference <XOutputStream>(),
1096 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
1097 38 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) );
1098 :
1099 : // destruct at the end of the block
1100 : {
1101 38 : ExcDocument aDocRoot( aRoot );
1102 38 : if (xStatusIndicator.is())
1103 0 : xStatusIndicator->setValue(10);
1104 38 : aDocRoot.ReadDoc();
1105 38 : if (xStatusIndicator.is())
1106 0 : xStatusIndicator->setValue(40);
1107 38 : aDocRoot.WriteXml( *this );
1108 : }
1109 :
1110 38 : PopStream();
1111 : // Free all FSHelperPtr, to flush data before commiting storage
1112 38 : maOpenedStreamMap.clear();
1113 :
1114 38 : commitStorage();
1115 :
1116 38 : if (xStatusIndicator.is())
1117 0 : xStatusIndicator->end();
1118 38 : mpRoot = NULL;
1119 76 : return true;
1120 : }
1121 :
1122 0 : ::oox::ole::VbaProject* XclExpXmlStream::implCreateVbaProject() const
1123 : {
1124 0 : return new ::oox::xls::ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
1125 : }
1126 :
1127 0 : OUString XclExpXmlStream::implGetImplementationName() const
1128 : {
1129 0 : return OUString( "TODO" );
1130 48 : }
1131 :
1132 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|