update dev300-m58
[ooovba.git] / sc / source / filter / xcl97 / xcl97rec.cxx
blob97bd958a68a77618dd1cdd9a3db3c0d68e9bce88
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xcl97rec.cxx,v $
10 * $Revision: 1.87.30.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 #include <svx/svdpool.hxx>
35 #include <svx/sdtaitm.hxx>
36 #include <svx/svdotext.hxx>
37 #include <svx/editobj.hxx>
38 #include <svx/svdoole2.hxx>
39 #include <sot/storage.hxx>
40 #include <svtools/itemset.hxx>
41 #include <svx/svdpage.hxx>
42 #include <svx/svdocapt.hxx>
43 #include <svx/unoapi.hxx>
44 #include <svx/writingmodeitem.hxx>
45 #include <vcl/svapp.hxx>
46 #include <rtl/math.hxx>
47 #include <svtools/zformat.hxx>
48 #include "cell.hxx"
49 #include "drwlayer.hxx"
51 #include "xcl97rec.hxx"
52 #include "xcl97esc.hxx"
53 #include "editutil.hxx"
54 #include "xecontent.hxx"
55 #include "xestyle.hxx"
56 #include "xelink.hxx"
58 #include "scitems.hxx"
60 #include <svtools/fltrcfg.hxx>
61 #include <svx/brshitem.hxx>
62 #include <svx/boxitem.hxx>
63 #include <svx/frmdiritem.hxx>
64 #include <svx/adjitem.hxx>
65 #include <svx/eeitem.hxx>
66 #include <svx/msoleexp.hxx>
68 #include <svtools/useroptions.hxx>
69 #include <unotools/localedatawrapper.hxx>
71 #include <stdio.h>
73 #include "document.hxx"
74 #include "conditio.hxx"
75 #include "rangelst.hxx"
76 #include "stlpool.hxx"
77 #include "viewopti.hxx"
78 #include "scextopt.hxx"
79 #include "docoptio.hxx"
80 #include "patattr.hxx"
81 #include "tabprotection.hxx"
83 #include <oox/core/tokens.hxx>
85 using ::rtl::OString;
86 using ::rtl::OUString;
87 using namespace ::com::sun::star;
88 using ::com::sun::star::uno::Reference;
89 using ::com::sun::star::uno::UNO_QUERY;
90 using ::com::sun::star::beans::XPropertySet;
91 using ::com::sun::star::drawing::XShape;
94 //___________________________________________________________________
96 // --- class XclMsodrawing_Base --------------------------------------
98 XclMsodrawing_Base::XclMsodrawing_Base( XclEscher& rEscher, sal_Size nInitialSize )
100 pEscher( &rEscher ),
101 nStartPos( rEscher.GetEx()->GetLastOffsetMapPos() )
103 // for safety's sake add this now
104 nStopPos = GetEscherEx()->AddCurrentOffsetToMap();
105 (void)nInitialSize; // avoid compiler warning
106 DBG_ASSERT( GetDataLen() == nInitialSize, "XclMsodrawing_Base ctor: do I really own that data?" );
110 XclMsodrawing_Base::~XclMsodrawing_Base()
115 void XclMsodrawing_Base::UpdateStopPos()
117 if ( nStopPos > 0 )
118 GetEscherEx()->ReplaceCurrentOffsetInMap( nStopPos );
119 else
120 nStopPos = GetEscherEx()->AddCurrentOffsetToMap();
124 sal_Size XclMsodrawing_Base::GetDataLen() const
126 if ( nStartPos < nStopPos )
128 XclEscherEx* pEx = GetEscherEx();
129 return pEx->GetOffsetFromMap( nStopPos ) - pEx->GetOffsetFromMap( nStartPos );
131 DBG_ERRORFILE( "XclMsodrawing_Base::GetDataLen: position mismatch" );
132 return 0;
137 // --- class XclMsodrawinggroup --------------------------------------
139 XclMsodrawinggroup::XclMsodrawinggroup( RootData& rRoot, UINT16 nEscherType ) :
140 XclMsodrawing_Base( *rRoot.pEscher ),
141 XclExpRecord(0x00EB, 2) // bogus record size since we don't know the actual size yet.
143 if ( nEscherType )
145 XclEscherEx* pEx = GetEscherEx();
146 SvStream& rOut = pEx->GetStream();
147 switch ( nEscherType )
149 case ESCHER_DggContainer :
150 { // per-document data
151 pEx->OpenContainer( nEscherType );
152 //2do: stuff it with our own document defaults?
153 #if 0
154 pEx->BeginCount();
155 pEx->AddOpt( ... );
156 pEx->EndCount( ESCHER_OPT, 3 );
157 #else
158 BYTE pDummyOPT[] = {
159 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
160 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
161 0x00, 0x08
163 pEx->AddAtom( sizeof(pDummyOPT), ESCHER_OPT, 3, 3 );
164 rOut.Write( pDummyOPT, sizeof(pDummyOPT) );
165 #endif
166 BYTE pDummySplitMenuColors[] = {
167 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
168 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
170 pEx->AddAtom( sizeof(pDummySplitMenuColors), ESCHER_SplitMenuColors, 0, 4 );
171 rOut.Write( pDummySplitMenuColors, sizeof(pDummySplitMenuColors) );
172 pEx->CloseContainer(); // ESCHER_DggContainer
174 break;
176 UpdateStopPos();
181 XclMsodrawinggroup::~XclMsodrawinggroup()
186 void XclMsodrawinggroup::WriteBody( XclExpStream& rStrm )
188 DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ),
189 "XclMsodrawinggroup::SaveCont: Escher stream position mismatch" );
190 rStrm.CopyFromStream( pEscher->GetStrm(), GetDataLen() );
194 // --- class XclMsodrawing --------------------------------------
196 XclMsodrawing::XclMsodrawing( const XclExpRoot& rRoot, UINT16 nEscherType, sal_Size nInitialSize ) :
197 XclMsodrawing_Base( *rRoot.GetOldRoot().pEscher, nInitialSize ),
198 XclExpRecord( 0x00EC, nInitialSize )
200 if ( nEscherType )
202 XclEscherEx* pEx = GetEscherEx();
203 switch ( nEscherType )
205 case ESCHER_DgContainer :
206 { // per-sheet data
207 pEx->OpenContainer( nEscherType );
208 // open group shape container
209 Rectangle aRect( 0, 0, 0, 0 );
210 pEx->EnterGroup( &aRect );
212 break;
214 UpdateStopPos();
219 XclMsodrawing::~XclMsodrawing()
224 void XclMsodrawing::WriteBody( XclExpStream& rStrm )
226 DBG_ASSERT( GetEscherEx()->GetStreamPos() == GetEscherEx()->GetOffsetFromMap( nStartPos ),
227 "XclMsodrawing::SaveCont: Escher stream position mismatch" );
228 rStrm.CopyFromStream( pEscher->GetStrm(), GetDataLen() );
234 // --- class XclObjList ----------------------------------------------
236 XclObjList::XclObjList( const XclExpRoot& rRoot ) :
237 XclExpRoot( rRoot ),
238 pMsodrawingPerSheet( new XclMsodrawing( rRoot, ESCHER_DgContainer ) ),
239 pSolverContainer( NULL )
244 XclObjList::~XclObjList()
246 for ( XclObj* p = First(); p; p = Next() )
247 delete p;
248 delete pMsodrawingPerSheet;
249 delete pSolverContainer;
253 UINT16 XclObjList::Add( XclObj* pObj )
255 DBG_ASSERT( Count() < 0xFFFF, "XclObjList::Add: too much for Xcl" );
256 if ( Count() < 0xFFFF )
258 Insert( pObj, LIST_APPEND );
259 UINT16 nCnt = (UINT16) Count();
260 pObj->SetId( nCnt );
261 return nCnt;
263 else
265 delete pObj;
266 return 0;
271 void XclObjList::EndSheet()
273 XclEscherEx* pEx = pMsodrawingPerSheet->GetEscherEx();
275 // Is there still something in the stream? -> The solver container
276 sal_Size nSolverSize = pEx->GetStreamPos() - pEx->GetOffsetFromMap( pEx->GetLastOffsetMapPos() );
277 if( nSolverSize > 0 )
278 pSolverContainer = new XclMsodrawing( GetRoot(), ESCHER_SolverContainer, nSolverSize );
280 //! close ESCHER_DgContainer created by XclObjList ctor MSODRAWING
281 pEx->CloseContainer();
285 void XclObjList::Save( XclExpStream& rStrm )
287 //! Escher must be written, even if there are no objects
288 pMsodrawingPerSheet->Save( rStrm );
290 for ( XclObj* p = First(); p; p = Next() )
291 p->Save( rStrm );
293 if( pSolverContainer )
294 pSolverContainer->Save( rStrm );
299 // --- class XclObj --------------------------------------------------
301 XclObj::XclObj( const XclExpRoot& rRoot, sal_uInt16 nObjType, bool bOwnEscher ) :
302 XclExpRecord( EXC_ID_OBJ, 26 ),
303 pClientTextbox( NULL ),
304 pTxo( NULL ),
305 mnObjType( nObjType ),
306 nObjId(0),
307 nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked
308 bFirstOnSheet( rRoot.GetOldRoot().pObjRecs->Count() == 0 ),
309 mbOwnEscher( bOwnEscher )
311 //! first object continues the first MSODRAWING record
312 if ( bFirstOnSheet )
313 pMsodrawing = rRoot.GetOldRoot().pObjRecs->GetMsodrawingPerSheet();
314 else
315 pMsodrawing = new XclMsodrawing( rRoot );
319 XclObj::~XclObj()
321 if ( !bFirstOnSheet )
322 delete pMsodrawing;
323 delete pClientTextbox;
324 delete pTxo;
328 void XclObj::SetEscherShapeType( UINT16 nType )
330 //2do: what about the other defined ot... types?
331 switch ( nType )
333 case ESCHER_ShpInst_Line :
334 mnObjType = EXC_OBJTYPE_LINE;
335 break;
336 case ESCHER_ShpInst_Rectangle :
337 case ESCHER_ShpInst_RoundRectangle :
338 mnObjType = EXC_OBJTYPE_RECTANGLE;
339 break;
340 case ESCHER_ShpInst_Ellipse :
341 mnObjType = EXC_OBJTYPE_OVAL;
342 break;
343 case ESCHER_ShpInst_Arc :
344 mnObjType = EXC_OBJTYPE_ARC;
345 break;
346 case ESCHER_ShpInst_TextBox :
347 mnObjType = EXC_OBJTYPE_TEXT;
348 break;
349 case ESCHER_ShpInst_PictureFrame :
350 mnObjType = EXC_OBJTYPE_PICTURE;
351 break;
352 default:
353 mnObjType = EXC_OBJTYPE_DRAWING;
358 void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj )
360 DBG_ASSERT( !pClientTextbox, "XclObj::SetText: already set" );
361 if ( !pClientTextbox )
363 pMsodrawing->UpdateStopPos();
364 pClientTextbox = new XclMsodrawing( rRoot );
365 pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
366 pClientTextbox->UpdateStopPos();
367 pTxo = new XclTxo( rRoot, rObj );
372 void XclObj::WriteBody( XclExpStream& rStrm )
374 DBG_ASSERT( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" );
376 // create a substream to be able to create subrecords
377 SvMemoryStream aMemStrm;
378 ::std::auto_ptr< XclExpStream > pXclStrm( new XclExpStream( aMemStrm, rStrm.GetRoot() ) );
380 // write the ftCmo subrecord
381 pXclStrm->StartRecord( EXC_ID_OBJCMO, 18 );
382 *pXclStrm << mnObjType << nObjId << nGrbit;
383 pXclStrm->WriteZeroBytes( 12 );
384 pXclStrm->EndRecord();
386 // write other subrecords
387 WriteSubRecs( *pXclStrm );
389 // write the ftEnd subrecord
390 pXclStrm->StartRecord( EXC_ID_OBJEND, 0 );
391 pXclStrm->EndRecord();
393 // copy the data to the OBJ record
394 pXclStrm.reset();
395 aMemStrm.Seek( 0 );
396 rStrm.CopyFromStream( aMemStrm );
400 void XclObj::Save( XclExpStream& rStrm )
402 // MSODRAWING record (msofbtSpContainer)
403 if ( !bFirstOnSheet )
404 pMsodrawing->Save( rStrm );
406 // OBJ
407 XclExpRecord::Save( rStrm );
409 // second MSODRAWING record and TXO and CONTINUE records
410 SaveTextRecs( rStrm );
414 void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ )
418 void XclObj::SaveTextRecs( XclExpStream& rStrm )
420 // MSODRAWING record (msofbtClientTextbox)
421 if ( pClientTextbox )
422 pClientTextbox->Save( rStrm );
423 // TXO and CONTINUE records
424 if ( pTxo )
425 pTxo->Save( rStrm );
429 // --- class XclObjComment -------------------------------------------
432 XclObjComment::XclObjComment( const XclExpRoot& rRoot, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible )
434 XclObj( rRoot, EXC_OBJTYPE_NOTE, true )
436 ProcessEscherObj(rRoot, rRect, pCaption, bVisible);
437 // TXO
438 pTxo = new XclTxo( rRoot, rEditObj, pCaption );
441 void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible )
443 Reference<XShape> aXShape;
444 EscherPropertyContainer aPropOpt;
446 if(pCaption)
448 aXShape = GetXShapeForSdrObject(pCaption);
449 Reference< XPropertySet > aXPropSet( aXShape, UNO_QUERY );
450 if( aXPropSet.is() )
452 aPropOpt.CreateFillProperties( aXPropSet, sal_True);
454 aPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // undocumented
455 aPropOpt.AddOpt( 0x0158, 0x00000000 ); // undocumented
457 sal_uInt32 nValue = 0;
458 if(!aPropOpt.GetOpt( ESCHER_Prop_FitTextToShape, nValue ))
459 aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
461 if(aPropOpt.GetOpt( ESCHER_Prop_fillColor, nValue ))
463 // If the Colour is the same as the 'ToolTip' System colour then
464 // use the default rather than the explicit colour value. This will
465 // be incorrect where user has chosen to use this colour explicity.
466 Color aColor = Color( (BYTE)nValue, (BYTE)( nValue >> 8 ), (BYTE)( nValue >> 16 ) );
467 const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
468 if(aColor == rSett.GetHelpColor().GetColor())
470 aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
471 aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
474 else
475 aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
477 if(!aPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nValue ))
478 aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
479 if(!aPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ))
480 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 ); // bool field
481 if(!aPropOpt.GetOpt( ESCHER_Prop_shadowColor, nValue ))
482 aPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x00000000 );
483 if(!aPropOpt.GetOpt( ESCHER_Prop_fshadowObscured, nValue )) // bool field
484 aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // bool field
488 nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked
489 XclEscherEx* pEx = pMsodrawing->GetEscherEx();
490 pEx->OpenContainer( ESCHER_SpContainer );
491 pEx->AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
492 sal_uInt32 nFlags = 0x000A0000;
493 ::set_flag( nFlags, sal_uInt32(2), !bVisible );
494 aPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field
495 aPropOpt.Commit( pEx->GetStream() );
497 XclExpDffNoteAnchor( rRoot, rRect ).WriteData( *pEx);
499 pEx->AddAtom( 0, ESCHER_ClientData ); // OBJ record
500 pMsodrawing->UpdateStopPos();
501 //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the
502 //! base OBJ's MSODRAWING record Escher data is completed.
503 pClientTextbox = new XclMsodrawing( rRoot );
504 pClientTextbox->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
505 pClientTextbox->UpdateStopPos();
506 pEx->CloseContainer(); // ESCHER_SpContainer
510 XclObjComment::~XclObjComment()
515 void XclObjComment::Save( XclExpStream& rStrm )
517 // content of this record
518 XclObj::Save( rStrm );
522 // --- class XclObjDropDown ------------------------------------------
524 XclObjDropDown::XclObjDropDown( const XclExpRoot& rRoot, const ScAddress& rPos, BOOL bFilt ) :
525 XclObj( rRoot, EXC_OBJTYPE_DROPDOWN, true ),
526 bIsFiltered( bFilt )
528 SetLocked( TRUE );
529 SetPrintable( FALSE );
530 SetAutoFill( TRUE );
531 SetAutoLine( FALSE );
532 nGrbit |= 0x0100; // undocumented
533 XclEscherEx* pEx = pMsodrawing->GetEscherEx();
534 pEx->OpenContainer( ESCHER_SpContainer );
535 pEx->AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
536 EscherPropertyContainer aPropOpt;
537 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field
538 aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
539 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field
540 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
541 aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field
542 aPropOpt.Commit( pEx->GetStream() );
544 XclExpDffDropDownAnchor( rRoot, rPos ).WriteData( *pEx );
546 pEx->AddAtom( 0, ESCHER_ClientData ); // OBJ record
547 pMsodrawing->UpdateStopPos();
548 pEx->CloseContainer(); // ESCHER_SpContainer
550 // old size + ftSbs + ftLbsData
551 AddRecSize( 24 + 20 );
554 XclObjDropDown::~XclObjDropDown()
558 void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm )
560 // ftSbs subrecord - Scroll bars (dummy)
561 rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
562 rStrm.WriteZeroBytes( 20 );
563 rStrm.EndRecord();
565 // ftLbsData subrecord - Listbox data
566 sal_uInt16 nDropDownFlags = 0;
567 ::insert_value( nDropDownFlags, EXC_OBJ_DROPDOWN_SIMPLE, 0, 2 );
568 ::set_flag( nDropDownFlags, EXC_OBJ_DROPDOWN_FILTERED, bIsFiltered );
569 rStrm.StartRecord( EXC_ID_OBJLBSDATA, 16 );
570 rStrm << (UINT32)0 << (UINT16)0 << (UINT16)0x0301 << (UINT16)0
571 << nDropDownFlags << sal_uInt16( 20 ) << sal_uInt16( 130 );
572 rStrm.EndRecord();
576 // --- class XclTxo --------------------------------------------------
578 sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet )
580 sal_uInt8 nHorAlign = EXC_OBJ_HOR_LEFT;
582 switch( static_cast< const SvxAdjustItem& >( rItemSet.Get( EE_PARA_JUST ) ).GetAdjust() )
584 case SVX_ADJUST_LEFT: nHorAlign = EXC_OBJ_HOR_LEFT; break;
585 case SVX_ADJUST_CENTER: nHorAlign = EXC_OBJ_HOR_CENTER; break;
586 case SVX_ADJUST_RIGHT: nHorAlign = EXC_OBJ_HOR_RIGHT; break;
587 case SVX_ADJUST_BLOCK: nHorAlign = EXC_OBJ_HOR_JUSTIFY; break;
588 default:;
590 return nHorAlign;
593 sal_uInt8 lcl_GetVerAlignFromItemSet( const SfxItemSet& rItemSet )
595 sal_uInt8 nVerAlign = EXC_OBJ_VER_TOP;
597 switch( static_cast< const SdrTextVertAdjustItem& >( rItemSet.Get( SDRATTR_TEXT_VERTADJUST ) ).GetValue() )
599 case SDRTEXTVERTADJUST_TOP: nVerAlign = EXC_OBJ_VER_TOP; break;
600 case SDRTEXTVERTADJUST_CENTER: nVerAlign = EXC_OBJ_VER_CENTER; break;
601 case SDRTEXTVERTADJUST_BOTTOM: nVerAlign = EXC_OBJ_VER_BOTTOM; break;
602 case SDRTEXTVERTADJUST_BLOCK: nVerAlign = EXC_OBJ_VER_JUSTIFY; break;
604 return nVerAlign;
607 XclTxo::XclTxo( const String& rString, sal_uInt16 nFontIx ) :
608 mpString( new XclExpString( rString ) ),
609 mnRotation( EXC_OBJ_ORIENT_NONE ),
610 mnHorAlign( EXC_OBJ_HOR_LEFT ),
611 mnVerAlign( EXC_OBJ_VER_TOP )
613 if( mpString->Len() )
615 // If there is text, Excel *needs* the 2nd CONTINUE record with at least two format runs
616 mpString->AppendFormat( 0, nFontIx );
617 mpString->AppendFormat( mpString->Len(), EXC_FONT_APP );
621 XclTxo::XclTxo( const XclExpRoot& rRoot, const SdrTextObj& rTextObj ) :
622 mpString( XclExpStringHelper::CreateString( rRoot, rTextObj ) ),
623 mnRotation( EXC_OBJ_ORIENT_NONE ),
624 mnHorAlign( EXC_OBJ_HOR_LEFT ),
625 mnVerAlign( EXC_OBJ_VER_TOP )
627 // additional alignment and orientation items
628 const SfxItemSet& rItemSet = rTextObj.GetMergedItemSet();
630 // horizontal alignment
631 SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
633 // vertical alignment
634 SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
636 // rotation
637 long nAngle = rTextObj.GetRotateAngle();
638 if( (4500 < nAngle) && (nAngle < 13500) )
639 mnRotation = EXC_OBJ_ORIENT_90CCW;
640 else if( (22500 < nAngle) && (nAngle < 31500) )
641 mnRotation = EXC_OBJ_ORIENT_90CW;
642 else
643 mnRotation = EXC_OBJ_ORIENT_NONE;
646 XclTxo::XclTxo( const XclExpRoot& rRoot, const EditTextObject& rEditObj, SdrObject* pCaption ) :
647 mpString( XclExpStringHelper::CreateString( rRoot, rEditObj ) ),
648 mnRotation( EXC_OBJ_ORIENT_NONE ),
649 mnHorAlign( EXC_OBJ_HOR_LEFT ),
650 mnVerAlign( EXC_OBJ_VER_TOP )
652 if(pCaption)
654 // Excel has one alignment per NoteObject while Calc supports
655 // one alignment per paragraph - use the first paragraph
656 // alignment (if set) as our overall alignment.
657 String aParaText( rEditObj.GetText( 0 ) );
658 if( aParaText.Len() )
660 SfxItemSet aSet( rEditObj.GetParaAttribs( 0));
661 const SfxPoolItem* pItem = NULL;
662 if( aSet.GetItemState( EE_PARA_JUST, TRUE, &pItem ) == SFX_ITEM_SET )
664 SvxAdjust eEEAlign = static_cast< const SvxAdjustItem& >( *pItem ).GetAdjust();
665 pCaption->SetMergedItem( SvxAdjustItem( eEEAlign, EE_PARA_JUST ) );
668 const SfxItemSet& rItemSet = pCaption->GetMergedItemSet();
670 // horizontal alignment
671 SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
673 // vertical alignment
674 SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
676 // orientation alignment
677 const SvxWritingModeItem& rItem = static_cast< const SvxWritingModeItem& >( rItemSet.Get( SDRATTR_TEXTDIRECTION ) );
678 if( rItem.GetValue() == com::sun::star::text::WritingMode_TB_RL )
679 mnRotation = EXC_OBJ_ORIENT_90CW;
683 void XclTxo::SaveCont( XclExpStream& rStrm )
685 DBG_ASSERT( mpString.get(), "XclTxo::SaveCont - missing string" );
687 // #i96858# do not save existing string formatting if text is empty
688 sal_uInt16 nRunLen = mpString->IsEmpty() ? 0 : (8 * mpString->GetFormatsCount());
689 // alignment
690 sal_uInt16 nFlags = 0;
691 ::insert_value( nFlags, mnHorAlign, 1, 3 );
692 ::insert_value( nFlags, mnVerAlign, 4, 3 );
694 rStrm << nFlags << mnRotation;
695 rStrm.WriteZeroBytes( 6 );
696 rStrm << mpString->Len() << nRunLen << sal_uInt32( 0 );
699 void XclTxo::Save( XclExpStream& rStrm )
701 // Write the TXO part
702 ExcRecord::Save( rStrm );
704 // CONTINUE records are only written if there is some text
705 if( !mpString->IsEmpty() )
707 // CONTINUE for character array
708 rStrm.StartRecord( EXC_ID_CONT, mpString->GetBufferSize() + 1 );
709 rStrm << static_cast< sal_uInt8 >( mpString->GetFlagField() & EXC_STRF_16BIT ); // only Unicode flag
710 mpString->WriteBuffer( rStrm );
711 rStrm.EndRecord();
713 // CONTINUE for formatting runs
714 rStrm.StartRecord( EXC_ID_CONT, 8 * mpString->GetFormatsCount() );
715 const XclFormatRunVec& rFormats = mpString->GetFormats();
716 for( XclFormatRunVec::const_iterator aIt = rFormats.begin(), aEnd = rFormats.end(); aIt != aEnd; ++aIt )
717 rStrm << aIt->mnChar << aIt->mnFontIdx << sal_uInt32( 0 );
718 rStrm.EndRecord();
722 UINT16 XclTxo::GetNum() const
724 return EXC_ID_TXO;
727 sal_Size XclTxo::GetLen() const
729 return 18;
733 // --- class XclObjOle -------------------------------------------
735 XclObjOle::XclObjOle( const XclExpRoot& rRoot, const SdrObject& rObj ) :
736 XclObj( rRoot, EXC_OBJTYPE_PICTURE ),
737 rOleObj( rObj ),
738 pRootStorage( rRoot.GetRootStorage() )
743 XclObjOle::~XclObjOle()
748 void XclObjOle::WriteSubRecs( XclExpStream& rStrm )
750 // write only as embedded, not linked
751 String aStorageName( RTL_CONSTASCII_USTRINGPARAM( "MBD" ) );
752 sal_Char aBuf[ sizeof(UINT32) * 2 + 1 ];
753 // FIXME Eeek! Is this just a way to get a unique id?
754 UINT32 nPictureId = UINT32(sal_uIntPtr(this) >> 2);
755 sprintf( aBuf, "%08X", static_cast< unsigned int >( nPictureId ) ); // #100211# - checked
756 aStorageName.AppendAscii( aBuf );
757 SotStorageRef xOleStg = pRootStorage->OpenSotStorage( aStorageName,
758 STREAM_READWRITE| STREAM_SHARE_DENYALL );
759 if( xOleStg.Is() )
761 uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj&)rOleObj).GetObjRef() );
762 if ( xObj.is() )
764 // set version to "old" version, because it must be
765 // saved in MS notation.
766 UINT32 nFl = 0;
767 SvtFilterOptions* pFltOpts = SvtFilterOptions::Get();
768 if( pFltOpts )
770 if( pFltOpts->IsMath2MathType() )
771 nFl |= OLE_STARMATH_2_MATHTYPE;
773 if( pFltOpts->IsWriter2WinWord() )
774 nFl |= OLE_STARWRITER_2_WINWORD;
776 if( pFltOpts->IsCalc2Excel() )
777 nFl |= OLE_STARCALC_2_EXCEL;
779 if( pFltOpts->IsImpress2PowerPoint() )
780 nFl |= OLE_STARIMPRESS_2_POWERPOINT;
783 SvxMSExportOLEObjects aOLEExpFilt( nFl );
784 aOLEExpFilt.ExportOLEObject( xObj, *xOleStg );
786 // OBJCF subrecord, undocumented as usual
787 rStrm.StartRecord( EXC_ID_OBJCF, 2 );
788 rStrm << UINT16(0x0002);
789 rStrm.EndRecord();
791 // OBJFLAGS subrecord, undocumented as usual
792 rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
793 sal_uInt16 nFlags = EXC_OBJ_PIC_MANUALSIZE;
794 ::set_flag( nFlags, EXC_OBJ_PIC_SYMBOL, ((SdrOle2Obj&)rOleObj).GetAspect() == embed::Aspects::MSOLE_ICON );
795 rStrm << nFlags;
796 rStrm.EndRecord();
798 // OBJPICTFMLA subrecord, undocumented as usual
799 XclExpString aName( xOleStg->GetUserName() );
800 UINT16 nPadLen = (UINT16)(aName.GetSize() & 0x01);
801 UINT16 nFmlaLen = static_cast< sal_uInt16 >( 12 + aName.GetSize() + nPadLen );
802 UINT16 nSubRecLen = nFmlaLen + 6;
804 rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nSubRecLen );
805 rStrm << nFmlaLen
806 << sal_uInt16( 5 ) << sal_uInt32( 0 ) << sal_uInt8( 2 )
807 << sal_uInt32( 0 ) << sal_uInt8( 3 )
808 << aName;
809 if( nPadLen )
810 rStrm << sal_uInt8( 0 ); // pad byte
811 rStrm << nPictureId;
812 rStrm.EndRecord();
818 void XclObjOle::Save( XclExpStream& rStrm )
820 // content of this record
821 XclObj::Save( rStrm );
825 // --- class XclObjAny -------------------------------------------
827 XclObjAny::XclObjAny( const XclExpRoot& rRoot ) :
828 XclObj( rRoot, EXC_OBJTYPE_UNKNOWN )
832 XclObjAny::~XclObjAny()
836 void XclObjAny::WriteSubRecs( XclExpStream& rStrm )
838 if( mnObjType == EXC_OBJTYPE_GROUP )
839 // ftGmo subrecord
840 rStrm << EXC_ID_OBJGMO << UINT16(2) << UINT16(0);
843 void XclObjAny::Save( XclExpStream& rStrm )
845 if( mnObjType == EXC_OBJTYPE_GROUP )
846 // old size + ftGmo
847 AddRecSize( 6 );
849 // content of this record
850 XclObj::Save( rStrm );
854 // --- class ExcBof8_Base --------------------------------------------
856 ExcBof8_Base::ExcBof8_Base()
858 nVers = 0x0600;
859 nRupBuild = 0x0dbb;
860 nRupYear = 0x07cc;
861 // nFileHistory = 0x00000001; // last edited by Microsoft Excel for Windows
862 nFileHistory = 0x00000000;
863 nLowestBiffVer = 0x00000006; // Biff8
867 void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
869 rStrm.DisableEncryption();
870 rStrm << nVers << nDocType << nRupBuild << nRupYear
871 << nFileHistory << nLowestBiffVer;
875 UINT16 ExcBof8_Base::GetNum() const
877 return 0x0809;
881 sal_Size ExcBof8_Base::GetLen() const
883 return 16;
887 // --- class ExcBof8 -------------------------------------------------
889 ExcBof8::ExcBof8()
891 nDocType = 0x0010;
895 // --- class ExcBofW8 ------------------------------------------------
897 ExcBofW8::ExcBofW8()
899 nDocType = 0x0005;
903 // --- class ExcBundlesheet8 -----------------------------------------
905 ExcBundlesheet8::ExcBundlesheet8( RootData& rRootData, SCTAB _nTab ) :
906 ExcBundlesheetBase( rRootData, static_cast<sal_uInt16>(_nTab) ),
907 sUnicodeName( rRootData.pER->GetTabInfo().GetScTabName( _nTab ) )
912 ExcBundlesheet8::ExcBundlesheet8( const String& rString ) :
913 ExcBundlesheetBase(),
914 sUnicodeName( rString )
919 XclExpString ExcBundlesheet8::GetName() const
921 return XclExpString( sUnicodeName, EXC_STR_8BITLENGTH );
925 void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
927 nOwnPos = rStrm.GetSvStreamPos();
928 // write dummy position, real position comes later
929 rStrm.DisableEncryption();
930 rStrm << sal_uInt32(0);
931 rStrm.EnableEncryption();
932 rStrm << nGrbit << GetName();
936 sal_Size ExcBundlesheet8::GetLen() const
937 { // Text max 255 chars
938 return 8 + GetName().GetBufferSize();
942 void ExcBundlesheet8::SaveXml( XclExpXmlStream& rStrm )
944 OUString sId;
945 rStrm.CreateOutputStream(
946 XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", nTab+1),
947 XclXmlUtils::GetStreamName( NULL, "worksheets/sheet", nTab+1),
948 rStrm.GetCurrentStream()->getOutputStream(),
949 "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
950 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
951 &sId );
953 rStrm.GetCurrentStream()->singleElement( XML_sheet,
954 XML_name, XclXmlUtils::ToOString( sUnicodeName ).getStr(),
955 XML_sheetId, rtl::OString::valueOf( (sal_Int32)( nTab+1 ) ).getStr(),
956 XML_state, nGrbit == 0x0000 ? "visible" : "hidden",
957 FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
958 FSEND );
963 // --- class XclObproj -----------------------------------------------
965 UINT16 XclObproj::GetNum() const
967 return 0x00D3;
971 sal_Size XclObproj::GetLen() const
973 return 0;
977 // ---- class XclCodename --------------------------------------------
979 XclCodename::XclCodename( const String& r ) : aName( r )
984 void XclCodename::SaveCont( XclExpStream& rStrm )
986 rStrm << aName;
990 UINT16 XclCodename::GetNum() const
992 return 0x01BA;
996 sal_Size XclCodename::GetLen() const
998 return aName.GetSize();
1003 // ---- Scenarios ----------------------------------------------------
1005 ExcEScenarioCell::ExcEScenarioCell( UINT16 nC, UINT16 nR, const String& rTxt ) :
1006 nCol( nC ),
1007 nRow( nR ),
1008 sText( rTxt, EXC_STR_DEFAULT, 255 )
1012 void ExcEScenarioCell::WriteAddress( XclExpStream& rStrm )
1014 rStrm << nRow << nCol;
1017 void ExcEScenarioCell::WriteText( XclExpStream& rStrm )
1019 rStrm << sText;
1022 void ExcEScenarioCell::SaveXml( XclExpXmlStream& rStrm )
1024 rStrm.GetCurrentStream()->singleElement( XML_inputCells,
1025 // OOXTODO: XML_deleted,
1026 // OOXTODO: XML_numFmtId,
1027 XML_r, XclXmlUtils::ToOString( ScAddress( nCol, nRow, 0 ) ).getStr(),
1028 // OOXTODO: XML_undone,
1029 XML_val, XclXmlUtils::ToOString( sText ).getStr(),
1030 FSEND );
1036 XclExpString ExcEScenario::sUsername;
1038 ExcEScenario::ExcEScenario( ScDocument& rDoc, SCTAB nTab )
1040 String sTmpName;
1041 String sTmpComm;
1042 Color aDummyCol;
1043 USHORT nFlags;
1045 rDoc.GetName( nTab, sTmpName );
1046 sName.Assign( sTmpName, EXC_STR_8BITLENGTH );
1047 nRecLen = 8 + sName.GetBufferSize();
1049 rDoc.GetScenarioData( nTab, sTmpComm, aDummyCol, nFlags );
1050 sComment.Assign( sTmpComm, EXC_STR_DEFAULT, 255 );
1051 if( sComment.Len() )
1052 nRecLen += sComment.GetSize();
1053 nProtected = (nFlags & SC_SCENARIO_PROTECT) ? 1 : 0;
1055 if( !sUsername.Len() )
1057 SvtUserOptions aUserOpt;
1058 sUsername.Assign( aUserOpt.GetLastName(), EXC_STR_DEFAULT, 255 );
1060 if( !sUsername.Len() )
1061 sUsername.Assign( String::CreateFromAscii( "SC" ) );
1062 nRecLen += sUsername.GetSize();
1064 const ScRangeList* pRList = rDoc.GetScenarioRanges( nTab );
1065 if( !pRList )
1066 return;
1068 BOOL bContLoop = TRUE;
1069 SCROW nRow;
1070 SCCOL nCol;
1071 String sText;
1072 double fVal;
1074 for( UINT32 nRange = 0; (nRange < pRList->Count()) && bContLoop; nRange++ )
1076 const ScRange* pRange = pRList->GetObject( nRange );
1077 for( nRow = pRange->aStart.Row(); (nRow <= pRange->aEnd.Row()) && bContLoop; nRow++ )
1078 for( nCol = pRange->aStart.Col(); (nCol <= pRange->aEnd.Col()) && bContLoop; nCol++ )
1080 if( rDoc.HasValueData( nCol, nRow, nTab ) )
1082 rDoc.GetValue( nCol, nRow, nTab, fVal );
1083 sText = ::rtl::math::doubleToUString( fVal,
1084 rtl_math_StringFormat_Automatic,
1085 rtl_math_DecimalPlaces_Max,
1086 ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0),
1087 TRUE );
1089 else
1090 rDoc.GetString( nCol, nRow, nTab, sText );
1091 bContLoop = Append( static_cast<sal_uInt16>(nCol),
1092 static_cast<sal_uInt16>(nRow), sText );
1097 ExcEScenario::~ExcEScenario()
1099 for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
1100 delete pCell;
1103 BOOL ExcEScenario::Append( UINT16 nCol, UINT16 nRow, const String& rTxt )
1105 if( List::Count() == EXC_SCEN_MAXCELL )
1106 return FALSE;
1108 ExcEScenarioCell* pCell = new ExcEScenarioCell( nCol, nRow, rTxt );
1109 List::Insert( pCell, LIST_APPEND );
1110 nRecLen += 6 + pCell->GetStringBytes(); // 4 bytes address, 2 bytes ifmt
1111 return TRUE;
1114 void ExcEScenario::SaveCont( XclExpStream& rStrm )
1116 rStrm << (UINT16) List::Count() // number of cells
1117 << nProtected // fProtection
1118 << (UINT8) 0 // fHidden
1119 << (UINT8) sName.Len() // length of scen name
1120 << (UINT8) sComment.Len() // length of comment
1121 << (UINT8) sUsername.Len(); // length of user name
1122 sName.WriteFlagField( rStrm );
1123 sName.WriteBuffer( rStrm );
1125 rStrm << sUsername;
1127 if( sComment.Len() )
1128 rStrm << sComment;
1130 ExcEScenarioCell* pCell;
1131 for( pCell = _First(); pCell; pCell = _Next() )
1132 pCell->WriteAddress( rStrm ); // pos of cell
1133 for( pCell = _First(); pCell; pCell = _Next() )
1134 pCell->WriteText( rStrm ); // string content
1135 rStrm.SetSliceSize( 2 );
1136 rStrm.WriteZeroBytes( 2 * List::Count() ); // date format
1139 UINT16 ExcEScenario::GetNum() const
1141 return 0x00AF;
1144 sal_Size ExcEScenario::GetLen() const
1146 return nRecLen;
1149 void ExcEScenario::SaveXml( XclExpXmlStream& rStrm )
1151 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
1152 rWorkbook->startElement( XML_scenario,
1153 XML_name, XclXmlUtils::ToOString( sName ).getStr(),
1154 XML_locked, XclXmlUtils::ToPsz( nProtected ),
1155 // OOXTODO: XML_hidden,
1156 XML_count, OString::valueOf( (sal_Int32) List::Count() ).getStr(),
1157 XML_user, XESTRING_TO_PSZ( sUsername ),
1158 XML_comment, XESTRING_TO_PSZ( sComment ),
1159 FSEND );
1161 for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
1162 pCell->SaveXml( rStrm );
1164 rWorkbook->endElement( XML_scenario );
1170 ExcEScenarioManager::ExcEScenarioManager( ScDocument& rDoc, SCTAB nTab ) :
1171 nActive( 0 )
1173 if( rDoc.IsScenario( nTab ) )
1174 return;
1176 SCTAB nFirstTab = nTab + 1;
1177 SCTAB nNewTab = nFirstTab;
1179 while( rDoc.IsScenario( nNewTab ) )
1181 Append( new ExcEScenario( rDoc, nNewTab ) );
1183 if( rDoc.IsActiveScenario( nNewTab ) )
1184 nActive = static_cast<sal_uInt16>(nNewTab - nFirstTab);
1185 nNewTab++;
1189 ExcEScenarioManager::~ExcEScenarioManager()
1191 for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
1192 delete pScen;
1195 void ExcEScenarioManager::SaveCont( XclExpStream& rStrm )
1197 rStrm << (UINT16) List::Count() // number of scenarios
1198 << nActive // active scen
1199 << nActive // last displayed
1200 << (UINT16) 0; // reference areas
1203 void ExcEScenarioManager::Save( XclExpStream& rStrm )
1205 if( List::Count() )
1206 ExcRecord::Save( rStrm );
1208 for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
1209 pScen->Save( rStrm );
1212 void ExcEScenarioManager::SaveXml( XclExpXmlStream& rStrm )
1214 if( ! List::Count() )
1215 return;
1217 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
1218 rWorkbook->startElement( XML_scenarios,
1219 XML_current, OString::valueOf( (sal_Int32)nActive ).getStr(),
1220 XML_show, OString::valueOf( (sal_Int32)nActive ).getStr(),
1221 // OOXTODO: XML_sqref,
1222 FSEND );
1224 for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
1225 pScen->SaveXml( rStrm );
1227 rWorkbook->endElement( XML_scenarios );
1230 UINT16 ExcEScenarioManager::GetNum() const
1232 return 0x00AE;
1235 sal_Size ExcEScenarioManager::GetLen() const
1237 return 8;
1240 // ============================================================================
1242 struct XclExpTabProtectOption
1244 ScTableProtection::Option eOption;
1245 sal_uInt16 nMask;
1248 XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
1249 XclExpRecord( 0x0867, 23 )
1251 static const XclExpTabProtectOption aTable[] =
1253 { ScTableProtection::OBJECTS, 0x0001 },
1254 { ScTableProtection::SCENARIOS, 0x0002 },
1255 { ScTableProtection::FORMAT_CELLS, 0x0004 },
1256 { ScTableProtection::FORMAT_COLUMNS, 0x0008 },
1257 { ScTableProtection::FORMAT_ROWS, 0x0010 },
1258 { ScTableProtection::INSERT_COLUMNS, 0x0020 },
1259 { ScTableProtection::INSERT_ROWS, 0x0040 },
1260 { ScTableProtection::INSERT_HYPERLINKS, 0x0080 },
1262 { ScTableProtection::DELETE_COLUMNS, 0x0100 },
1263 { ScTableProtection::DELETE_ROWS, 0x0200 },
1264 { ScTableProtection::SELECT_LOCKED_CELLS, 0x0400 },
1265 { ScTableProtection::SORT, 0x0800 },
1266 { ScTableProtection::AUTOFILTER, 0x1000 },
1267 { ScTableProtection::PIVOT_TABLES, 0x2000 },
1268 { ScTableProtection::SELECT_UNLOCKED_CELLS, 0x4000 },
1270 { ScTableProtection::NONE, 0x0000 }
1273 mnOptions = 0x0000;
1274 ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
1275 if (!pProtect)
1276 return;
1278 for (int i = 0; aTable[i].nMask != 0x0000; ++i)
1280 if ( pProtect->isOptionEnabled(aTable[i].eOption) )
1281 mnOptions |= aTable[i].nMask;
1285 void XclExpSheetProtectOptions::WriteBody( XclExpStream& rStrm )
1287 sal_uInt16 nBytes = 0x0867;
1288 rStrm << nBytes;
1290 sal_uChar nZero = 0x00;
1291 for (int i = 0; i < 9; ++i)
1292 rStrm << nZero;
1294 nBytes = 0x0200;
1295 rStrm << nBytes;
1296 nBytes = 0x0100;
1297 rStrm << nBytes;
1298 nBytes = 0xFFFF;
1299 rStrm << nBytes << nBytes;
1301 rStrm << mnOptions;
1302 nBytes = 0;
1303 rStrm << nBytes;
1306 // ============================================================================
1311 void XclCalccount::SaveCont( XclExpStream& rStrm )
1313 rStrm << nCount;
1317 XclCalccount::XclCalccount( const ScDocument& rDoc )
1319 nCount = rDoc.GetDocOptions().GetIterCount();
1323 UINT16 XclCalccount::GetNum() const
1325 return 0x000C;
1329 sal_Size XclCalccount::GetLen() const
1331 return 2;
1335 void XclCalccount::SaveXml( XclExpXmlStream& rStrm )
1337 rStrm.WriteAttributes(
1338 XML_iterateCount, OString::valueOf( (sal_Int32)nCount ).getStr(),
1339 FSEND );
1345 void XclIteration::SaveCont( XclExpStream& rStrm )
1347 rStrm << nIter;
1351 XclIteration::XclIteration( const ScDocument& rDoc )
1353 nIter = rDoc.GetDocOptions().IsIter()? 1 : 0;
1357 UINT16 XclIteration::GetNum() const
1359 return 0x0011;
1363 sal_Size XclIteration::GetLen() const
1365 return 2;
1369 void XclIteration::SaveXml( XclExpXmlStream& rStrm )
1371 rStrm.WriteAttributes(
1372 XML_iterate, XclXmlUtils::ToPsz( nIter == 1 ),
1373 FSEND );
1379 void XclDelta::SaveCont( XclExpStream& rStrm )
1381 rStrm << fDelta;
1386 XclDelta::XclDelta( const ScDocument& rDoc )
1388 fDelta = rDoc.GetDocOptions().GetIterEps();
1392 UINT16 XclDelta::GetNum() const
1394 return 0x0010;
1398 sal_Size XclDelta::GetLen() const
1400 return 8;
1404 void XclDelta::SaveXml( XclExpXmlStream& rStrm )
1406 rStrm.WriteAttributes(
1407 XML_iterateDelta, OString::valueOf( fDelta ).getStr(),
1408 FSEND );
1411 // ============================================================================
1413 XclExpFilePass::XclExpFilePass( const XclExpRoot& rRoot ) :
1414 XclExpRecord(0x002F, 54),
1415 mrRoot(rRoot)
1419 XclExpFilePass::~XclExpFilePass()
1423 void XclExpFilePass::WriteBody( XclExpStream& rStrm )
1425 static const sal_uInt8 nDocId[] = {
1426 0x17, 0xf7, 0x01, 0x08, 0xea, 0xad, 0x30, 0x5c,
1427 0x1a, 0x95, 0xa5, 0x75, 0xd6, 0x79, 0xcd, 0x8d };
1430 static const sal_uInt8 nSalt[] = {
1431 0xa4, 0x5b, 0xf7, 0xe9, 0x9f, 0x55, 0x21, 0xc5,
1432 0xc5, 0x56, 0xa8, 0x0d, 0x39, 0x05, 0x3a, 0xb4 };
1434 // 0x0000 - neither standard nor strong encryption
1435 // 0x0001 - standard or strong encryption
1436 rStrm << static_cast<sal_uInt16>(0x0001);
1438 // 0x0000 - non standard encryption
1439 // 0x0001 - standard encryption
1440 sal_uInt16 nStdEnc = 0x0001;
1441 rStrm << nStdEnc << nStdEnc;
1443 sal_uInt8 nSaltHash[16];
1444 XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot, nDocId, nSalt) );
1445 xEnc->GetSaltDigest(nSaltHash);
1447 rStrm.Write(nDocId, 16);
1448 rStrm.Write(nSalt, 16);
1449 rStrm.Write(nSaltHash, 16);
1451 rStrm.SetEncrypter(xEnc);
1454 // ============================================================================
1456 XclExpFnGroupCount::XclExpFnGroupCount() :
1457 XclExpRecord(0x009C, 2)
1461 XclExpFnGroupCount::~XclExpFnGroupCount()
1465 void XclExpFnGroupCount::WriteBody( XclExpStream& rStrm )
1467 rStrm << static_cast<sal_uInt16>(14);
1470 // ============================================================================
1472 XclExpInterfaceHdr::XclExpInterfaceHdr() :
1473 XclExpRecord(0x00E1, 2)
1477 XclExpInterfaceHdr::~XclExpInterfaceHdr()
1481 void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
1483 // The value must be the same value as the CODEPAGE record.
1484 rStrm.DisableEncryption();
1485 rStrm << static_cast<sal_uInt16>(0x04B0);
1488 // ============================================================================
1490 XclExpInterfaceEnd::XclExpInterfaceEnd() :
1491 XclExpRecord(0x00E2, 0)
1495 XclExpInterfaceEnd::~XclExpInterfaceEnd()
1499 void XclExpInterfaceEnd::WriteBody( XclExpStream& /*rStrm*/ )
1503 // ============================================================================
1505 XclExpMMS::XclExpMMS() :
1506 XclExpRecord(0x00C1, 2)
1510 XclExpMMS::~XclExpMMS()
1514 void XclExpMMS::WriteBody( XclExpStream& rStrm )
1516 rStrm << static_cast<sal_uInt16>(0x0000);
1519 // ============================================================================
1521 XclExpWriteAccess::XclExpWriteAccess() :
1522 XclExpRecord(0x005C, 112)
1526 XclExpWriteAccess::~XclExpWriteAccess()
1530 void XclExpWriteAccess::WriteBody( XclExpStream& rStrm )
1532 static const sal_uInt8 aData[] = {
1533 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20,
1534 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1535 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1536 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1537 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1538 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1539 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1540 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1541 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1542 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1543 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1544 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1545 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1546 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
1548 sal_Size nDataSize = sizeof(aData);
1549 for (sal_Size i = 0; i < nDataSize; ++i)
1550 rStrm << aData[i];
1553 // ============================================================================
1555 XclExpCodePage::XclExpCodePage() :
1556 XclExpRecord(0x0042, 2)
1560 XclExpCodePage::~XclExpCodePage()
1564 void XclExpCodePage::WriteBody( XclExpStream& rStrm )
1566 // 0x04B0 : UTF-16 (BIFF8)
1567 rStrm << static_cast<sal_uInt16>(0x04B0);
1570 // ============================================================================
1572 XclExpDSF::XclExpDSF() :
1573 XclExpRecord(0x0161, 2)
1577 XclExpDSF::~XclExpDSF()
1581 void XclExpDSF::WriteBody( XclExpStream& rStrm )
1583 rStrm << static_cast<sal_uInt16>(0x0000);
1586 // ============================================================================
1588 XclExpProt4Rev::XclExpProt4Rev() :
1589 XclExpRecord(0x01AF, 2)
1593 XclExpProt4Rev::~XclExpProt4Rev()
1597 void XclExpProt4Rev::WriteBody( XclExpStream& rStrm )
1599 rStrm << static_cast<sal_uInt16>(0x0000);
1602 // ============================================================================
1604 XclExpProt4RevPass::XclExpProt4RevPass() :
1605 XclExpRecord(0x01BC, 2)
1609 XclExpProt4RevPass::~XclExpProt4RevPass()
1613 void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm )
1615 rStrm << static_cast<sal_uInt16>(0x0000);
1618 // ============================================================================
1620 XclExpExcel9File::XclExpExcel9File() :
1621 XclExpRecord(0x01C0, 0)
1625 XclExpExcel9File::~XclExpExcel9File()
1629 void XclExpExcel9File::WriteBody( XclExpStream& /*rStrm*/ )
1633 // ============================================================================
1635 static const sal_uInt8 nDataRecalcId[] = {
1636 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
1639 XclExpRecalcId::XclExpRecalcId() :
1640 XclExpDummyRecord(0x01C1, nDataRecalcId, sizeof(nDataRecalcId))
1644 // ============================================================================
1646 static const sal_uInt8 nDataBookExt[] = {
1647 0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1648 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1649 0x02
1652 XclExpBookExt::XclExpBookExt() :
1653 XclExpDummyRecord(0x0863, nDataBookExt, sizeof(nDataBookExt))
1657 // ============================================================================
1659 XclRefmode::XclRefmode( const ScDocument& rDoc ) :
1660 XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != formula::FormulaGrammar::CONV_XL_R1C1 )
1664 void XclRefmode::SaveXml( XclExpXmlStream& rStrm )
1666 rStrm.WriteAttributes(
1667 XML_refMode, GetBool() ? "A1" : "R1C1",
1668 FSEND );