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 37 : 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 37 : mbInRec( false )
95 : {
96 37 : if( mnMaxRecSize == 0 )
97 36 : mnMaxRecSize = (mrRoot.GetBiff() <= EXC_BIFF5) ? EXC_MAXRECSIZE_BIFF5 : EXC_MAXRECSIZE_BIFF8;
98 37 : mnMaxContSize = mnMaxRecSize;
99 37 : }
100 :
101 74 : XclExpStream::~XclExpStream()
102 : {
103 37 : mrStrm.Flush();
104 37 : }
105 :
106 3772 : void XclExpStream::StartRecord( sal_uInt16 nRecId, sal_Size nRecSize )
107 : {
108 : OSL_ENSURE( !mbInRec, "XclExpStream::StartRecord - another record still open" );
109 3772 : DisableEncryption();
110 3772 : mnMaxContSize = mnCurrMaxSize = mnMaxRecSize;
111 3772 : mnPredictSize = nRecSize;
112 3772 : mbInRec = true;
113 3772 : InitRecord( nRecId );
114 3772 : SetSliceSize( 0 );
115 3772 : EnableEncryption();
116 3772 : }
117 :
118 3772 : void XclExpStream::EndRecord()
119 : {
120 : OSL_ENSURE( mbInRec, "XclExpStream::EndRecord - no record open" );
121 3772 : DisableEncryption();
122 3772 : UpdateRecSize();
123 3772 : mrStrm.Seek( STREAM_SEEK_TO_END );
124 3772 : mbInRec = false;
125 3772 : }
126 :
127 4950 : void XclExpStream::SetSliceSize( sal_uInt16 nSize )
128 : {
129 4950 : mnMaxSliceSize = nSize;
130 4950 : mnSliceSize = 0;
131 4950 : }
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 8169 : XclExpStream& XclExpStream::operator<<( sal_uInt8 nValue )
144 : {
145 8169 : PrepareWrite( 1 );
146 8169 : if (mbUseEncrypter && HasValidEncrypter())
147 0 : mxEncrypter->Encrypt(mrStrm, nValue);
148 : else
149 8169 : mrStrm.WriteUChar( nValue );
150 8169 : return *this;
151 : }
152 :
153 30 : XclExpStream& XclExpStream::operator<<( sal_Int16 nValue )
154 : {
155 30 : PrepareWrite( 2 );
156 30 : if (mbUseEncrypter && HasValidEncrypter())
157 0 : mxEncrypter->Encrypt(mrStrm, nValue);
158 : else
159 30 : mrStrm.WriteInt16( nValue );
160 30 : return *this;
161 : }
162 :
163 13569 : XclExpStream& XclExpStream::operator<<( sal_uInt16 nValue )
164 : {
165 13569 : PrepareWrite( 2 );
166 13569 : if (mbUseEncrypter && HasValidEncrypter())
167 0 : mxEncrypter->Encrypt(mrStrm, nValue);
168 : else
169 13569 : mrStrm.WriteUInt16( nValue );
170 13569 : return *this;
171 : }
172 :
173 369 : XclExpStream& XclExpStream::operator<<( sal_Int32 nValue )
174 : {
175 369 : PrepareWrite( 4 );
176 369 : if (mbUseEncrypter && HasValidEncrypter())
177 0 : mxEncrypter->Encrypt(mrStrm, nValue);
178 : else
179 369 : mrStrm.WriteInt32( nValue );
180 369 : return *this;
181 : }
182 :
183 2236 : XclExpStream& XclExpStream::operator<<( sal_uInt32 nValue )
184 : {
185 2236 : PrepareWrite( 4 );
186 2236 : if (mbUseEncrypter && HasValidEncrypter())
187 0 : mxEncrypter->Encrypt(mrStrm, nValue);
188 : else
189 2236 : mrStrm.WriteUInt32( nValue );
190 2236 : 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 913 : XclExpStream& XclExpStream::operator<<( double fValue )
204 : {
205 913 : PrepareWrite( 8 );
206 913 : if (mbUseEncrypter && HasValidEncrypter())
207 0 : mxEncrypter->Encrypt(mrStrm, fValue);
208 : else
209 913 : mrStrm.WriteDouble( fValue );
210 913 : return *this;
211 : }
212 :
213 877 : sal_Size XclExpStream::Write( const void* pData, sal_Size nBytes )
214 : {
215 877 : sal_Size nRet = 0;
216 877 : if( pData && (nBytes > 0) )
217 : {
218 877 : if( mbInRec )
219 : {
220 869 : const sal_uInt8* pBuffer = static_cast< const sal_uInt8* >( pData );
221 869 : sal_Size nBytesLeft = nBytes;
222 869 : bool bValid = true;
223 :
224 2642 : while( bValid && (nBytesLeft > 0) )
225 : {
226 904 : sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
227 904 : sal_Size nWriteRet = nWriteLen;
228 904 : 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 904 : nWriteRet = mrStrm.Write( pBuffer, nWriteLen );
239 904 : bValid = (nWriteLen == nWriteRet);
240 : OSL_ENSURE( bValid, "XclExpStream::Write - stream write error" );
241 : }
242 904 : pBuffer += nWriteRet;
243 904 : nRet += nWriteRet;
244 904 : nBytesLeft -= nWriteRet;
245 904 : UpdateSizeVars( nWriteRet );
246 : }
247 : }
248 : else
249 8 : nRet = mrStrm.Write( pData, nBytes );
250 : }
251 877 : return nRet;
252 : }
253 :
254 33 : void XclExpStream::WriteZeroBytes( sal_Size nBytes )
255 : {
256 33 : if( mbInRec )
257 : {
258 33 : sal_Size nBytesLeft = nBytes;
259 99 : while( nBytesLeft > 0 )
260 : {
261 33 : sal_Size nWriteLen = ::std::min< sal_Size >( PrepareWrite(), nBytesLeft );
262 33 : WriteRawZeroBytes( nWriteLen );
263 33 : nBytesLeft -= nWriteLen;
264 33 : UpdateSizeVars( nWriteLen );
265 : }
266 : }
267 : else
268 0 : WriteRawZeroBytes( nBytes );
269 33 : }
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 73 : void XclExpStream::CopyFromStream(SvStream& rInStrm, sal_uInt64 const nBytes)
283 : {
284 73 : sal_uInt64 const nRemaining(rInStrm.remainingSize());
285 73 : sal_uInt64 nBytesLeft = ::std::min(nBytes, nRemaining);
286 73 : if( nBytesLeft > 0 )
287 : {
288 66 : const sal_Size nMaxBuffer = 4096;
289 : boost::scoped_array<sal_uInt8> pBuffer(
290 66 : new sal_uInt8[ ::std::min<sal_Size>(nBytesLeft, nMaxBuffer) ]);
291 66 : bool bValid = true;
292 :
293 270 : while( bValid && (nBytesLeft > 0) )
294 : {
295 138 : sal_Size nWriteLen = ::std::min<sal_Size>(nBytesLeft, nMaxBuffer);
296 138 : rInStrm.Read( pBuffer.get(), nWriteLen );
297 138 : sal_Size nWriteRet = Write( pBuffer.get(), nWriteLen );
298 138 : bValid = (nWriteLen == nWriteRet);
299 138 : nBytesLeft -= nWriteRet;
300 66 : }
301 : }
302 73 : }
303 :
304 370 : void XclExpStream::WriteUnicodeBuffer( const ScfUInt16Vec& rBuffer, sal_uInt8 nFlags )
305 : {
306 370 : SetSliceSize( 0 );
307 370 : nFlags &= EXC_STRF_16BIT; // repeat only 16bit flag
308 370 : sal_uInt16 nCharLen = nFlags ? 2 : 1;
309 :
310 370 : ScfUInt16Vec::const_iterator aEnd = rBuffer.end();
311 4683 : for( ScfUInt16Vec::const_iterator aIter = rBuffer.begin(); aIter != aEnd; ++aIter )
312 : {
313 4313 : if( mbInRec && (mnCurrSize + nCharLen > mnCurrMaxSize) )
314 : {
315 0 : StartContinue();
316 0 : operator<<( nFlags );
317 : }
318 4313 : if( nCharLen == 2 )
319 476 : operator<<( *aIter );
320 : else
321 3837 : operator<<( static_cast< sal_uInt8 >( *aIter ) );
322 : }
323 370 : }
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 3867 : bool XclExpStream::HasValidEncrypter() const
359 : {
360 3867 : return mxEncrypter && mxEncrypter->IsValid();
361 : }
362 :
363 11532 : void XclExpStream::EnableEncryption( bool bEnable )
364 : {
365 11532 : mbUseEncrypter = bEnable && HasValidEncrypter();
366 11532 : }
367 :
368 7665 : void XclExpStream::DisableEncryption()
369 : {
370 7665 : EnableEncryption(false);
371 7665 : }
372 :
373 29 : sal_uInt64 XclExpStream::SetSvStreamPos(sal_uInt64 const nPos)
374 : {
375 : OSL_ENSURE( !mbInRec, "XclExpStream::SetSvStreamPos - not allowed inside of a record" );
376 29 : return mbInRec ? 0 : mrStrm.Seek( nPos );
377 : }
378 :
379 : // private --------------------------------------------------------------------
380 :
381 3807 : void XclExpStream::InitRecord( sal_uInt16 nRecId )
382 : {
383 3807 : mrStrm.Seek( STREAM_SEEK_TO_END );
384 3807 : mrStrm.WriteUInt16( nRecId );
385 :
386 3807 : mnLastSizePos = mrStrm.Tell();
387 3807 : mnHeaderSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( mnPredictSize, mnCurrMaxSize ) );
388 3807 : mrStrm.WriteUInt16( mnHeaderSize );
389 3807 : mnCurrSize = mnSliceSize = 0;
390 3807 : }
391 :
392 3807 : void XclExpStream::UpdateRecSize()
393 : {
394 3807 : if( mnCurrSize != mnHeaderSize )
395 : {
396 184 : mrStrm.Seek( mnLastSizePos );
397 184 : mrStrm.WriteUInt16( mnCurrSize );
398 : }
399 3807 : }
400 :
401 27064 : void XclExpStream::UpdateSizeVars( sal_Size nSize )
402 : {
403 : OSL_ENSURE( mnCurrSize + nSize <= mnCurrMaxSize, "XclExpStream::UpdateSizeVars - record overwritten" );
404 27064 : mnCurrSize = mnCurrSize + static_cast< sal_uInt16 >( nSize );
405 :
406 27064 : if( mnMaxSliceSize > 0 )
407 : {
408 : OSL_ENSURE( mnSliceSize + nSize <= mnMaxSliceSize, "XclExpStream::UpdateSizeVars - slice overwritten" );
409 1047 : mnSliceSize = mnSliceSize + static_cast< sal_uInt16 >( nSize );
410 1047 : if( mnSliceSize >= mnMaxSliceSize )
411 56 : mnSliceSize = 0;
412 : }
413 27064 : }
414 :
415 35 : void XclExpStream::StartContinue()
416 : {
417 35 : UpdateRecSize();
418 35 : mnCurrMaxSize = mnMaxContSize;
419 35 : mnPredictSize -= mnCurrSize;
420 35 : InitRecord( EXC_ID_CONT );
421 35 : }
422 :
423 25286 : void XclExpStream::PrepareWrite( sal_uInt16 nSize )
424 : {
425 25286 : if( mbInRec )
426 : {
427 50380 : if( (mnCurrSize + nSize > mnCurrMaxSize) ||
428 26237 : ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
429 0 : StartContinue();
430 25190 : UpdateSizeVars( nSize );
431 : }
432 25286 : }
433 :
434 937 : sal_uInt16 XclExpStream::PrepareWrite()
435 : {
436 937 : sal_uInt16 nRet = 0;
437 937 : if( mbInRec )
438 : {
439 1839 : if( (mnCurrSize >= mnCurrMaxSize) ||
440 902 : ((mnMaxSliceSize > 0) && (mnSliceSize == 0) && (mnCurrSize + mnMaxSliceSize > mnCurrMaxSize)) )
441 35 : StartContinue();
442 937 : UpdateSizeVars( 0 );
443 :
444 937 : nRet = (mnMaxSliceSize > 0) ? (mnMaxSliceSize - mnSliceSize) : (mnCurrMaxSize - mnCurrSize);
445 : }
446 937 : return nRet;
447 : }
448 :
449 33 : void XclExpStream::WriteRawZeroBytes( sal_Size nBytes )
450 : {
451 33 : const sal_uInt32 nData = 0;
452 33 : sal_Size nBytesLeft = nBytes;
453 425 : while( nBytesLeft >= sizeof( nData ) )
454 : {
455 359 : mrStrm.WriteUInt32( nData );
456 359 : nBytesLeft -= sizeof( nData );
457 : }
458 33 : if( nBytesLeft )
459 5 : mrStrm.Write( &nData, nBytesLeft );
460 33 : }
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 )
578 : {
579 0 : return static_cast< sal_uInt32 >( nStrmPos / EXC_ENCR_BLOCKSIZE );
580 : }
581 :
582 0 : sal_uInt16 XclExpBiff8Encrypter::GetOffsetInBlock( sal_Size nStrmPos )
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 1 : static const char* lcl_GetErrorString( sal_uInt16 nScErrCode )
652 : {
653 1 : sal_uInt8 nXclErrCode = XclTools::GetXclErrorCode( nScErrCode );
654 1 : switch( nXclErrCode )
655 : {
656 0 : case EXC_ERR_NULL: return "#NULL!";
657 1 : 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 550 : void XclXmlUtils::GetFormulaTypeAndValue( ScFormulaCell& rCell, const char*& rsType, OUString& rsValue )
668 : {
669 550 : sc::FormulaResultValue aResValue = rCell.GetResult();
670 :
671 550 : switch (aResValue.meType)
672 : {
673 : case sc::FormulaResultValue::Error:
674 1 : rsType = "e";
675 1 : rsValue = ToOUString(lcl_GetErrorString(aResValue.mnError));
676 1 : break;
677 : case sc::FormulaResultValue::Value:
678 537 : rsType = "n";
679 537 : rsValue = OUString::number(aResValue.mfValue);
680 537 : break;
681 : case sc::FormulaResultValue::String:
682 12 : rsType = "str";
683 12 : rsValue = rCell.GetString().getString();
684 12 : 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 550 : }
691 550 : }
692 :
693 402 : OUString XclXmlUtils::GetStreamName( const char* sStreamDir, const char* sStream, sal_Int32 nId )
694 : {
695 402 : OUStringBuffer sBuf;
696 402 : if( sStreamDir )
697 293 : sBuf.appendAscii( sStreamDir );
698 402 : sBuf.appendAscii( sStream );
699 402 : if( nId )
700 402 : sBuf.append( nId );
701 402 : if( strstr(sStream, "vml") )
702 0 : sBuf.appendAscii( ".vml" );
703 : else
704 402 : sBuf.appendAscii( ".xml" );
705 402 : return sBuf.makeStringAndClear();
706 : }
707 :
708 1648 : OString XclXmlUtils::ToOString( const Color& rColor )
709 : {
710 : char buf[9];
711 1648 : sprintf( buf, "%.2X%.2X%.2X%.2X", 0xFF-rColor.GetTransparency(), rColor.GetRed(), rColor.GetGreen(), rColor.GetBlue() );
712 1648 : buf[8] = '\0';
713 1648 : return OString( buf );
714 : }
715 :
716 833 : OString XclXmlUtils::ToOString( const OUString& s )
717 : {
718 833 : return OUStringToOString( s, RTL_TEXTENCODING_UTF8 );
719 : }
720 :
721 2095 : OStringBuffer& XclXmlUtils::ToOString( OStringBuffer& s, const ScAddress& rAddress )
722 : {
723 2095 : rAddress.Format(s, SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1));
724 2095 : return s;
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 120 : OString XclXmlUtils::ToOString( const ScRange& rRange )
737 : {
738 120 : OUString sRange(rRange.Format(SCA_VALID, NULL, ScAddress::Details( FormulaGrammar::CONV_XL_A1)));
739 120 : return ToOString( sRange );
740 : }
741 :
742 105 : OString XclXmlUtils::ToOString( const ScRangeList& rRangeList )
743 : {
744 105 : OUString s;
745 105 : rRangeList.Format(s, SCA_VALID, NULL, FormulaGrammar::CONV_XL_A1, ' ');
746 105 : return ToOString( s );
747 : }
748 :
749 2295 : static ScAddress lcl_ToAddress( const XclAddress& rAddress )
750 : {
751 2295 : 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 2295 : aAddress.SetRow( std::min<sal_Int32>( rAddress.mnRow, MAXROW ) );
758 2295 : aAddress.SetCol( static_cast<sal_Int16>(std::min<sal_Int32>( rAddress.mnCol, MAXCOL )) );
759 :
760 2295 : return aAddress;
761 : }
762 :
763 2095 : OStringBuffer& XclXmlUtils::ToOString( OStringBuffer& s, const XclAddress& rAddress )
764 : {
765 2095 : return ToOString( s, 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 100 : static ScRange lcl_ToRange( const XclRange& rRange )
775 : {
776 100 : ScRange aRange;
777 :
778 100 : aRange.aStart = lcl_ToAddress( rRange.maFirst );
779 100 : aRange.aEnd = lcl_ToAddress( rRange.maLast );
780 :
781 100 : return aRange;
782 : }
783 :
784 0 : OString XclXmlUtils::ToOString( const XclRange& rRange )
785 : {
786 0 : return ToOString( lcl_ToRange( rRange ) );
787 : }
788 :
789 100 : OString XclXmlUtils::ToOString( const XclRangeList& rRanges )
790 : {
791 100 : ScRangeList aRanges;
792 200 : for( XclRangeVector::const_iterator i = rRanges.begin(), end = rRanges.end();
793 : i != end; ++i )
794 : {
795 100 : aRanges.Append( lcl_ToRange( *i ) );
796 : }
797 100 : return ToOString( aRanges );
798 : }
799 :
800 1 : OUString XclXmlUtils::ToOUString( const char* s )
801 : {
802 1 : return OUString( s, (sal_Int32) strlen( s ), RTL_TEXTENCODING_ASCII_US );
803 : }
804 :
805 242 : OUString XclXmlUtils::ToOUString( const ScfUInt16Vec& rBuf, sal_Int32 nStart, sal_Int32 nLength )
806 : {
807 242 : if( nLength == -1 || ( nLength > ((sal_Int32)rBuf.size() - nStart) ) )
808 236 : nLength = (rBuf.size() - nStart);
809 :
810 242 : return (nLength > 0) ? OUString( &rBuf[nStart], nLength ) : OUString();
811 : }
812 :
813 560 : OUString XclXmlUtils::ToOUString(
814 : sc::CompileFormulaContext& rCtx, const ScAddress& rAddress, const ScTokenArray* pTokenArray )
815 : {
816 560 : ScCompiler aCompiler( rCtx, rAddress, const_cast<ScTokenArray&>(*pTokenArray));
817 :
818 560 : aCompiler.SetGrammar(FormulaGrammar::GRAM_OOXML);
819 :
820 1120 : OUStringBuffer aBuffer( pTokenArray->GetLen() * 5 );
821 560 : aCompiler.CreateStringFromTokenArray( aBuffer );
822 1120 : return aBuffer.makeStringAndClear();
823 : }
824 :
825 236 : OUString XclXmlUtils::ToOUString( const XclExpString& s )
826 : {
827 : OSL_ENSURE( !s.IsRich(), "XclXmlUtils::ToOString(XclExpString): rich text string found!" );
828 236 : return ToOUString( s.GetUnicodeBuffer() );
829 : }
830 :
831 11024 : const char* XclXmlUtils::ToPsz( bool b )
832 : {
833 11024 : return b ? "true" : "false";
834 : }
835 :
836 6 : 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 6 : return b ? "1" : "0";
841 : }
842 :
843 184 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int32 nValue )
844 : {
845 184 : pStream->startElement( nElement, FSEND );
846 184 : pStream->write( nValue );
847 184 : pStream->endElement( nElement );
848 :
849 184 : return pStream;
850 : }
851 :
852 184 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteElement( sax_fastparser::FSHelperPtr pStream, sal_Int32 nElement, sal_Int64 nValue )
853 : {
854 184 : pStream->startElement( nElement, FSEND );
855 184 : pStream->write( nValue );
856 184 : pStream->endElement( nElement );
857 :
858 184 : 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 3102 : static void lcl_WriteValue( sax_fastparser::FSHelperPtr& rStream, sal_Int32 nElement, const char* pValue )
871 : {
872 3102 : if( !pValue )
873 5275 : return;
874 : rStream->singleElement( nElement,
875 : XML_val, pValue,
876 929 : FSEND );
877 : }
878 :
879 282 : static const char* lcl_GetUnderlineStyle( FontUnderline eUnderline, bool& bHaveUnderline )
880 : {
881 282 : bHaveUnderline = true;
882 282 : switch( eUnderline )
883 : {
884 : // OOXTODO: doubleAccounting, singleAccounting
885 : // OOXTODO: what should be done with the other FontUnderline values?
886 2 : case UNDERLINE_SINGLE: return "single";
887 1 : case UNDERLINE_DOUBLE: return "double";
888 : case UNDERLINE_NONE:
889 279 : default: bHaveUnderline = false; return "none";
890 : }
891 : }
892 :
893 282 : static const char* lcl_ToVerticalAlignmentRun( SvxEscapement eEscapement, bool& bHaveAlignment )
894 : {
895 282 : bHaveAlignment = true;
896 282 : 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 282 : default: bHaveAlignment = false; return "baseline";
902 : }
903 : }
904 :
905 282 : sax_fastparser::FSHelperPtr XclXmlUtils::WriteFontData( sax_fastparser::FSHelperPtr pStream, const XclFontData& rFontData, sal_Int32 nFontId )
906 : {
907 : bool bHaveUnderline, bHaveVertAlign;
908 282 : const char* pUnderline = lcl_GetUnderlineStyle( rFontData.GetScUnderline(), bHaveUnderline );
909 282 : const char* pVertAlign = lcl_ToVerticalAlignmentRun( rFontData.GetScEscapement(), bHaveVertAlign );
910 :
911 282 : lcl_WriteValue( pStream, XML_b, rFontData.mnWeight > 400 ? XclXmlUtils::ToPsz( rFontData.mnWeight > 400 ) : NULL );
912 282 : lcl_WriteValue( pStream, XML_i, rFontData.mbItalic ? XclXmlUtils::ToPsz( rFontData.mbItalic ) : NULL );
913 282 : 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 282 : lcl_WriteValue( pStream, XML_outline, rFontData.mbOutline ? XclXmlUtils::ToPsz( rFontData.mbOutline ) : NULL );
917 282 : lcl_WriteValue( pStream, XML_shadow, rFontData.mbShadow ? XclXmlUtils::ToPsz( rFontData.mbShadow ) : NULL );
918 282 : lcl_WriteValue( pStream, XML_u, bHaveUnderline ? pUnderline : NULL );
919 282 : lcl_WriteValue( pStream, XML_vertAlign, bHaveVertAlign ? pVertAlign : NULL );
920 282 : lcl_WriteValue( pStream, XML_sz, OString::number( (double) (rFontData.mnHeight / 20.0) ).getStr() ); // Twips->Pt
921 282 : 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 99 : FSEND );
929 282 : lcl_WriteValue( pStream, nFontId, XclXmlUtils::ToOString( rFontData.maName ).getStr() );
930 282 : lcl_WriteValue( pStream, XML_family, OString::number( rFontData.mnFamily ).getStr() );
931 282 : lcl_WriteValue( pStream, XML_charset, rFontData.mnCharSet != 0 ? OString::number( rFontData.mnCharSet ).getStr() : NULL );
932 :
933 282 : return pStream;
934 : }
935 :
936 55 : XclExpXmlStream::XclExpXmlStream( const Reference< XComponentContext >& rCC )
937 : : XmlFilterBase( rCC ),
938 55 : mpRoot( NULL )
939 : {
940 55 : }
941 :
942 110 : XclExpXmlStream::~XclExpXmlStream()
943 : {
944 : assert(maStreams.empty() && "Forgotten PopStream()?");
945 110 : }
946 :
947 10426 : sax_fastparser::FSHelperPtr& XclExpXmlStream::GetCurrentStream()
948 : {
949 : OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::GetCurrentStream - no current stream" );
950 10426 : return maStreams.top();
951 : }
952 :
953 295 : void XclExpXmlStream::PushStream( sax_fastparser::FSHelperPtr aStream )
954 : {
955 295 : maStreams.push( aStream );
956 295 : }
957 :
958 295 : void XclExpXmlStream::PopStream()
959 : {
960 : OSL_ENSURE( !maStreams.empty(), "XclExpXmlStream::PopStream - stack is empty!" );
961 295 : maStreams.pop();
962 295 : }
963 :
964 100 : sax_fastparser::FSHelperPtr XclExpXmlStream::GetStreamForPath( const OUString& sPath )
965 : {
966 100 : if( maOpenedStreamMap.find( sPath ) == maOpenedStreamMap.end() )
967 0 : return sax_fastparser::FSHelperPtr();
968 100 : return maOpenedStreamMap[ sPath ].second;
969 : }
970 :
971 1536 : sax_fastparser::FSHelperPtr& XclExpXmlStream::WriteAttributesInternal( sal_Int32 nAttribute, ... )
972 : {
973 1536 : sax_fastparser::FSHelperPtr& rStream = GetCurrentStream();
974 :
975 : va_list args;
976 1536 : va_start( args, nAttribute );
977 : do {
978 1567 : const char* pValue = va_arg( args, const char* );
979 1567 : if( pValue )
980 : {
981 : rStream->write( " " )
982 : ->writeId( nAttribute )
983 : ->write( "=\"" )
984 1556 : ->writeEscaped( OUString(pValue, strlen(pValue), RTL_TEXTENCODING_UTF8) )
985 1556 : ->write( "\"" );
986 : }
987 :
988 1567 : nAttribute = va_arg( args, sal_Int32 );
989 1567 : if( nAttribute == FSEND_internal )
990 1536 : break;
991 : } while( true );
992 1536 : va_end( args );
993 :
994 1567 : return rStream;
995 : }
996 296 : 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 296 : OUString sRelationshipId;
1005 296 : if (xParentRelation.is())
1006 241 : sRelationshipId = addRelation( xParentRelation, OUString::createFromAscii( sRelationshipType), sRelativeStream );
1007 : else
1008 55 : sRelationshipId = addRelation( OUString::createFromAscii( sRelationshipType ), sRelativeStream );
1009 :
1010 296 : if( pRelationshipId )
1011 149 : *pRelationshipId = sRelationshipId;
1012 :
1013 296 : sax_fastparser::FSHelperPtr p = openFragmentStreamWithSerializer( sFullStream, OUString::createFromAscii( sContentType ) );
1014 :
1015 296 : maOpenedStreamMap[ sFullStream ] = std::make_pair( sRelationshipId, p );
1016 :
1017 296 : 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 55 : ScDocShell* XclExpXmlStream::getDocShell()
1047 : {
1048 55 : Reference< XInterface > xModel( getModel(), UNO_QUERY );
1049 :
1050 55 : ScModelObj *pObj = dynamic_cast < ScModelObj* >( xModel.get() );
1051 :
1052 55 : if ( pObj )
1053 55 : return static_cast < ScDocShell* >( pObj->GetEmbeddedObject() );
1054 :
1055 0 : return 0;
1056 : }
1057 :
1058 55 : bool XclExpXmlStream::exportDocument()
1059 : throw (css::uno::RuntimeException, std::exception)
1060 : {
1061 55 : ScDocShell* pShell = getDocShell();
1062 55 : ScDocument& rDoc = pShell->GetDocument();
1063 55 : ScRefreshTimerProtector aProt(rDoc.GetRefreshTimerControlAddress());
1064 :
1065 110 : uno::Reference<task::XStatusIndicator> xStatusIndicator = getStatusIndicator();
1066 :
1067 55 : 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 110 : tools::SvRef<SotStorage> rStorage = static_cast<SotStorage*>(NULL);
1074 55 : XclExpObjList::ResetCounters();
1075 :
1076 110 : XclExpRootData aData( EXC_BIFF8, *pShell->GetMedium (), rStorage, rDoc, RTL_TEXTENCODING_DONTKNOW );
1077 55 : aData.meOutput = EXC_OUTPUT_XML_2007;
1078 55 : aData.maXclMaxPos.Set( EXC_MAXCOL_XML_2007, EXC_MAXROW_XML_2007, EXC_MAXTAB_XML_2007 );
1079 55 : aData.maMaxPos.SetCol( ::std::min( aData.maScMaxPos.Col(), aData.maXclMaxPos.Col() ) );
1080 55 : aData.maMaxPos.SetRow( ::std::min( aData.maScMaxPos.Row(), aData.maXclMaxPos.Row() ) );
1081 55 : aData.maMaxPos.SetTab( ::std::min( aData.maScMaxPos.Tab(), aData.maXclMaxPos.Tab() ) );
1082 55 : aData.mpCompileFormulaCxt.reset( new sc::CompileFormulaContext(&rDoc) );
1083 :
1084 110 : XclExpRoot aRoot( aData );
1085 :
1086 55 : mpRoot = &aRoot;
1087 55 : aRoot.GetOldRoot().pER = &aRoot;
1088 55 : aRoot.GetOldRoot().eDateiTyp = Biff8;
1089 : // Get the viewsettings before processing
1090 55 : if( ScDocShell::GetViewData() )
1091 23 : ScDocShell::GetViewData()->WriteExtOptions( mpRoot->GetExtDocOptions() );
1092 :
1093 110 : OUString const workbook = "xl/workbook.xml";
1094 : PushStream( CreateOutputStream( workbook, workbook,
1095 : Reference <XOutputStream>(),
1096 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
1097 55 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" ) );
1098 :
1099 : // destruct at the end of the block
1100 : {
1101 55 : ExcDocument aDocRoot( aRoot );
1102 55 : if (xStatusIndicator.is())
1103 0 : xStatusIndicator->setValue(10);
1104 55 : aDocRoot.ReadDoc();
1105 55 : if (xStatusIndicator.is())
1106 0 : xStatusIndicator->setValue(40);
1107 55 : aDocRoot.WriteXml( *this );
1108 : }
1109 :
1110 55 : PopStream();
1111 : // Free all FSHelperPtr, to flush data before committing storage
1112 55 : maOpenedStreamMap.clear();
1113 :
1114 55 : commitStorage();
1115 :
1116 55 : if (xStatusIndicator.is())
1117 0 : xStatusIndicator->end();
1118 55 : mpRoot = NULL;
1119 110 : 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::getImplementationName() throw (css::uno::RuntimeException, std::exception)
1128 : {
1129 0 : return OUString( "TODO" );
1130 30 : }
1131 :
1132 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|