merged tag ooo/OOO330_m14
[LibreOffice.git] / sc / source / filter / xcl97 / xcl97rec.cxx
blobdf6bdcbbe6715a20e3549036f6e4373a462019ff
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
31 #include <svx/svdpool.hxx>
32 #include <svx/sdtaitm.hxx>
33 #include <svx/svdotext.hxx>
34 #include <editeng/editobj.hxx>
35 #include <svx/svdoole2.hxx>
36 #include <sot/storage.hxx>
37 #include <svl/itemset.hxx>
38 #include <svx/svdpage.hxx>
39 #include <svx/svdocapt.hxx>
40 #include <svx/unoapi.hxx>
41 #include <editeng/writingmodeitem.hxx>
42 #include <vcl/svapp.hxx>
43 #include <rtl/math.hxx>
44 #include <svl/zformat.hxx>
45 #include "cell.hxx"
46 #include "drwlayer.hxx"
48 #include "xcl97rec.hxx"
49 #include "xcl97esc.hxx"
50 #include "editutil.hxx"
51 #include "xecontent.hxx"
52 #include "xeescher.hxx"
53 #include "xestyle.hxx"
54 #include "xelink.hxx"
56 #include "scitems.hxx"
58 #include <unotools/fltrcfg.hxx>
59 #include <editeng/brshitem.hxx>
60 #include <editeng/boxitem.hxx>
61 #include <editeng/frmdiritem.hxx>
62 #include <editeng/adjitem.hxx>
63 #include <editeng/eeitem.hxx>
64 #include <filter/msfilter/msoleexp.hxx>
66 #include <unotools/localedatawrapper.hxx>
68 #include <stdio.h>
70 #include "document.hxx"
71 #include "conditio.hxx"
72 #include "rangelst.hxx"
73 #include "stlpool.hxx"
74 #include "viewopti.hxx"
75 #include "scextopt.hxx"
76 #include "docoptio.hxx"
77 #include "patattr.hxx"
78 #include "tabprotection.hxx"
80 #include <oox/core/tokens.hxx>
82 using ::rtl::OString;
83 using ::rtl::OUString;
84 using namespace ::com::sun::star;
85 using ::com::sun::star::uno::Reference;
86 using ::com::sun::star::uno::UNO_QUERY;
87 using ::com::sun::star::beans::XPropertySet;
88 using ::com::sun::star::drawing::XShape;
90 // ============================================================================
92 XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) :
93 XclExpRoot( rRoot ),
94 mrEscherEx( rEscherEx ),
95 pSolverContainer( 0 )
97 pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx );
98 // open the DGCONTAINER and the patriarch group shape
99 mrEscherEx.OpenContainer( ESCHER_DgContainer );
100 Rectangle aRect( 0, 0, 0, 0 );
101 mrEscherEx.EnterGroup( &aRect );
102 mrEscherEx.UpdateDffFragmentEnd();
105 XclExpObjList::~XclExpObjList()
107 for ( XclObj* p = First(); p; p = Next() )
108 delete p;
109 delete pMsodrawingPerSheet;
110 delete pSolverContainer;
113 UINT16 XclExpObjList::Add( XclObj* pObj )
115 DBG_ASSERT( Count() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" );
116 if ( Count() < 0xFFFF )
118 Insert( pObj, LIST_APPEND );
119 UINT16 nCnt = (UINT16) Count();
120 pObj->SetId( nCnt );
121 return nCnt;
123 else
125 delete pObj;
126 return 0;
130 void XclExpObjList::EndSheet()
132 // Is there still something in the stream? -> The solver container
133 if( mrEscherEx.HasPendingDffData() )
134 pSolverContainer = new XclExpMsoDrawing( mrEscherEx );
136 // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING
137 mrEscherEx.CloseContainer();
140 void XclExpObjList::Save( XclExpStream& rStrm )
142 //! Escher must be written, even if there are no objects
143 pMsodrawingPerSheet->Save( rStrm );
145 for ( XclObj* p = First(); p; p = Next() )
146 p->Save( rStrm );
148 if( pSolverContainer )
149 pSolverContainer->Save( rStrm );
152 // --- class XclObj --------------------------------------------------
154 XclObj::XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher ) :
155 XclExpRecord( EXC_ID_OBJ, 26 ),
156 mrEscherEx( rObjMgr.GetEscherEx() ),
157 pClientTextbox( NULL ),
158 pTxo( NULL ),
159 mnObjType( nObjType ),
160 nObjId(0),
161 nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked
162 bFirstOnSheet( !rObjMgr.HasObj() ),
163 mbOwnEscher( bOwnEscher )
165 //! first object continues the first MSODRAWING record
166 if ( bFirstOnSheet )
167 pMsodrawing = rObjMgr.GetMsodrawingPerSheet();
168 else
169 pMsodrawing = new XclExpMsoDrawing( mrEscherEx );
172 XclObj::~XclObj()
174 if ( !bFirstOnSheet )
175 delete pMsodrawing;
176 delete pClientTextbox;
177 delete pTxo;
180 void XclObj::ImplWriteAnchor( const XclExpRoot& /*rRoot*/, const SdrObject* pSdrObj, const Rectangle* pChildAnchor )
182 if( pChildAnchor )
184 mrEscherEx.AddChildAnchor( *pChildAnchor );
186 else if( pSdrObj )
188 ::std::auto_ptr< XclExpDffAnchorBase > xDffAnchor( mrEscherEx.CreateDffAnchor( *pSdrObj ) );
189 xDffAnchor->WriteDffData( mrEscherEx );
193 void XclObj::SetEscherShapeType( UINT16 nType )
195 //2do: what about the other defined ot... types?
196 switch ( nType )
198 case ESCHER_ShpInst_Line :
199 mnObjType = EXC_OBJTYPE_LINE;
200 break;
201 case ESCHER_ShpInst_Rectangle :
202 case ESCHER_ShpInst_RoundRectangle :
203 mnObjType = EXC_OBJTYPE_RECTANGLE;
204 break;
205 case ESCHER_ShpInst_Ellipse :
206 mnObjType = EXC_OBJTYPE_OVAL;
207 break;
208 case ESCHER_ShpInst_Arc :
209 mnObjType = EXC_OBJTYPE_ARC;
210 break;
211 case ESCHER_ShpInst_TextBox :
212 mnObjType = EXC_OBJTYPE_TEXT;
213 break;
214 case ESCHER_ShpInst_PictureFrame :
215 mnObjType = EXC_OBJTYPE_PICTURE;
216 break;
217 default:
218 mnObjType = EXC_OBJTYPE_DRAWING;
222 void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj )
224 DBG_ASSERT( !pClientTextbox, "XclObj::SetText: already set" );
225 if ( !pClientTextbox )
227 mrEscherEx.UpdateDffFragmentEnd();
228 pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
229 mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
230 mrEscherEx.UpdateDffFragmentEnd();
231 pTxo = new XclTxo( rRoot, rObj );
235 void XclObj::WriteBody( XclExpStream& rStrm )
237 DBG_ASSERT( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" );
239 // create a substream to be able to create subrecords
240 SvMemoryStream aMemStrm;
241 ::std::auto_ptr< XclExpStream > pXclStrm( new XclExpStream( aMemStrm, rStrm.GetRoot() ) );
243 // write the ftCmo subrecord
244 pXclStrm->StartRecord( EXC_ID_OBJCMO, 18 );
245 *pXclStrm << mnObjType << nObjId << nGrbit;
246 pXclStrm->WriteZeroBytes( 12 );
247 pXclStrm->EndRecord();
249 // write other subrecords
250 WriteSubRecs( *pXclStrm );
252 // write the ftEnd subrecord
253 pXclStrm->StartRecord( EXC_ID_OBJEND, 0 );
254 pXclStrm->EndRecord();
256 // copy the data to the OBJ record
257 pXclStrm.reset();
258 aMemStrm.Seek( 0 );
259 rStrm.CopyFromStream( aMemStrm );
262 void XclObj::Save( XclExpStream& rStrm )
264 // MSODRAWING record (msofbtSpContainer)
265 if ( !bFirstOnSheet )
266 pMsodrawing->Save( rStrm );
268 // OBJ
269 XclExpRecord::Save( rStrm );
271 // second MSODRAWING record and TXO and CONTINUE records
272 SaveTextRecs( rStrm );
275 void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ )
279 void XclObj::SaveTextRecs( XclExpStream& rStrm )
281 // MSODRAWING record (msofbtClientTextbox)
282 if ( pClientTextbox )
283 pClientTextbox->Save( rStrm );
284 // TXO and CONTINUE records
285 if ( pTxo )
286 pTxo->Save( rStrm );
289 // --- class XclObjComment -------------------------------------------
291 XclObjComment::XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrObject* pCaption, bool bVisible ) :
292 XclObj( rObjMgr, EXC_OBJTYPE_NOTE, true )
294 ProcessEscherObj( rObjMgr.GetRoot(), rRect, pCaption, bVisible);
295 // TXO
296 pTxo = new XclTxo( rObjMgr.GetRoot(), rEditObj, pCaption );
299 void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible )
301 Reference<XShape> aXShape;
302 EscherPropertyContainer aPropOpt;
304 if(pCaption)
306 aXShape = GetXShapeForSdrObject(pCaption);
307 Reference< XPropertySet > aXPropSet( aXShape, UNO_QUERY );
308 if( aXPropSet.is() )
310 aPropOpt.CreateFillProperties( aXPropSet, sal_True);
312 aPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // undocumented
313 aPropOpt.AddOpt( 0x0158, 0x00000000 ); // undocumented
315 sal_uInt32 nValue = 0;
316 if(!aPropOpt.GetOpt( ESCHER_Prop_FitTextToShape, nValue ))
317 aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
319 if(aPropOpt.GetOpt( ESCHER_Prop_fillColor, nValue ))
321 // If the Colour is the same as the 'ToolTip' System colour then
322 // use the default rather than the explicit colour value. This will
323 // be incorrect where user has chosen to use this colour explicity.
324 Color aColor = Color( (BYTE)nValue, (BYTE)( nValue >> 8 ), (BYTE)( nValue >> 16 ) );
325 const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
326 if(aColor == rSett.GetHelpColor().GetColor())
328 aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
329 aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
332 else
333 aPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
335 if(!aPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nValue ))
336 aPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
337 if(!aPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ))
338 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 ); // bool field
339 if(!aPropOpt.GetOpt( ESCHER_Prop_shadowColor, nValue ))
340 aPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x00000000 );
341 if(!aPropOpt.GetOpt( ESCHER_Prop_fshadowObscured, nValue )) // bool field
342 aPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // bool field
346 nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked
347 mrEscherEx.OpenContainer( ESCHER_SpContainer );
348 mrEscherEx.AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
349 sal_uInt32 nFlags = 0x000A0000;
350 ::set_flag( nFlags, sal_uInt32(2), !bVisible );
351 aPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field
352 aPropOpt.Commit( mrEscherEx.GetStream() );
354 XclExpDffNoteAnchor( rRoot, rRect ).WriteDffData( mrEscherEx );
356 mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
357 mrEscherEx.UpdateDffFragmentEnd();
359 //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the
360 //! base OBJ's MSODRAWING record Escher data is completed.
361 pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
362 mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
363 mrEscherEx.UpdateDffFragmentEnd();
364 mrEscherEx.CloseContainer(); // ESCHER_SpContainer
367 XclObjComment::~XclObjComment()
371 void XclObjComment::Save( XclExpStream& rStrm )
373 // content of this record
374 XclObj::Save( rStrm );
377 // --- class XclObjDropDown ------------------------------------------
379 XclObjDropDown::XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, BOOL bFilt ) :
380 XclObj( rObjMgr, EXC_OBJTYPE_DROPDOWN, true ),
381 bIsFiltered( bFilt )
383 SetLocked( TRUE );
384 SetPrintable( FALSE );
385 SetAutoFill( TRUE );
386 SetAutoLine( FALSE );
387 nGrbit |= 0x0100; // undocumented
388 mrEscherEx.OpenContainer( ESCHER_SpContainer );
389 mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
390 EscherPropertyContainer aPropOpt;
391 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field
392 aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
393 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field
394 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
395 aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field
396 aPropOpt.Commit( mrEscherEx.GetStream() );
398 XclExpDffDropDownAnchor( rObjMgr.GetRoot(), rPos ).WriteDffData( mrEscherEx );
400 mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
401 mrEscherEx.UpdateDffFragmentEnd();
402 mrEscherEx.CloseContainer(); // ESCHER_SpContainer
404 // old size + ftSbs + ftLbsData
405 AddRecSize( 24 + 20 );
408 XclObjDropDown::~XclObjDropDown()
412 void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm )
414 // ftSbs subrecord - Scroll bars (dummy)
415 rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
416 rStrm.WriteZeroBytes( 20 );
417 rStrm.EndRecord();
419 // ftLbsData subrecord - Listbox data
420 sal_uInt16 nDropDownFlags = 0;
421 ::insert_value( nDropDownFlags, EXC_OBJ_DROPDOWN_SIMPLE, 0, 2 );
422 ::set_flag( nDropDownFlags, EXC_OBJ_DROPDOWN_FILTERED, bIsFiltered );
423 rStrm.StartRecord( EXC_ID_OBJLBSDATA, 16 );
424 rStrm << (UINT32)0 << (UINT16)0 << (UINT16)0x0301 << (UINT16)0
425 << nDropDownFlags << sal_uInt16( 20 ) << sal_uInt16( 130 );
426 rStrm.EndRecord();
429 // --- class XclTxo --------------------------------------------------
431 sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet )
433 sal_uInt8 nHorAlign = EXC_OBJ_HOR_LEFT;
435 switch( static_cast< const SvxAdjustItem& >( rItemSet.Get( EE_PARA_JUST ) ).GetAdjust() )
437 case SVX_ADJUST_LEFT: nHorAlign = EXC_OBJ_HOR_LEFT; break;
438 case SVX_ADJUST_CENTER: nHorAlign = EXC_OBJ_HOR_CENTER; break;
439 case SVX_ADJUST_RIGHT: nHorAlign = EXC_OBJ_HOR_RIGHT; break;
440 case SVX_ADJUST_BLOCK: nHorAlign = EXC_OBJ_HOR_JUSTIFY; break;
441 default:;
443 return nHorAlign;
446 sal_uInt8 lcl_GetVerAlignFromItemSet( const SfxItemSet& rItemSet )
448 sal_uInt8 nVerAlign = EXC_OBJ_VER_TOP;
450 switch( static_cast< const SdrTextVertAdjustItem& >( rItemSet.Get( SDRATTR_TEXT_VERTADJUST ) ).GetValue() )
452 case SDRTEXTVERTADJUST_TOP: nVerAlign = EXC_OBJ_VER_TOP; break;
453 case SDRTEXTVERTADJUST_CENTER: nVerAlign = EXC_OBJ_VER_CENTER; break;
454 case SDRTEXTVERTADJUST_BOTTOM: nVerAlign = EXC_OBJ_VER_BOTTOM; break;
455 case SDRTEXTVERTADJUST_BLOCK: nVerAlign = EXC_OBJ_VER_JUSTIFY; break;
457 return nVerAlign;
460 XclTxo::XclTxo( const String& rString, sal_uInt16 nFontIx ) :
461 mpString( new XclExpString( rString ) ),
462 mnRotation( EXC_OBJ_ORIENT_NONE ),
463 mnHorAlign( EXC_OBJ_HOR_LEFT ),
464 mnVerAlign( EXC_OBJ_VER_TOP )
466 if( mpString->Len() )
468 // If there is text, Excel *needs* the 2nd CONTINUE record with at least two format runs
469 mpString->AppendFormat( 0, nFontIx );
470 mpString->AppendFormat( mpString->Len(), EXC_FONT_APP );
474 XclTxo::XclTxo( const XclExpRoot& rRoot, const SdrTextObj& rTextObj ) :
475 mpString( XclExpStringHelper::CreateString( rRoot, rTextObj ) ),
476 mnRotation( EXC_OBJ_ORIENT_NONE ),
477 mnHorAlign( EXC_OBJ_HOR_LEFT ),
478 mnVerAlign( EXC_OBJ_VER_TOP )
480 // additional alignment and orientation items
481 const SfxItemSet& rItemSet = rTextObj.GetMergedItemSet();
483 // horizontal alignment
484 SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
486 // vertical alignment
487 SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
489 // rotation
490 long nAngle = rTextObj.GetRotateAngle();
491 if( (4500 < nAngle) && (nAngle < 13500) )
492 mnRotation = EXC_OBJ_ORIENT_90CCW;
493 else if( (22500 < nAngle) && (nAngle < 31500) )
494 mnRotation = EXC_OBJ_ORIENT_90CW;
495 else
496 mnRotation = EXC_OBJ_ORIENT_NONE;
499 XclTxo::XclTxo( const XclExpRoot& rRoot, const EditTextObject& rEditObj, SdrObject* pCaption ) :
500 mpString( XclExpStringHelper::CreateString( rRoot, rEditObj ) ),
501 mnRotation( EXC_OBJ_ORIENT_NONE ),
502 mnHorAlign( EXC_OBJ_HOR_LEFT ),
503 mnVerAlign( EXC_OBJ_VER_TOP )
505 if(pCaption)
507 // Excel has one alignment per NoteObject while Calc supports
508 // one alignment per paragraph - use the first paragraph
509 // alignment (if set) as our overall alignment.
510 String aParaText( rEditObj.GetText( 0 ) );
511 if( aParaText.Len() )
513 SfxItemSet aSet( rEditObj.GetParaAttribs( 0));
514 const SfxPoolItem* pItem = NULL;
515 if( aSet.GetItemState( EE_PARA_JUST, TRUE, &pItem ) == SFX_ITEM_SET )
517 SvxAdjust eEEAlign = static_cast< const SvxAdjustItem& >( *pItem ).GetAdjust();
518 pCaption->SetMergedItem( SvxAdjustItem( eEEAlign, EE_PARA_JUST ) );
521 const SfxItemSet& rItemSet = pCaption->GetMergedItemSet();
523 // horizontal alignment
524 SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
526 // vertical alignment
527 SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
529 // orientation alignment
530 const SvxWritingModeItem& rItem = static_cast< const SvxWritingModeItem& >( rItemSet.Get( SDRATTR_TEXTDIRECTION ) );
531 if( rItem.GetValue() == com::sun::star::text::WritingMode_TB_RL )
532 mnRotation = EXC_OBJ_ORIENT_90CW;
536 void XclTxo::SaveCont( XclExpStream& rStrm )
538 DBG_ASSERT( mpString.get(), "XclTxo::SaveCont - missing string" );
540 // #i96858# do not save existing string formatting if text is empty
541 sal_uInt16 nRunLen = mpString->IsEmpty() ? 0 : (8 * mpString->GetFormatsCount());
542 // alignment
543 sal_uInt16 nFlags = 0;
544 ::insert_value( nFlags, mnHorAlign, 1, 3 );
545 ::insert_value( nFlags, mnVerAlign, 4, 3 );
547 rStrm << nFlags << mnRotation;
548 rStrm.WriteZeroBytes( 6 );
549 rStrm << mpString->Len() << nRunLen << sal_uInt32( 0 );
552 void XclTxo::Save( XclExpStream& rStrm )
554 // Write the TXO part
555 ExcRecord::Save( rStrm );
557 // CONTINUE records are only written if there is some text
558 if( !mpString->IsEmpty() )
560 // CONTINUE for character array
561 rStrm.StartRecord( EXC_ID_CONT, mpString->GetBufferSize() + 1 );
562 rStrm << static_cast< sal_uInt8 >( mpString->GetFlagField() & EXC_STRF_16BIT ); // only Unicode flag
563 mpString->WriteBuffer( rStrm );
564 rStrm.EndRecord();
566 // CONTINUE for formatting runs
567 rStrm.StartRecord( EXC_ID_CONT, 8 * mpString->GetFormatsCount() );
568 const XclFormatRunVec& rFormats = mpString->GetFormats();
569 for( XclFormatRunVec::const_iterator aIt = rFormats.begin(), aEnd = rFormats.end(); aIt != aEnd; ++aIt )
570 rStrm << aIt->mnChar << aIt->mnFontIdx << sal_uInt32( 0 );
571 rStrm.EndRecord();
575 UINT16 XclTxo::GetNum() const
577 return EXC_ID_TXO;
580 sal_Size XclTxo::GetLen() const
582 return 18;
585 // --- class XclObjOle -------------------------------------------
587 XclObjOle::XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ) :
588 XclObj( rObjMgr, EXC_OBJTYPE_PICTURE ),
589 rOleObj( rObj ),
590 pRootStorage( rObjMgr.GetRoot().GetRootStorage() )
594 XclObjOle::~XclObjOle()
598 void XclObjOle::WriteSubRecs( XclExpStream& rStrm )
600 // write only as embedded, not linked
601 String aStorageName( RTL_CONSTASCII_USTRINGPARAM( "MBD" ) );
602 sal_Char aBuf[ sizeof(UINT32) * 2 + 1 ];
603 // FIXME Eeek! Is this just a way to get a unique id?
604 UINT32 nPictureId = UINT32(sal_uIntPtr(this) >> 2);
605 sprintf( aBuf, "%08X", static_cast< unsigned int >( nPictureId ) ); // #100211# - checked
606 aStorageName.AppendAscii( aBuf );
607 SotStorageRef xOleStg = pRootStorage->OpenSotStorage( aStorageName,
608 STREAM_READWRITE| STREAM_SHARE_DENYALL );
609 if( xOleStg.Is() )
611 uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj&)rOleObj).GetObjRef() );
612 if ( xObj.is() )
614 // set version to "old" version, because it must be
615 // saved in MS notation.
616 UINT32 nFl = 0;
617 SvtFilterOptions* pFltOpts = SvtFilterOptions::Get();
618 if( pFltOpts )
620 if( pFltOpts->IsMath2MathType() )
621 nFl |= OLE_STARMATH_2_MATHTYPE;
623 if( pFltOpts->IsWriter2WinWord() )
624 nFl |= OLE_STARWRITER_2_WINWORD;
626 if( pFltOpts->IsCalc2Excel() )
627 nFl |= OLE_STARCALC_2_EXCEL;
629 if( pFltOpts->IsImpress2PowerPoint() )
630 nFl |= OLE_STARIMPRESS_2_POWERPOINT;
633 SvxMSExportOLEObjects aOLEExpFilt( nFl );
634 aOLEExpFilt.ExportOLEObject( xObj, *xOleStg );
636 // OBJCF subrecord, undocumented as usual
637 rStrm.StartRecord( EXC_ID_OBJCF, 2 );
638 rStrm << UINT16(0x0002);
639 rStrm.EndRecord();
641 // OBJFLAGS subrecord, undocumented as usual
642 rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
643 sal_uInt16 nFlags = EXC_OBJ_PIC_MANUALSIZE;
644 ::set_flag( nFlags, EXC_OBJ_PIC_SYMBOL, ((SdrOle2Obj&)rOleObj).GetAspect() == embed::Aspects::MSOLE_ICON );
645 rStrm << nFlags;
646 rStrm.EndRecord();
648 // OBJPICTFMLA subrecord, undocumented as usual
649 XclExpString aName( xOleStg->GetUserName() );
650 UINT16 nPadLen = (UINT16)(aName.GetSize() & 0x01);
651 UINT16 nFmlaLen = static_cast< sal_uInt16 >( 12 + aName.GetSize() + nPadLen );
652 UINT16 nSubRecLen = nFmlaLen + 6;
654 rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nSubRecLen );
655 rStrm << nFmlaLen
656 << sal_uInt16( 5 ) << sal_uInt32( 0 ) << sal_uInt8( 2 )
657 << sal_uInt32( 0 ) << sal_uInt8( 3 )
658 << aName;
659 if( nPadLen )
660 rStrm << sal_uInt8( 0 ); // pad byte
661 rStrm << nPictureId;
662 rStrm.EndRecord();
667 void XclObjOle::Save( XclExpStream& rStrm )
669 // content of this record
670 XclObj::Save( rStrm );
673 // --- class XclObjAny -------------------------------------------
675 XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr ) :
676 XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN )
680 XclObjAny::~XclObjAny()
684 void XclObjAny::WriteSubRecs( XclExpStream& rStrm )
686 if( mnObjType == EXC_OBJTYPE_GROUP )
687 // ftGmo subrecord
688 rStrm << EXC_ID_OBJGMO << UINT16(2) << UINT16(0);
691 void XclObjAny::Save( XclExpStream& rStrm )
693 if( mnObjType == EXC_OBJTYPE_GROUP )
694 // old size + ftGmo
695 AddRecSize( 6 );
697 // content of this record
698 XclObj::Save( rStrm );
701 // --- class ExcBof8_Base --------------------------------------------
703 ExcBof8_Base::ExcBof8_Base()
705 nVers = 0x0600;
706 nRupBuild = 0x0dbb;
707 nRupYear = 0x07cc;
708 // nFileHistory = 0x00000001; // last edited by Microsoft Excel for Windows
709 nFileHistory = 0x00000000;
710 nLowestBiffVer = 0x00000006; // Biff8
714 void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
716 rStrm.DisableEncryption();
717 rStrm << nVers << nDocType << nRupBuild << nRupYear
718 << nFileHistory << nLowestBiffVer;
722 UINT16 ExcBof8_Base::GetNum() const
724 return 0x0809;
728 sal_Size ExcBof8_Base::GetLen() const
730 return 16;
734 // --- class ExcBof8 -------------------------------------------------
736 ExcBof8::ExcBof8()
738 nDocType = 0x0010;
742 // --- class ExcBofW8 ------------------------------------------------
744 ExcBofW8::ExcBofW8()
746 nDocType = 0x0005;
750 // --- class ExcBundlesheet8 -----------------------------------------
752 ExcBundlesheet8::ExcBundlesheet8( RootData& rRootData, SCTAB _nTab ) :
753 ExcBundlesheetBase( rRootData, static_cast<sal_uInt16>(_nTab) ),
754 sUnicodeName( rRootData.pER->GetTabInfo().GetScTabName( _nTab ) )
759 ExcBundlesheet8::ExcBundlesheet8( const String& rString ) :
760 ExcBundlesheetBase(),
761 sUnicodeName( rString )
766 XclExpString ExcBundlesheet8::GetName() const
768 return XclExpString( sUnicodeName, EXC_STR_8BITLENGTH );
772 void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
774 nOwnPos = rStrm.GetSvStreamPos();
775 // write dummy position, real position comes later
776 rStrm.DisableEncryption();
777 rStrm << sal_uInt32(0);
778 rStrm.EnableEncryption();
779 rStrm << nGrbit << GetName();
783 sal_Size ExcBundlesheet8::GetLen() const
784 { // Text max 255 chars
785 return 8 + GetName().GetBufferSize();
789 void ExcBundlesheet8::SaveXml( XclExpXmlStream& rStrm )
791 OUString sId;
792 rStrm.CreateOutputStream(
793 XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", nTab+1),
794 XclXmlUtils::GetStreamName( NULL, "worksheets/sheet", nTab+1),
795 rStrm.GetCurrentStream()->getOutputStream(),
796 "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
797 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
798 &sId );
800 rStrm.GetCurrentStream()->singleElement( XML_sheet,
801 XML_name, XclXmlUtils::ToOString( sUnicodeName ).getStr(),
802 XML_sheetId, rtl::OString::valueOf( (sal_Int32)( nTab+1 ) ).getStr(),
803 XML_state, nGrbit == 0x0000 ? "visible" : "hidden",
804 FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
805 FSEND );
810 // --- class XclObproj -----------------------------------------------
812 UINT16 XclObproj::GetNum() const
814 return 0x00D3;
818 sal_Size XclObproj::GetLen() const
820 return 0;
824 // ---- class XclCodename --------------------------------------------
826 XclCodename::XclCodename( const String& r ) : aName( r )
831 void XclCodename::SaveCont( XclExpStream& rStrm )
833 rStrm << aName;
837 UINT16 XclCodename::GetNum() const
839 return 0x01BA;
843 sal_Size XclCodename::GetLen() const
845 return aName.GetSize();
850 // ---- Scenarios ----------------------------------------------------
852 ExcEScenarioCell::ExcEScenarioCell( UINT16 nC, UINT16 nR, const String& rTxt ) :
853 nCol( nC ),
854 nRow( nR ),
855 sText( rTxt, EXC_STR_DEFAULT, 255 )
859 void ExcEScenarioCell::WriteAddress( XclExpStream& rStrm )
861 rStrm << nRow << nCol;
864 void ExcEScenarioCell::WriteText( XclExpStream& rStrm )
866 rStrm << sText;
869 void ExcEScenarioCell::SaveXml( XclExpXmlStream& rStrm )
871 rStrm.GetCurrentStream()->singleElement( XML_inputCells,
872 // OOXTODO: XML_deleted,
873 // OOXTODO: XML_numFmtId,
874 XML_r, XclXmlUtils::ToOString( ScAddress( nCol, nRow, 0 ) ).getStr(),
875 // OOXTODO: XML_undone,
876 XML_val, XclXmlUtils::ToOString( sText ).getStr(),
877 FSEND );
883 ExcEScenario::ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab )
885 String sTmpName;
886 String sTmpComm;
887 Color aDummyCol;
888 USHORT nFlags;
890 ScDocument& rDoc = rRoot.GetDoc();
891 rDoc.GetName( nTab, sTmpName );
892 sName.Assign( sTmpName, EXC_STR_8BITLENGTH );
893 nRecLen = 8 + sName.GetBufferSize();
895 rDoc.GetScenarioData( nTab, sTmpComm, aDummyCol, nFlags );
896 sComment.Assign( sTmpComm, EXC_STR_DEFAULT, 255 );
897 if( sComment.Len() )
898 nRecLen += sComment.GetSize();
899 nProtected = (nFlags & SC_SCENARIO_PROTECT) ? 1 : 0;
901 sUserName.Assign( rRoot.GetUserName(), EXC_STR_DEFAULT, 255 );
902 nRecLen += sUserName.GetSize();
904 const ScRangeList* pRList = rDoc.GetScenarioRanges( nTab );
905 if( !pRList )
906 return;
908 BOOL bContLoop = TRUE;
909 SCROW nRow;
910 SCCOL nCol;
911 String sText;
912 double fVal;
914 for( UINT32 nRange = 0; (nRange < pRList->Count()) && bContLoop; nRange++ )
916 const ScRange* pRange = pRList->GetObject( nRange );
917 for( nRow = pRange->aStart.Row(); (nRow <= pRange->aEnd.Row()) && bContLoop; nRow++ )
918 for( nCol = pRange->aStart.Col(); (nCol <= pRange->aEnd.Col()) && bContLoop; nCol++ )
920 if( rDoc.HasValueData( nCol, nRow, nTab ) )
922 rDoc.GetValue( nCol, nRow, nTab, fVal );
923 sText = ::rtl::math::doubleToUString( fVal,
924 rtl_math_StringFormat_Automatic,
925 rtl_math_DecimalPlaces_Max,
926 ScGlobal::pLocaleData->getNumDecimalSep().GetChar(0),
927 TRUE );
929 else
930 rDoc.GetString( nCol, nRow, nTab, sText );
931 bContLoop = Append( static_cast<sal_uInt16>(nCol),
932 static_cast<sal_uInt16>(nRow), sText );
937 ExcEScenario::~ExcEScenario()
939 for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
940 delete pCell;
943 BOOL ExcEScenario::Append( UINT16 nCol, UINT16 nRow, const String& rTxt )
945 if( List::Count() == EXC_SCEN_MAXCELL )
946 return FALSE;
948 ExcEScenarioCell* pCell = new ExcEScenarioCell( nCol, nRow, rTxt );
949 List::Insert( pCell, LIST_APPEND );
950 nRecLen += 6 + pCell->GetStringBytes(); // 4 bytes address, 2 bytes ifmt
951 return TRUE;
954 void ExcEScenario::SaveCont( XclExpStream& rStrm )
956 rStrm << (UINT16) List::Count() // number of cells
957 << nProtected // fProtection
958 << (UINT8) 0 // fHidden
959 << (UINT8) sName.Len() // length of scen name
960 << (UINT8) sComment.Len() // length of comment
961 << (UINT8) sUserName.Len(); // length of user name
962 sName.WriteFlagField( rStrm );
963 sName.WriteBuffer( rStrm );
965 rStrm << sUserName;
967 if( sComment.Len() )
968 rStrm << sComment;
970 ExcEScenarioCell* pCell;
971 for( pCell = _First(); pCell; pCell = _Next() )
972 pCell->WriteAddress( rStrm ); // pos of cell
973 for( pCell = _First(); pCell; pCell = _Next() )
974 pCell->WriteText( rStrm ); // string content
975 rStrm.SetSliceSize( 2 );
976 rStrm.WriteZeroBytes( 2 * List::Count() ); // date format
979 UINT16 ExcEScenario::GetNum() const
981 return 0x00AF;
984 sal_Size ExcEScenario::GetLen() const
986 return nRecLen;
989 void ExcEScenario::SaveXml( XclExpXmlStream& rStrm )
991 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
992 rWorkbook->startElement( XML_scenario,
993 XML_name, XclXmlUtils::ToOString( sName ).getStr(),
994 XML_locked, XclXmlUtils::ToPsz( nProtected ),
995 // OOXTODO: XML_hidden,
996 XML_count, OString::valueOf( (sal_Int32) List::Count() ).getStr(),
997 XML_user, XESTRING_TO_PSZ( sUserName ),
998 XML_comment, XESTRING_TO_PSZ( sComment ),
999 FSEND );
1001 for( ExcEScenarioCell* pCell = _First(); pCell; pCell = _Next() )
1002 pCell->SaveXml( rStrm );
1004 rWorkbook->endElement( XML_scenario );
1010 ExcEScenarioManager::ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab ) :
1011 nActive( 0 )
1013 ScDocument& rDoc = rRoot.GetDoc();
1014 if( rDoc.IsScenario( nTab ) )
1015 return;
1017 SCTAB nFirstTab = nTab + 1;
1018 SCTAB nNewTab = nFirstTab;
1020 while( rDoc.IsScenario( nNewTab ) )
1022 Append( new ExcEScenario( rRoot, nNewTab ) );
1024 if( rDoc.IsActiveScenario( nNewTab ) )
1025 nActive = static_cast<sal_uInt16>(nNewTab - nFirstTab);
1026 nNewTab++;
1030 ExcEScenarioManager::~ExcEScenarioManager()
1032 for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
1033 delete pScen;
1036 void ExcEScenarioManager::SaveCont( XclExpStream& rStrm )
1038 rStrm << (UINT16) List::Count() // number of scenarios
1039 << nActive // active scen
1040 << nActive // last displayed
1041 << (UINT16) 0; // reference areas
1044 void ExcEScenarioManager::Save( XclExpStream& rStrm )
1046 if( List::Count() )
1047 ExcRecord::Save( rStrm );
1049 for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
1050 pScen->Save( rStrm );
1053 void ExcEScenarioManager::SaveXml( XclExpXmlStream& rStrm )
1055 if( ! List::Count() )
1056 return;
1058 sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
1059 rWorkbook->startElement( XML_scenarios,
1060 XML_current, OString::valueOf( (sal_Int32)nActive ).getStr(),
1061 XML_show, OString::valueOf( (sal_Int32)nActive ).getStr(),
1062 // OOXTODO: XML_sqref,
1063 FSEND );
1065 for( ExcEScenario* pScen = _First(); pScen; pScen = _Next() )
1066 pScen->SaveXml( rStrm );
1068 rWorkbook->endElement( XML_scenarios );
1071 UINT16 ExcEScenarioManager::GetNum() const
1073 return 0x00AE;
1076 sal_Size ExcEScenarioManager::GetLen() const
1078 return 8;
1081 // ============================================================================
1083 struct XclExpTabProtectOption
1085 ScTableProtection::Option eOption;
1086 sal_uInt16 nMask;
1089 XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
1090 XclExpRecord( 0x0867, 23 )
1092 static const XclExpTabProtectOption aTable[] =
1094 { ScTableProtection::OBJECTS, 0x0001 },
1095 { ScTableProtection::SCENARIOS, 0x0002 },
1096 { ScTableProtection::FORMAT_CELLS, 0x0004 },
1097 { ScTableProtection::FORMAT_COLUMNS, 0x0008 },
1098 { ScTableProtection::FORMAT_ROWS, 0x0010 },
1099 { ScTableProtection::INSERT_COLUMNS, 0x0020 },
1100 { ScTableProtection::INSERT_ROWS, 0x0040 },
1101 { ScTableProtection::INSERT_HYPERLINKS, 0x0080 },
1103 { ScTableProtection::DELETE_COLUMNS, 0x0100 },
1104 { ScTableProtection::DELETE_ROWS, 0x0200 },
1105 { ScTableProtection::SELECT_LOCKED_CELLS, 0x0400 },
1106 { ScTableProtection::SORT, 0x0800 },
1107 { ScTableProtection::AUTOFILTER, 0x1000 },
1108 { ScTableProtection::PIVOT_TABLES, 0x2000 },
1109 { ScTableProtection::SELECT_UNLOCKED_CELLS, 0x4000 },
1111 { ScTableProtection::NONE, 0x0000 }
1114 mnOptions = 0x0000;
1115 ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
1116 if (!pProtect)
1117 return;
1119 for (int i = 0; aTable[i].nMask != 0x0000; ++i)
1121 if ( pProtect->isOptionEnabled(aTable[i].eOption) )
1122 mnOptions |= aTable[i].nMask;
1126 void XclExpSheetProtectOptions::WriteBody( XclExpStream& rStrm )
1128 sal_uInt16 nBytes = 0x0867;
1129 rStrm << nBytes;
1131 sal_uChar nZero = 0x00;
1132 for (int i = 0; i < 9; ++i)
1133 rStrm << nZero;
1135 nBytes = 0x0200;
1136 rStrm << nBytes;
1137 nBytes = 0x0100;
1138 rStrm << nBytes;
1139 nBytes = 0xFFFF;
1140 rStrm << nBytes << nBytes;
1142 rStrm << mnOptions;
1143 nBytes = 0;
1144 rStrm << nBytes;
1147 // ============================================================================
1152 void XclCalccount::SaveCont( XclExpStream& rStrm )
1154 rStrm << nCount;
1158 XclCalccount::XclCalccount( const ScDocument& rDoc )
1160 nCount = rDoc.GetDocOptions().GetIterCount();
1164 UINT16 XclCalccount::GetNum() const
1166 return 0x000C;
1170 sal_Size XclCalccount::GetLen() const
1172 return 2;
1176 void XclCalccount::SaveXml( XclExpXmlStream& rStrm )
1178 rStrm.WriteAttributes(
1179 XML_iterateCount, OString::valueOf( (sal_Int32)nCount ).getStr(),
1180 FSEND );
1186 void XclIteration::SaveCont( XclExpStream& rStrm )
1188 rStrm << nIter;
1192 XclIteration::XclIteration( const ScDocument& rDoc )
1194 nIter = rDoc.GetDocOptions().IsIter()? 1 : 0;
1198 UINT16 XclIteration::GetNum() const
1200 return 0x0011;
1204 sal_Size XclIteration::GetLen() const
1206 return 2;
1210 void XclIteration::SaveXml( XclExpXmlStream& rStrm )
1212 rStrm.WriteAttributes(
1213 XML_iterate, XclXmlUtils::ToPsz( nIter == 1 ),
1214 FSEND );
1220 void XclDelta::SaveCont( XclExpStream& rStrm )
1222 rStrm << fDelta;
1227 XclDelta::XclDelta( const ScDocument& rDoc )
1229 fDelta = rDoc.GetDocOptions().GetIterEps();
1233 UINT16 XclDelta::GetNum() const
1235 return 0x0010;
1239 sal_Size XclDelta::GetLen() const
1241 return 8;
1245 void XclDelta::SaveXml( XclExpXmlStream& rStrm )
1247 rStrm.WriteAttributes(
1248 XML_iterateDelta, OString::valueOf( fDelta ).getStr(),
1249 FSEND );
1252 // ============================================================================
1254 XclExpFilePass::XclExpFilePass( const XclExpRoot& rRoot ) :
1255 XclExpRecord(0x002F, 54),
1256 mrRoot(rRoot)
1260 XclExpFilePass::~XclExpFilePass()
1264 void XclExpFilePass::WriteBody( XclExpStream& rStrm )
1266 static const sal_uInt8 nDocId[] = {
1267 0x17, 0xf7, 0x01, 0x08, 0xea, 0xad, 0x30, 0x5c,
1268 0x1a, 0x95, 0xa5, 0x75, 0xd6, 0x79, 0xcd, 0x8d };
1271 static const sal_uInt8 nSalt[] = {
1272 0xa4, 0x5b, 0xf7, 0xe9, 0x9f, 0x55, 0x21, 0xc5,
1273 0xc5, 0x56, 0xa8, 0x0d, 0x39, 0x05, 0x3a, 0xb4 };
1275 // 0x0000 - neither standard nor strong encryption
1276 // 0x0001 - standard or strong encryption
1277 rStrm << static_cast<sal_uInt16>(0x0001);
1279 // 0x0000 - non standard encryption
1280 // 0x0001 - standard encryption
1281 sal_uInt16 nStdEnc = 0x0001;
1282 rStrm << nStdEnc << nStdEnc;
1284 sal_uInt8 nSaltHash[16];
1285 XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot, nDocId, nSalt) );
1286 xEnc->GetSaltDigest(nSaltHash);
1288 rStrm.Write(nDocId, 16);
1289 rStrm.Write(nSalt, 16);
1290 rStrm.Write(nSaltHash, 16);
1292 rStrm.SetEncrypter(xEnc);
1295 // ============================================================================
1297 XclExpInterfaceHdr::XclExpInterfaceHdr( sal_uInt16 nCodePage ) :
1298 XclExpUInt16Record( EXC_ID_INTERFACEHDR, nCodePage )
1302 void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
1304 rStrm.DisableEncryption();
1305 rStrm << GetValue();
1308 // ============================================================================
1310 XclExpInterfaceEnd::XclExpInterfaceEnd() :
1311 XclExpRecord(0x00E2, 0) {}
1313 XclExpInterfaceEnd::~XclExpInterfaceEnd() {}
1315 void XclExpInterfaceEnd::WriteBody( XclExpStream& rStrm )
1317 // Don't forget to re-enable encryption.
1318 rStrm.EnableEncryption();
1321 // ============================================================================
1323 XclExpWriteAccess::XclExpWriteAccess() :
1324 XclExpRecord(0x005C, 112)
1328 XclExpWriteAccess::~XclExpWriteAccess()
1332 void XclExpWriteAccess::WriteBody( XclExpStream& rStrm )
1334 static const sal_uInt8 aData[] = {
1335 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20,
1336 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1337 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1338 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1339 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1340 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1341 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1342 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1343 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1344 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1345 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1346 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1347 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1348 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
1350 sal_Size nDataSize = sizeof(aData);
1351 for (sal_Size i = 0; i < nDataSize; ++i)
1352 rStrm << aData[i];
1355 // ============================================================================
1357 XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly ) :
1358 XclExpRecord( EXC_ID_FILESHARING ),
1359 mnPasswordHash( nPasswordHash ),
1360 mbRecommendReadOnly( bRecommendReadOnly )
1362 if( rRoot.GetBiff() <= EXC_BIFF5 )
1363 maUserName.AssignByte( rRoot.GetUserName(), rRoot.GetTextEncoding(), EXC_STR_8BITLENGTH );
1364 else
1365 maUserName.Assign( rRoot.GetUserName() );
1368 void XclExpFileSharing::Save( XclExpStream& rStrm )
1370 if( (mnPasswordHash != 0) || mbRecommendReadOnly )
1371 XclExpRecord::Save( rStrm );
1374 void XclExpFileSharing::WriteBody( XclExpStream& rStrm )
1376 rStrm << sal_uInt16( mbRecommendReadOnly ? 1 : 0 ) << mnPasswordHash << maUserName;
1379 // ============================================================================
1381 XclExpProt4Rev::XclExpProt4Rev() :
1382 XclExpRecord(0x01AF, 2)
1386 XclExpProt4Rev::~XclExpProt4Rev()
1390 void XclExpProt4Rev::WriteBody( XclExpStream& rStrm )
1392 rStrm << static_cast<sal_uInt16>(0x0000);
1395 // ============================================================================
1397 XclExpProt4RevPass::XclExpProt4RevPass() :
1398 XclExpRecord(0x01BC, 2)
1402 XclExpProt4RevPass::~XclExpProt4RevPass()
1406 void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm )
1408 rStrm << static_cast<sal_uInt16>(0x0000);
1411 // ============================================================================
1413 static const sal_uInt8 nDataRecalcId[] = {
1414 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
1417 XclExpRecalcId::XclExpRecalcId() :
1418 XclExpDummyRecord(0x01C1, nDataRecalcId, sizeof(nDataRecalcId))
1422 // ============================================================================
1424 static const sal_uInt8 nDataBookExt[] = {
1425 0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1426 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1427 0x02
1430 XclExpBookExt::XclExpBookExt() :
1431 XclExpDummyRecord(0x0863, nDataBookExt, sizeof(nDataBookExt))
1435 // ============================================================================
1437 XclRefmode::XclRefmode( const ScDocument& rDoc ) :
1438 XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != formula::FormulaGrammar::CONV_XL_R1C1 )
1442 void XclRefmode::SaveXml( XclExpXmlStream& rStrm )
1444 rStrm.WriteAttributes(
1445 XML_refMode, GetBool() ? "A1" : "R1C1",
1446 FSEND );