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