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 :
21 : #include <svx/svdpool.hxx>
22 : #include <svx/sdtaitm.hxx>
23 : #include <svx/svdotext.hxx>
24 : #include <editeng/editobj.hxx>
25 : #include <svx/svdoole2.hxx>
26 : #include <sot/storage.hxx>
27 : #include <svl/itemset.hxx>
28 : #include <svx/svdpage.hxx>
29 : #include <svx/svdocapt.hxx>
30 : #include <svx/unoapi.hxx>
31 : #include <editeng/writingmodeitem.hxx>
32 : #include <vcl/svapp.hxx>
33 : #include <rtl/math.hxx>
34 : #include <svl/zformat.hxx>
35 : #include "cell.hxx"
36 : #include "drwlayer.hxx"
37 :
38 : #include "xcl97rec.hxx"
39 : #include "xcl97esc.hxx"
40 : #include "editutil.hxx"
41 : #include "xecontent.hxx"
42 : #include "xeescher.hxx"
43 : #include "xestyle.hxx"
44 : #include "xelink.hxx"
45 :
46 : #include "scitems.hxx"
47 :
48 : #include <unotools/fltrcfg.hxx>
49 : #include <editeng/brshitem.hxx>
50 : #include <editeng/boxitem.hxx>
51 : #include <editeng/frmdiritem.hxx>
52 : #include <editeng/adjitem.hxx>
53 : #include <editeng/eeitem.hxx>
54 : #include <filter/msfilter/msoleexp.hxx>
55 :
56 : #include <unotools/localedatawrapper.hxx>
57 :
58 : #include <stdio.h>
59 :
60 : #include "document.hxx"
61 : #include "conditio.hxx"
62 : #include "rangelst.hxx"
63 : #include "stlpool.hxx"
64 : #include "viewopti.hxx"
65 : #include "scextopt.hxx"
66 : #include "docoptio.hxx"
67 : #include "patattr.hxx"
68 : #include "tabprotection.hxx"
69 : #include "stlalgorithm.hxx"
70 :
71 : #include <com/sun/star/sheet/XCellAddressable.hpp>
72 : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
73 : #include <oox/token/tokens.hxx>
74 : #include <oox/export/shapes.hxx>
75 : #include <oox/export/utils.hxx>
76 : #include <oox/export/vmlexport.hxx>
77 :
78 : using ::rtl::OString;
79 : using ::rtl::OUString;
80 : using namespace ::com::sun::star;
81 : using ::com::sun::star::uno::Reference;
82 : using ::oox::drawingml::DrawingML;
83 : using ::com::sun::star::uno::UNO_QUERY;
84 : using ::com::sun::star::beans::XPropertySet;
85 : using ::com::sun::star::drawing::XShape;
86 : using ::oox::drawingml::ShapeExport;
87 : using ::oox::vml::VMLExport;
88 : using namespace oox;
89 :
90 : // ============================================================================
91 :
92 : sal_Int32 XclExpObjList::mnDrawingMLCount;
93 : sal_Int32 XclExpObjList::mnVmlCount;
94 :
95 1 : XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) :
96 : XclExpRoot( rRoot ),
97 1 : mnScTab( rRoot.GetCurrScTab() ),
98 : mrEscherEx( rEscherEx ),
99 2 : pSolverContainer( 0 )
100 : {
101 1 : pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx );
102 : // open the DGCONTAINER and the patriarch group shape
103 1 : mrEscherEx.OpenContainer( ESCHER_DgContainer );
104 1 : Rectangle aRect( 0, 0, 0, 0 );
105 1 : mrEscherEx.EnterGroup( &aRect );
106 1 : mrEscherEx.UpdateDffFragmentEnd();
107 1 : }
108 :
109 3 : XclExpObjList::~XclExpObjList()
110 : {
111 1 : ::std::for_each(maObjs.begin(), maObjs.end(), ScDeleteObjectByPtr<XclObj>());
112 1 : delete pMsodrawingPerSheet;
113 1 : delete pSolverContainer;
114 2 : }
115 :
116 0 : sal_uInt16 XclExpObjList::Add( XclObj* pObj )
117 : {
118 : OSL_ENSURE( maObjs.size() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" );
119 :
120 0 : size_t nSize = maObjs.size();
121 :
122 0 : if ( nSize < 0xFFFF )
123 : {
124 0 : maObjs.push_back(pObj);
125 0 : ++nSize;
126 0 : pObj->SetId( nSize );
127 0 : pObj->SetTab( mnScTab );
128 : }
129 : else
130 : {
131 0 : delete pObj;
132 0 : nSize = 0;
133 : }
134 :
135 0 : return nSize;
136 : }
137 :
138 0 : void XclExpObjList::pop_back ()
139 : {
140 0 : maObjs.pop_back();
141 0 : }
142 :
143 1 : void XclExpObjList::EndSheet()
144 : {
145 : // Is there still something in the stream? -> The solver container
146 1 : if( mrEscherEx.HasPendingDffData() )
147 0 : pSolverContainer = new XclExpMsoDrawing( mrEscherEx );
148 :
149 : // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING
150 1 : mrEscherEx.CloseContainer();
151 1 : }
152 :
153 0 : void XclExpObjList::Save( XclExpStream& rStrm )
154 : {
155 : //! Escher must be written, even if there are no objects
156 0 : pMsodrawingPerSheet->Save( rStrm );
157 :
158 0 : std::vector<XclObj*>::iterator pIter;
159 0 : for ( pIter = maObjs.begin(); pIter != maObjs.end(); ++pIter )
160 0 : (*pIter)->Save( rStrm );
161 :
162 0 : if( pSolverContainer )
163 0 : pSolverContainer->Save( rStrm );
164 0 : }
165 :
166 0 : static bool IsVmlObject( const XclObj *rObj )
167 : {
168 0 : switch( rObj->GetObjType() )
169 : {
170 : case EXC_OBJTYPE_NOTE:
171 0 : return true;
172 : default:
173 0 : return false;
174 : }
175 : }
176 :
177 :
178 0 : static sal_Int32 GetVmlObjectCount( XclExpObjList& rList )
179 : {
180 0 : sal_Int32 nNumVml = 0;
181 :
182 0 : std::vector<XclObj*>::iterator pIter;
183 0 : for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
184 0 : if( IsVmlObject( *pIter ) )
185 0 : ++nNumVml;
186 :
187 0 : return nNumVml;
188 : }
189 :
190 :
191 0 : static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nDrawingMLCount )
192 : {
193 0 : sal_Int32 nVmlObjects = GetVmlObjectCount( rList );
194 0 : if( (rList.size() - nVmlObjects) == 0 )
195 0 : return;
196 :
197 0 : sal_Int32 nDrawing = ++nDrawingMLCount;
198 0 : OUString sId;
199 : sax_fastparser::FSHelperPtr pDrawing = rStrm.CreateOutputStream(
200 : XclXmlUtils::GetStreamName( "xl/", "drawings/drawing", nDrawing ),
201 : XclXmlUtils::GetStreamName( "../", "drawings/drawing", nDrawing ),
202 0 : rStrm.GetCurrentStream()->getOutputStream(),
203 : "application/vnd.openxmlformats-officedocument.drawing+xml",
204 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
205 0 : &sId );
206 :
207 0 : rStrm.GetCurrentStream()->singleElement( XML_drawing,
208 : FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
209 0 : FSEND );
210 :
211 0 : rStrm.PushStream( pDrawing );
212 : pDrawing->startElement( FSNS( XML_xdr, XML_wsDr ),
213 : FSNS( XML_xmlns, XML_xdr ), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
214 : FSNS( XML_xmlns, XML_a ), "http://schemas.openxmlformats.org/drawingml/2006/main",
215 : FSNS( XML_xmlns, XML_r ), "http://schemas.openxmlformats.org/officeDocument/2006/relationships",
216 0 : FSEND );
217 :
218 0 : std::vector<XclObj*>::iterator pIter;
219 0 : for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
220 : {
221 0 : if( IsVmlObject( *pIter ) )
222 0 : continue;
223 0 : (*pIter)->SaveXml( rStrm );
224 : }
225 :
226 0 : pDrawing->endElement( FSNS( XML_xdr, XML_wsDr ) );
227 :
228 0 : rStrm.PopStream();
229 : }
230 :
231 :
232 0 : static void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nVmlCount )
233 : {
234 0 : if( GetVmlObjectCount( rList ) == 0 )
235 0 : return;
236 :
237 0 : sal_Int32 nDrawing = ++nVmlCount;
238 0 : OUString sId;
239 : sax_fastparser::FSHelperPtr pVmlDrawing = rStrm.CreateOutputStream(
240 : XclXmlUtils::GetStreamName( "xl/", "drawings/vmlDrawing", nDrawing ),
241 : XclXmlUtils::GetStreamName( "../", "drawings/vmlDrawing", nDrawing ),
242 0 : rStrm.GetCurrentStream()->getOutputStream(),
243 : "application/vnd.openxmlformats-officedocument.vmlDrawing",
244 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
245 0 : &sId );
246 :
247 0 : rStrm.GetCurrentStream()->singleElement( XML_legacyDrawing,
248 : FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
249 0 : FSEND );
250 :
251 0 : rStrm.PushStream( pVmlDrawing );
252 : pVmlDrawing->startElement( XML_xml,
253 : FSNS( XML_xmlns, XML_v ), "urn:schemas-microsoft-com:vml",
254 : FSNS( XML_xmlns, XML_o ), "urn:schemas-microsoft-com:office:office",
255 : FSNS( XML_xmlns, XML_x ), "urn:schemas-microsoft-com:office:excel",
256 0 : FSEND );
257 :
258 0 : std::vector<XclObj*>::iterator pIter;
259 0 : for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
260 : {
261 0 : if( !IsVmlObject( *pIter ) )
262 0 : continue;
263 0 : (*pIter)->SaveXml( rStrm );
264 : }
265 :
266 0 : pVmlDrawing->endElement( XML_xml );
267 :
268 0 : rStrm.PopStream();
269 : }
270 :
271 :
272 1 : void XclExpObjList::SaveXml( XclExpXmlStream& rStrm )
273 : {
274 1 : if( pSolverContainer )
275 0 : pSolverContainer->SaveXml( rStrm );
276 :
277 1 : if( maObjs.empty())
278 2 : return;
279 :
280 0 : SaveDrawingMLObjects( *this, rStrm, mnDrawingMLCount );
281 0 : SaveVmlObjects( *this, rStrm, mnVmlCount );
282 : }
283 :
284 :
285 1 : void XclExpObjList::ResetCounters()
286 : {
287 1 : mnDrawingMLCount = 0;
288 1 : mnVmlCount = 0;
289 1 : }
290 :
291 : // --- class XclObj --------------------------------------------------
292 :
293 0 : XclObj::XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher ) :
294 : XclExpRecord( EXC_ID_OBJ, 26 ),
295 0 : mrEscherEx( rObjMgr.GetEscherEx() ),
296 : pClientTextbox( NULL ),
297 : pTxo( NULL ),
298 : mnObjType( nObjType ),
299 : nObjId(0),
300 : nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked
301 0 : bFirstOnSheet( !rObjMgr.HasObj() ),
302 0 : mbOwnEscher( bOwnEscher )
303 : {
304 : //! first object continues the first MSODRAWING record
305 0 : if ( bFirstOnSheet )
306 0 : pMsodrawing = rObjMgr.GetMsodrawingPerSheet();
307 : else
308 0 : pMsodrawing = new XclExpMsoDrawing( mrEscherEx );
309 0 : }
310 :
311 0 : XclObj::~XclObj()
312 : {
313 0 : if ( !bFirstOnSheet )
314 0 : delete pMsodrawing;
315 0 : delete pClientTextbox;
316 0 : delete pTxo;
317 0 : }
318 :
319 0 : void XclObj::ImplWriteAnchor( const XclExpRoot& /*rRoot*/, const SdrObject* pSdrObj, const Rectangle* pChildAnchor )
320 : {
321 0 : if( pChildAnchor )
322 : {
323 0 : mrEscherEx.AddChildAnchor( *pChildAnchor );
324 : }
325 0 : else if( pSdrObj )
326 : {
327 0 : ::std::auto_ptr< XclExpDffAnchorBase > xDffAnchor( mrEscherEx.CreateDffAnchor( *pSdrObj ) );
328 0 : xDffAnchor->WriteDffData( mrEscherEx );
329 : }
330 0 : }
331 :
332 0 : void XclObj::SetEscherShapeType( sal_uInt16 nType )
333 : {
334 : //2do: what about the other defined ot... types?
335 0 : switch ( nType )
336 : {
337 : case ESCHER_ShpInst_Line :
338 0 : mnObjType = EXC_OBJTYPE_LINE;
339 0 : break;
340 : case ESCHER_ShpInst_Rectangle :
341 : case ESCHER_ShpInst_RoundRectangle :
342 0 : mnObjType = EXC_OBJTYPE_RECTANGLE;
343 0 : break;
344 : case ESCHER_ShpInst_Ellipse :
345 0 : mnObjType = EXC_OBJTYPE_OVAL;
346 0 : break;
347 : case ESCHER_ShpInst_Arc :
348 0 : mnObjType = EXC_OBJTYPE_ARC;
349 0 : break;
350 : case ESCHER_ShpInst_TextBox :
351 0 : mnObjType = EXC_OBJTYPE_TEXT;
352 0 : break;
353 : case ESCHER_ShpInst_PictureFrame :
354 0 : mnObjType = EXC_OBJTYPE_PICTURE;
355 0 : break;
356 : default:
357 0 : mnObjType = EXC_OBJTYPE_DRAWING;
358 : }
359 0 : }
360 :
361 0 : void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj )
362 : {
363 : OSL_ENSURE( !pClientTextbox, "XclObj::SetText: already set" );
364 0 : if ( !pClientTextbox )
365 : {
366 0 : mrEscherEx.UpdateDffFragmentEnd();
367 0 : pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
368 0 : mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
369 0 : mrEscherEx.UpdateDffFragmentEnd();
370 0 : pTxo = new XclTxo( rRoot, rObj );
371 : }
372 0 : }
373 :
374 0 : void XclObj::WriteBody( XclExpStream& rStrm )
375 : {
376 : OSL_ENSURE( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" );
377 :
378 : // create a substream to be able to create subrecords
379 0 : SvMemoryStream aMemStrm;
380 0 : ::std::auto_ptr< XclExpStream > pXclStrm( new XclExpStream( aMemStrm, rStrm.GetRoot() ) );
381 :
382 : // write the ftCmo subrecord
383 0 : pXclStrm->StartRecord( EXC_ID_OBJCMO, 18 );
384 0 : *pXclStrm << mnObjType << nObjId << nGrbit;
385 0 : pXclStrm->WriteZeroBytes( 12 );
386 0 : pXclStrm->EndRecord();
387 :
388 : // write other subrecords
389 0 : WriteSubRecs( *pXclStrm );
390 :
391 : // write the ftEnd subrecord
392 0 : pXclStrm->StartRecord( EXC_ID_OBJEND, 0 );
393 0 : pXclStrm->EndRecord();
394 :
395 : // copy the data to the OBJ record
396 0 : pXclStrm.reset();
397 0 : aMemStrm.Seek( 0 );
398 0 : rStrm.CopyFromStream( aMemStrm );
399 0 : }
400 :
401 0 : void XclObj::Save( XclExpStream& rStrm )
402 : {
403 : // MSODRAWING record (msofbtSpContainer)
404 0 : if ( !bFirstOnSheet )
405 0 : pMsodrawing->Save( rStrm );
406 :
407 : // OBJ
408 0 : XclExpRecord::Save( rStrm );
409 :
410 : // second MSODRAWING record and TXO and CONTINUE records
411 0 : SaveTextRecs( rStrm );
412 0 : }
413 :
414 0 : void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ )
415 : {
416 0 : }
417 :
418 0 : void XclObj::SaveTextRecs( XclExpStream& rStrm )
419 : {
420 : // MSODRAWING record (msofbtClientTextbox)
421 0 : if ( pClientTextbox )
422 0 : pClientTextbox->Save( rStrm );
423 : // TXO and CONTINUE records
424 0 : if ( pTxo )
425 0 : pTxo->Save( rStrm );
426 0 : }
427 :
428 : // --- class XclObjComment ------------------------------------------
429 :
430 0 : XclObjComment::XclObjComment( XclExpObjectManager& rObjMgr, const Rectangle& rRect, const EditTextObject& rEditObj, SdrCaptionObj* pCaption, bool bVisible, const ScAddress& rAddress, Rectangle &rFrom, Rectangle &rTo ) :
431 : XclObj( rObjMgr, EXC_OBJTYPE_NOTE, true )
432 : , maScPos( rAddress )
433 0 : , mpCaption( static_cast< SdrCaptionObj* >( pCaption->Clone() ) )
434 : , mbVisible( bVisible )
435 : , maFrom ( rFrom )
436 0 : , maTo ( rTo )
437 : {
438 0 : ProcessEscherObj( rObjMgr.GetRoot(), rRect, pCaption, bVisible);
439 : // TXO
440 0 : pTxo = new XclTxo( rObjMgr.GetRoot(), rEditObj, pCaption );
441 0 : }
442 :
443 0 : static void lcl_FillProps( EscherPropertyContainer& rPropOpt, SdrObject* pCaption, bool bVisible )
444 : {
445 0 : if( pCaption )
446 : {
447 0 : Reference< XShape > aXShape = GetXShapeForSdrObject( pCaption );
448 0 : Reference< XPropertySet > aXPropSet( aXShape, UNO_QUERY );
449 0 : if( aXPropSet.is() )
450 : {
451 0 : rPropOpt.CreateFillProperties( aXPropSet, sal_True);
452 :
453 0 : rPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // undocumented
454 0 : rPropOpt.AddOpt( 0x0158, 0x00000000 ); // undocumented
455 :
456 0 : sal_uInt32 nValue = 0;
457 0 : if( !rPropOpt.GetOpt( ESCHER_Prop_FitTextToShape, nValue ) )
458 0 : rPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
459 :
460 0 : if( rPropOpt.GetOpt( ESCHER_Prop_fillColor, nValue ) )
461 : {
462 : // If the Colour is the same as the 'ToolTip' System colour then
463 : // use the default rather than the explicit colour value. This will
464 : // be incorrect where user has chosen to use this colour explicity.
465 0 : Color aColor = Color( (sal_uInt8)nValue, (sal_uInt8)( nValue >> 8 ), (sal_uInt8)( nValue >> 16 ) );
466 0 : const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
467 0 : if( aColor == rSett.GetHelpColor().GetColor() )
468 : {
469 0 : rPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
470 0 : rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
471 : }
472 : }
473 : else
474 0 : rPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
475 :
476 0 : if( !rPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nValue ) )
477 0 : rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
478 0 : if( !rPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ) )
479 0 : rPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 ); // bool field
480 0 : if( !rPropOpt.GetOpt( ESCHER_Prop_shadowColor, nValue ) )
481 0 : rPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x00000000 );
482 0 : if( !rPropOpt.GetOpt( ESCHER_Prop_fshadowObscured, nValue ) ) // bool field
483 0 : rPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // bool field
484 0 : }
485 : }
486 :
487 0 : sal_uInt32 nFlags = 0x000A0000;
488 0 : ::set_flag( nFlags, sal_uInt32(2), !bVisible );
489 0 : rPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field
490 0 : }
491 :
492 0 : void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible )
493 : {
494 0 : EscherPropertyContainer aPropOpt;
495 :
496 :
497 0 : lcl_FillProps( aPropOpt, pCaption, bVisible );
498 :
499 0 : nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked
500 0 : mrEscherEx.OpenContainer( ESCHER_SpContainer );
501 0 : mrEscherEx.AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
502 0 : aPropOpt.Commit( mrEscherEx.GetStream() );
503 :
504 0 : XclExpDffNoteAnchor( rRoot, rRect ).WriteDffData( mrEscherEx );
505 :
506 0 : mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
507 0 : mrEscherEx.UpdateDffFragmentEnd();
508 :
509 : //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the
510 : //! base OBJ's MSODRAWING record Escher data is completed.
511 0 : pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
512 0 : mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
513 0 : mrEscherEx.UpdateDffFragmentEnd();
514 0 : mrEscherEx.CloseContainer(); // ESCHER_SpContainer
515 0 : }
516 :
517 0 : XclObjComment::~XclObjComment()
518 : {
519 0 : }
520 :
521 0 : void XclObjComment::Save( XclExpStream& rStrm )
522 : {
523 : // content of this record
524 0 : XclObj::Save( rStrm );
525 0 : }
526 :
527 0 : class VmlCommentExporter : public VMLExport
528 : {
529 : ScAddress maScPos;
530 : SdrCaptionObj* mpCaption;
531 : bool mbVisible;
532 : Rectangle maFrom;
533 : Rectangle maTo;
534 :
535 : public:
536 : VmlCommentExporter ( sax_fastparser::FSHelperPtr p, ScAddress aScPos, SdrCaptionObj* pCaption, bool bVisible, Rectangle &aFrom, Rectangle &aTo );
537 : protected:
538 : virtual void Commit( EscherPropertyContainer& rProps, const Rectangle& rRect );
539 : using VMLExport::StartShape;
540 : virtual sal_Int32 StartShape();
541 : using VMLExport::EndShape;
542 : virtual void EndShape( sal_Int32 nShapeElement );
543 : };
544 :
545 :
546 0 : VmlCommentExporter::VmlCommentExporter( sax_fastparser::FSHelperPtr p, ScAddress aScPos, SdrCaptionObj* pCaption,
547 : bool bVisible, Rectangle &aFrom, Rectangle &aTo )
548 : : VMLExport( p )
549 : , maScPos( aScPos )
550 : , mpCaption( pCaption )
551 : , mbVisible( bVisible )
552 : , maFrom ( aFrom )
553 0 : , maTo ( aTo )
554 : {
555 0 : }
556 :
557 0 : void VmlCommentExporter::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect )
558 : {
559 0 : lcl_FillProps( rProps, mpCaption, mbVisible );
560 0 : rProps.AddOpt( ESCHER_Prop_fHidden, mbVisible ); // bool field
561 :
562 : // shadow property value for comment ( set in lcl_FillProps [*] ) has been
563 : // overwritten by new value ( 0x20000 ) in the generic part of the export
564 : // ( see EscherPropertyContainer::CreateShadowProperties )
565 : // Safer option here is to just force the needed value here for oox vml
566 : // export alone ( and avoid potential problems with binary export )
567 : // #TODO investigate value of ESCHER_Prop_fshadowObscured generally
568 : // in binary export ( if indeed this value is good for binary export )
569 : // we can change the heuristics and/or initialisation path and get
570 : // rid of line below.
571 : // [*] lcl_FillProps seems to be called twice when exporting to xlsx
572 : // once from XclObjComment::ProcessEscherObj #TODO look into that also
573 0 : rProps.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // force value for comments
574 :
575 0 : VMLExport::Commit( rProps, rRect );
576 0 : }
577 :
578 0 : sal_Int32 VmlCommentExporter::StartShape()
579 : {
580 0 : AddShapeAttribute( XML_type, OString( "#_x0000_t202") );
581 :
582 0 : sal_Int32 nId = VMLExport::StartShape();
583 :
584 0 : return nId;
585 : }
586 :
587 0 : void VmlCommentExporter::EndShape( sal_Int32 nShapeElement )
588 : {
589 : char pAnchor[100];
590 0 : sax_fastparser::FSHelperPtr pVmlDrawing = GetFS();
591 : snprintf( pAnchor, 100, "%ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld",
592 0 : maFrom.Left(), maFrom.Top(), maFrom.Right(), maFrom.Bottom(),
593 0 : maTo.Left(), maTo.Top(), maTo.Right(), maTo.Bottom() );
594 :
595 : pVmlDrawing->startElement( FSNS( XML_x, XML_ClientData ),
596 : XML_ObjectType, "Note",
597 0 : FSEND );
598 : pVmlDrawing->singleElement( FSNS( XML_x, XML_MoveWithCells ),
599 0 : FSEND );
600 : pVmlDrawing->singleElement( FSNS( XML_x, XML_SizeWithCells ),
601 0 : FSEND );
602 0 : XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Anchor ), pAnchor );
603 0 : XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_AutoFill ), "False" );
604 0 : XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Row ), maScPos.Row() );
605 0 : XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Column ), sal_Int32( maScPos.Col() ) );
606 0 : pVmlDrawing->endElement( FSNS( XML_x, XML_ClientData ) );
607 :
608 0 : VMLExport::EndShape( nShapeElement );
609 0 : }
610 :
611 0 : void XclObjComment::SaveXml( XclExpXmlStream& rStrm )
612 : {
613 0 : VmlCommentExporter aCommentExporter( rStrm.GetCurrentStream(), maScPos, mpCaption.get(), mbVisible, maFrom, maTo );
614 0 : aCommentExporter.AddSdrObject( *mpCaption );
615 0 : }
616 :
617 :
618 : // --- class XclObjDropDown ------------------------------------------
619 :
620 0 : XclObjDropDown::XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, sal_Bool bFilt ) :
621 : XclObj( rObjMgr, EXC_OBJTYPE_DROPDOWN, true ),
622 0 : bIsFiltered( bFilt )
623 : {
624 0 : SetLocked( sal_True );
625 0 : SetPrintable( false );
626 0 : SetAutoFill( sal_True );
627 0 : SetAutoLine( false );
628 0 : nGrbit |= 0x0100; // undocumented
629 0 : mrEscherEx.OpenContainer( ESCHER_SpContainer );
630 0 : mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
631 0 : EscherPropertyContainer aPropOpt;
632 0 : aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field
633 0 : aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
634 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field
635 0 : aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
636 0 : aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field
637 0 : aPropOpt.Commit( mrEscherEx.GetStream() );
638 :
639 0 : XclExpDffDropDownAnchor( rObjMgr.GetRoot(), rPos ).WriteDffData( mrEscherEx );
640 :
641 0 : mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
642 0 : mrEscherEx.UpdateDffFragmentEnd();
643 0 : mrEscherEx.CloseContainer(); // ESCHER_SpContainer
644 :
645 : // old size + ftSbs + ftLbsData
646 0 : AddRecSize( 24 + 20 );
647 0 : }
648 :
649 0 : XclObjDropDown::~XclObjDropDown()
650 : {
651 0 : }
652 :
653 0 : void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm )
654 : {
655 : // ftSbs subrecord - Scroll bars (dummy)
656 0 : rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
657 0 : rStrm.WriteZeroBytes( 20 );
658 0 : rStrm.EndRecord();
659 :
660 : // ftLbsData subrecord - Listbox data
661 0 : sal_uInt16 nDropDownFlags = 0;
662 0 : ::insert_value( nDropDownFlags, EXC_OBJ_DROPDOWN_SIMPLE, 0, 2 );
663 0 : ::set_flag( nDropDownFlags, EXC_OBJ_DROPDOWN_FILTERED, bIsFiltered );
664 0 : rStrm.StartRecord( EXC_ID_OBJLBSDATA, 16 );
665 0 : rStrm << (sal_uInt32)0 << (sal_uInt16)0 << (sal_uInt16)0x0301 << (sal_uInt16)0
666 0 : << nDropDownFlags << sal_uInt16( 20 ) << sal_uInt16( 130 );
667 0 : rStrm.EndRecord();
668 0 : }
669 :
670 : // --- class XclTxo --------------------------------------------------
671 :
672 0 : static sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet )
673 : {
674 0 : sal_uInt8 nHorAlign = EXC_OBJ_HOR_LEFT;
675 :
676 0 : switch( static_cast< const SvxAdjustItem& >( rItemSet.Get( EE_PARA_JUST ) ).GetAdjust() )
677 : {
678 0 : case SVX_ADJUST_LEFT: nHorAlign = EXC_OBJ_HOR_LEFT; break;
679 0 : case SVX_ADJUST_CENTER: nHorAlign = EXC_OBJ_HOR_CENTER; break;
680 0 : case SVX_ADJUST_RIGHT: nHorAlign = EXC_OBJ_HOR_RIGHT; break;
681 0 : case SVX_ADJUST_BLOCK: nHorAlign = EXC_OBJ_HOR_JUSTIFY; break;
682 : default:;
683 : }
684 0 : return nHorAlign;
685 : }
686 :
687 0 : static sal_uInt8 lcl_GetVerAlignFromItemSet( const SfxItemSet& rItemSet )
688 : {
689 0 : sal_uInt8 nVerAlign = EXC_OBJ_VER_TOP;
690 :
691 0 : switch( static_cast< const SdrTextVertAdjustItem& >( rItemSet.Get( SDRATTR_TEXT_VERTADJUST ) ).GetValue() )
692 : {
693 0 : case SDRTEXTVERTADJUST_TOP: nVerAlign = EXC_OBJ_VER_TOP; break;
694 0 : case SDRTEXTVERTADJUST_CENTER: nVerAlign = EXC_OBJ_VER_CENTER; break;
695 0 : case SDRTEXTVERTADJUST_BOTTOM: nVerAlign = EXC_OBJ_VER_BOTTOM; break;
696 0 : case SDRTEXTVERTADJUST_BLOCK: nVerAlign = EXC_OBJ_VER_JUSTIFY; break;
697 : }
698 0 : return nVerAlign;
699 : }
700 :
701 0 : XclTxo::XclTxo( const String& rString, sal_uInt16 nFontIx ) :
702 0 : mpString( new XclExpString( rString ) ),
703 : mnRotation( EXC_OBJ_ORIENT_NONE ),
704 : mnHorAlign( EXC_OBJ_HOR_LEFT ),
705 0 : mnVerAlign( EXC_OBJ_VER_TOP )
706 : {
707 0 : if( mpString->Len() )
708 : {
709 : // If there is text, Excel *needs* the 2nd CONTINUE record with at least two format runs
710 0 : mpString->AppendFormat( 0, nFontIx );
711 0 : mpString->AppendFormat( mpString->Len(), EXC_FONT_APP );
712 : }
713 0 : }
714 :
715 0 : XclTxo::XclTxo( const XclExpRoot& rRoot, const SdrTextObj& rTextObj ) :
716 : mpString( XclExpStringHelper::CreateString( rRoot, rTextObj ) ),
717 : mnRotation( EXC_OBJ_ORIENT_NONE ),
718 : mnHorAlign( EXC_OBJ_HOR_LEFT ),
719 0 : mnVerAlign( EXC_OBJ_VER_TOP )
720 : {
721 : // additional alignment and orientation items
722 0 : const SfxItemSet& rItemSet = rTextObj.GetMergedItemSet();
723 :
724 : // horizontal alignment
725 0 : SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
726 :
727 : // vertical alignment
728 0 : SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
729 :
730 : // rotation
731 0 : long nAngle = rTextObj.GetRotateAngle();
732 0 : if( (4500 < nAngle) && (nAngle < 13500) )
733 0 : mnRotation = EXC_OBJ_ORIENT_90CCW;
734 0 : else if( (22500 < nAngle) && (nAngle < 31500) )
735 0 : mnRotation = EXC_OBJ_ORIENT_90CW;
736 : else
737 0 : mnRotation = EXC_OBJ_ORIENT_NONE;
738 0 : }
739 :
740 0 : XclTxo::XclTxo( const XclExpRoot& rRoot, const EditTextObject& rEditObj, SdrObject* pCaption ) :
741 : mpString( XclExpStringHelper::CreateString( rRoot, rEditObj ) ),
742 : mnRotation( EXC_OBJ_ORIENT_NONE ),
743 : mnHorAlign( EXC_OBJ_HOR_LEFT ),
744 0 : mnVerAlign( EXC_OBJ_VER_TOP )
745 : {
746 0 : if(pCaption)
747 : {
748 : // Excel has one alignment per NoteObject while Calc supports
749 : // one alignment per paragraph - use the first paragraph
750 : // alignment (if set) as our overall alignment.
751 0 : String aParaText( rEditObj.GetText( 0 ) );
752 0 : if( aParaText.Len() )
753 : {
754 0 : SfxItemSet aSet( rEditObj.GetParaAttribs( 0));
755 0 : const SfxPoolItem* pItem = NULL;
756 0 : if( aSet.GetItemState( EE_PARA_JUST, sal_True, &pItem ) == SFX_ITEM_SET )
757 : {
758 0 : SvxAdjust eEEAlign = static_cast< const SvxAdjustItem& >( *pItem ).GetAdjust();
759 0 : pCaption->SetMergedItem( SvxAdjustItem( eEEAlign, EE_PARA_JUST ) );
760 0 : }
761 : }
762 0 : const SfxItemSet& rItemSet = pCaption->GetMergedItemSet();
763 :
764 : // horizontal alignment
765 0 : SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
766 :
767 : // vertical alignment
768 0 : SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
769 :
770 : // orientation alignment
771 0 : const SvxWritingModeItem& rItem = static_cast< const SvxWritingModeItem& >( rItemSet.Get( SDRATTR_TEXTDIRECTION ) );
772 0 : if( rItem.GetValue() == com::sun::star::text::WritingMode_TB_RL )
773 0 : mnRotation = EXC_OBJ_ORIENT_90CW;
774 : }
775 0 : }
776 :
777 0 : void XclTxo::SaveCont( XclExpStream& rStrm )
778 : {
779 : OSL_ENSURE( mpString.get(), "XclTxo::SaveCont - missing string" );
780 :
781 : // #i96858# do not save existing string formatting if text is empty
782 0 : sal_uInt16 nRunLen = mpString->IsEmpty() ? 0 : (8 * mpString->GetFormatsCount());
783 : // alignment
784 0 : sal_uInt16 nFlags = 0;
785 0 : ::insert_value( nFlags, mnHorAlign, 1, 3 );
786 0 : ::insert_value( nFlags, mnVerAlign, 4, 3 );
787 :
788 0 : rStrm << nFlags << mnRotation;
789 0 : rStrm.WriteZeroBytes( 6 );
790 0 : rStrm << mpString->Len() << nRunLen << sal_uInt32( 0 );
791 0 : }
792 :
793 0 : void XclTxo::Save( XclExpStream& rStrm )
794 : {
795 : // Write the TXO part
796 0 : ExcRecord::Save( rStrm );
797 :
798 : // CONTINUE records are only written if there is some text
799 0 : if( !mpString->IsEmpty() )
800 : {
801 : // CONTINUE for character array
802 0 : rStrm.StartRecord( EXC_ID_CONT, mpString->GetBufferSize() + 1 );
803 0 : rStrm << static_cast< sal_uInt8 >( mpString->GetFlagField() & EXC_STRF_16BIT ); // only Unicode flag
804 0 : mpString->WriteBuffer( rStrm );
805 0 : rStrm.EndRecord();
806 :
807 : // CONTINUE for formatting runs
808 0 : rStrm.StartRecord( EXC_ID_CONT, 8 * mpString->GetFormatsCount() );
809 0 : const XclFormatRunVec& rFormats = mpString->GetFormats();
810 0 : for( XclFormatRunVec::const_iterator aIt = rFormats.begin(), aEnd = rFormats.end(); aIt != aEnd; ++aIt )
811 0 : rStrm << aIt->mnChar << aIt->mnFontIdx << sal_uInt32( 0 );
812 0 : rStrm.EndRecord();
813 : }
814 0 : }
815 :
816 0 : sal_uInt16 XclTxo::GetNum() const
817 : {
818 0 : return EXC_ID_TXO;
819 : }
820 :
821 0 : sal_Size XclTxo::GetLen() const
822 : {
823 0 : return 18;
824 : }
825 :
826 : // --- class XclObjOle -------------------------------------------
827 :
828 0 : XclObjOle::XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ) :
829 : XclObj( rObjMgr, EXC_OBJTYPE_PICTURE ),
830 : rOleObj( rObj ),
831 0 : pRootStorage( rObjMgr.GetRoot().GetRootStorage() )
832 : {
833 0 : }
834 :
835 0 : XclObjOle::~XclObjOle()
836 : {
837 0 : }
838 :
839 0 : void XclObjOle::WriteSubRecs( XclExpStream& rStrm )
840 : {
841 : // write only as embedded, not linked
842 0 : String aStorageName( RTL_CONSTASCII_USTRINGPARAM( "MBD" ) );
843 : sal_Char aBuf[ sizeof(sal_uInt32) * 2 + 1 ];
844 : // FIXME Eeek! Is this just a way to get a unique id?
845 0 : sal_uInt32 nPictureId = sal_uInt32(sal_uIntPtr(this) >> 2);
846 0 : sprintf( aBuf, "%08X", static_cast< unsigned int >( nPictureId ) );
847 0 : aStorageName.AppendAscii( aBuf );
848 : SotStorageRef xOleStg = pRootStorage->OpenSotStorage( aStorageName,
849 0 : STREAM_READWRITE| STREAM_SHARE_DENYALL );
850 0 : if( xOleStg.Is() )
851 : {
852 0 : uno::Reference < embed::XEmbeddedObject > xObj( ((SdrOle2Obj&)rOleObj).GetObjRef() );
853 0 : if ( xObj.is() )
854 : {
855 : // set version to "old" version, because it must be
856 : // saved in MS notation.
857 0 : sal_uInt32 nFl = 0;
858 0 : const SvtFilterOptions& rFltOpts = SvtFilterOptions::Get();
859 0 : if( rFltOpts.IsMath2MathType() )
860 0 : nFl |= OLE_STARMATH_2_MATHTYPE;
861 :
862 0 : if( rFltOpts.IsWriter2WinWord() )
863 0 : nFl |= OLE_STARWRITER_2_WINWORD;
864 :
865 0 : if( rFltOpts.IsCalc2Excel() )
866 0 : nFl |= OLE_STARCALC_2_EXCEL;
867 :
868 0 : if( rFltOpts.IsImpress2PowerPoint() )
869 0 : nFl |= OLE_STARIMPRESS_2_POWERPOINT;
870 :
871 0 : SvxMSExportOLEObjects aOLEExpFilt( nFl );
872 0 : aOLEExpFilt.ExportOLEObject( xObj, *xOleStg );
873 :
874 : // OBJCF subrecord, undocumented as usual
875 0 : rStrm.StartRecord( EXC_ID_OBJCF, 2 );
876 0 : rStrm << sal_uInt16(0x0002);
877 0 : rStrm.EndRecord();
878 :
879 : // OBJFLAGS subrecord, undocumented as usual
880 0 : rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
881 0 : sal_uInt16 nFlags = EXC_OBJ_PIC_MANUALSIZE;
882 0 : ::set_flag( nFlags, EXC_OBJ_PIC_SYMBOL, ((SdrOle2Obj&)rOleObj).GetAspect() == embed::Aspects::MSOLE_ICON );
883 0 : rStrm << nFlags;
884 0 : rStrm.EndRecord();
885 :
886 : // OBJPICTFMLA subrecord, undocumented as usual
887 0 : XclExpString aName( xOleStg->GetUserName() );
888 0 : sal_uInt16 nPadLen = (sal_uInt16)(aName.GetSize() & 0x01);
889 0 : sal_uInt16 nFmlaLen = static_cast< sal_uInt16 >( 12 + aName.GetSize() + nPadLen );
890 0 : sal_uInt16 nSubRecLen = nFmlaLen + 6;
891 :
892 0 : rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nSubRecLen );
893 0 : rStrm << nFmlaLen
894 0 : << sal_uInt16( 5 ) << sal_uInt32( 0 ) << sal_uInt8( 2 )
895 0 : << sal_uInt32( 0 ) << sal_uInt8( 3 )
896 0 : << aName;
897 0 : if( nPadLen )
898 0 : rStrm << sal_uInt8( 0 ); // pad byte
899 0 : rStrm << nPictureId;
900 0 : rStrm.EndRecord();
901 0 : }
902 0 : }
903 0 : }
904 :
905 0 : void XclObjOle::Save( XclExpStream& rStrm )
906 : {
907 : // content of this record
908 0 : XclObj::Save( rStrm );
909 0 : }
910 :
911 : // --- class XclObjAny -------------------------------------------
912 :
913 0 : XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr, const Reference< XShape >& rShape )
914 : : XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN )
915 0 : , mxShape( rShape )
916 : {
917 0 : }
918 :
919 0 : XclObjAny::~XclObjAny()
920 : {
921 0 : }
922 :
923 0 : void XclObjAny::WriteSubRecs( XclExpStream& rStrm )
924 : {
925 0 : if( mnObjType == EXC_OBJTYPE_GROUP )
926 : // ftGmo subrecord
927 0 : rStrm << EXC_ID_OBJGMO << sal_uInt16(2) << sal_uInt16(0);
928 0 : }
929 :
930 0 : void XclObjAny::Save( XclExpStream& rStrm )
931 : {
932 0 : if( mnObjType == EXC_OBJTYPE_GROUP )
933 : // old size + ftGmo
934 0 : AddRecSize( 6 );
935 :
936 : // content of this record
937 0 : XclObj::Save( rStrm );
938 0 : }
939 :
940 : // --- class ExcBof8_Base --------------------------------------------
941 :
942 2 : ExcBof8_Base::ExcBof8_Base()
943 : {
944 2 : nVers = 0x0600;
945 2 : nRupBuild = 0x0dbb;
946 2 : nRupYear = 0x07cc;
947 : // nFileHistory = 0x00000001; // last edited by Microsoft Excel for Windows
948 2 : nFileHistory = 0x00000000;
949 2 : nLowestBiffVer = 0x00000006; // Biff8
950 2 : }
951 0 : void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const Reference< XShape >& rShape, SCTAB nTab )
952 : {
953 0 : sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
954 :
955 0 : awt::Point aTopLeft = rShape->getPosition();
956 0 : awt::Size aSize = rShape->getSize();
957 0 : Rectangle aLocation( aTopLeft.X, aTopLeft.Y, aTopLeft.X + aSize.Width, aTopLeft.Y + aSize.Height );
958 0 : ScRange aRange = rStrm.GetRoot().GetDoc().GetRange( nTab, aLocation );
959 0 : Rectangle aRangeRect = rStrm.GetRoot().GetDoc().GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(),
960 0 : aRange.aEnd.Col()-1, aRange.aEnd.Row()-1,
961 0 : nTab );
962 :
963 :
964 : pDrawing->startElement( FSNS( XML_xdr, XML_from ),
965 0 : FSEND );
966 0 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_col ), (sal_Int32) aRange.aStart.Col() );
967 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_colOff ),
968 0 : MM100toEMU( aLocation.Left() - aRangeRect.Left() ) );
969 0 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_row ), (sal_Int32) aRange.aStart.Row() );
970 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_rowOff ),
971 0 : MM100toEMU( aLocation.Top() - aRangeRect.Top() ) );
972 0 : pDrawing->endElement( FSNS( XML_xdr, XML_from ) );
973 :
974 : pDrawing->startElement( FSNS( XML_xdr, XML_to ),
975 0 : FSEND );
976 0 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_col ), (sal_Int32) aRange.aEnd.Col() );
977 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_colOff ),
978 0 : MM100toEMU( aLocation.Right() - aRangeRect.Right() ) );
979 0 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_row ), (sal_Int32) aRange.aEnd.Row() );
980 : XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_rowOff ),
981 0 : MM100toEMU( aLocation.Bottom() - aRangeRect.Bottom() ) );
982 0 : pDrawing->endElement( FSNS( XML_xdr, XML_to ) );
983 0 : }
984 :
985 0 : void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj )
986 : {
987 0 : WriteFromTo( rStrm, rObj.GetShape(), rObj.GetTab() );
988 0 : }
989 :
990 : static const char*
991 0 : GetEditAs( XclObjAny& rObj )
992 : {
993 0 : if( const SdrObject* pShape = EscherEx::GetSdrObject( rObj.GetShape() ) )
994 : {
995 : // OOXTODO: returning "twoCell"
996 0 : switch( ScDrawLayer::GetAnchorType( *pShape ) )
997 : {
998 0 : case SCA_CELL: return "oneCell";
999 0 : default: break;
1000 : }
1001 : }
1002 0 : return "absolute";
1003 : }
1004 :
1005 :
1006 0 : void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
1007 : {
1008 : // ignore group shapes at the moment, we don't process them correctly
1009 : // leading to ms2010 rejecting the content
1010 0 : if( !mxShape.is() || mxShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
1011 0 : return;
1012 :
1013 0 : sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
1014 :
1015 0 : ShapeExport aDML( XML_xdr, pDrawing, NULL, &rStrm, DrawingML::DOCUMENT_XLSX );
1016 :
1017 : pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor
1018 : XML_editAs, GetEditAs( *this ),
1019 0 : FSEND );
1020 0 : Reference< XPropertySet > xPropSet( mxShape, UNO_QUERY );
1021 0 : if (xPropSet.is())
1022 : {
1023 0 : WriteFromTo( rStrm, *this );
1024 0 : aDML.WriteShape( mxShape );
1025 : }
1026 :
1027 : pDrawing->singleElement( FSNS( XML_xdr, XML_clientData),
1028 : // OOXTODO: XML_fLocksWithSheet
1029 : // OOXTODO: XML_fPrintsWithSheet
1030 0 : FSEND );
1031 0 : pDrawing->endElement( FSNS( XML_xdr, XML_twoCellAnchor ) );
1032 : }
1033 :
1034 :
1035 :
1036 0 : void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
1037 : {
1038 0 : rStrm.DisableEncryption();
1039 0 : rStrm << nVers << nDocType << nRupBuild << nRupYear
1040 0 : << nFileHistory << nLowestBiffVer;
1041 0 : }
1042 :
1043 :
1044 0 : sal_uInt16 ExcBof8_Base::GetNum() const
1045 : {
1046 0 : return 0x0809;
1047 : }
1048 :
1049 :
1050 0 : sal_Size ExcBof8_Base::GetLen() const
1051 : {
1052 0 : return 16;
1053 : }
1054 :
1055 :
1056 : // --- class ExcBof8 -------------------------------------------------
1057 :
1058 1 : ExcBof8::ExcBof8()
1059 : {
1060 1 : nDocType = 0x0010;
1061 1 : }
1062 :
1063 :
1064 : // --- class ExcBofW8 ------------------------------------------------
1065 :
1066 1 : ExcBofW8::ExcBofW8()
1067 : {
1068 1 : nDocType = 0x0005;
1069 1 : }
1070 :
1071 :
1072 : // --- class ExcBundlesheet8 -----------------------------------------
1073 :
1074 1 : ExcBundlesheet8::ExcBundlesheet8( RootData& rRootData, SCTAB _nTab ) :
1075 : ExcBundlesheetBase( rRootData, static_cast<sal_uInt16>(_nTab) ),
1076 1 : sUnicodeName( rRootData.pER->GetTabInfo().GetScTabName( _nTab ) )
1077 : {
1078 1 : }
1079 :
1080 :
1081 0 : ExcBundlesheet8::ExcBundlesheet8( const String& rString ) :
1082 : ExcBundlesheetBase(),
1083 0 : sUnicodeName( rString )
1084 : {
1085 0 : }
1086 :
1087 :
1088 0 : XclExpString ExcBundlesheet8::GetName() const
1089 : {
1090 0 : return XclExpString( sUnicodeName, EXC_STR_8BITLENGTH );
1091 : }
1092 :
1093 :
1094 0 : void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
1095 : {
1096 0 : nOwnPos = rStrm.GetSvStreamPos();
1097 : // write dummy position, real position comes later
1098 0 : rStrm.DisableEncryption();
1099 0 : rStrm << sal_uInt32(0);
1100 0 : rStrm.EnableEncryption();
1101 0 : rStrm << nGrbit << GetName();
1102 0 : }
1103 :
1104 :
1105 0 : sal_Size ExcBundlesheet8::GetLen() const
1106 : { // Text max 255 chars
1107 0 : return 8 + GetName().GetBufferSize();
1108 : }
1109 :
1110 :
1111 1 : void ExcBundlesheet8::SaveXml( XclExpXmlStream& rStrm )
1112 : {
1113 1 : OUString sId;
1114 : rStrm.CreateOutputStream(
1115 : XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", nTab+1),
1116 : XclXmlUtils::GetStreamName( NULL, "worksheets/sheet", nTab+1),
1117 1 : rStrm.GetCurrentStream()->getOutputStream(),
1118 : "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
1119 : "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
1120 1 : &sId );
1121 :
1122 1 : rStrm.GetCurrentStream()->singleElement( XML_sheet,
1123 : XML_name, XclXmlUtils::ToOString( sUnicodeName ).getStr(),
1124 : XML_sheetId, rtl::OString::valueOf( (sal_Int32)( nTab+1 ) ).getStr(),
1125 : XML_state, nGrbit == 0x0000 ? "visible" : "hidden",
1126 : FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
1127 2 : FSEND );
1128 1 : }
1129 :
1130 :
1131 :
1132 : // --- class XclObproj -----------------------------------------------
1133 :
1134 0 : sal_uInt16 XclObproj::GetNum() const
1135 : {
1136 0 : return 0x00D3;
1137 : }
1138 :
1139 :
1140 0 : sal_Size XclObproj::GetLen() const
1141 : {
1142 0 : return 0;
1143 : }
1144 :
1145 :
1146 : // ---- class XclCodename --------------------------------------------
1147 :
1148 0 : XclCodename::XclCodename( const String& r ) : aName( r )
1149 : {
1150 0 : }
1151 :
1152 :
1153 0 : void XclCodename::SaveCont( XclExpStream& rStrm )
1154 : {
1155 0 : rStrm << aName;
1156 0 : }
1157 :
1158 :
1159 0 : sal_uInt16 XclCodename::GetNum() const
1160 : {
1161 0 : return 0x01BA;
1162 : }
1163 :
1164 :
1165 0 : sal_Size XclCodename::GetLen() const
1166 : {
1167 0 : return aName.GetSize();
1168 : }
1169 :
1170 :
1171 :
1172 : // ---- Scenarios ----------------------------------------------------
1173 :
1174 0 : ExcEScenarioCell::ExcEScenarioCell( sal_uInt16 nC, sal_uInt16 nR, const String& rTxt ) :
1175 : nCol( nC ),
1176 : nRow( nR ),
1177 0 : sText( rTxt, EXC_STR_DEFAULT, 255 )
1178 : {
1179 0 : }
1180 :
1181 0 : void ExcEScenarioCell::WriteAddress( XclExpStream& rStrm ) const
1182 : {
1183 0 : rStrm << nRow << nCol;
1184 0 : }
1185 :
1186 0 : void ExcEScenarioCell::WriteText( XclExpStream& rStrm ) const
1187 : {
1188 0 : rStrm << sText;
1189 0 : }
1190 :
1191 0 : void ExcEScenarioCell::SaveXml( XclExpXmlStream& rStrm ) const
1192 : {
1193 0 : rStrm.GetCurrentStream()->singleElement( XML_inputCells,
1194 : // OOXTODO: XML_deleted,
1195 : // OOXTODO: XML_numFmtId,
1196 : XML_r, XclXmlUtils::ToOString( ScAddress( nCol, nRow, 0 ) ).getStr(),
1197 : // OOXTODO: XML_undone,
1198 : XML_val, XclXmlUtils::ToOString( sText ).getStr(),
1199 0 : FSEND );
1200 0 : }
1201 :
1202 :
1203 :
1204 :
1205 0 : ExcEScenario::ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab )
1206 : {
1207 0 : String sTmpName;
1208 0 : String sTmpComm;
1209 0 : rtl::OUString aTmp;
1210 0 : Color aDummyCol;
1211 : sal_uInt16 nFlags;
1212 :
1213 0 : ScDocument& rDoc = rRoot.GetDoc();
1214 0 : rDoc.GetName(nTab, aTmp);
1215 0 : sTmpName = aTmp;
1216 0 : sName.Assign( sTmpName, EXC_STR_8BITLENGTH );
1217 0 : nRecLen = 8 + sName.GetBufferSize();
1218 :
1219 0 : rDoc.GetScenarioData( nTab, aTmp, aDummyCol, nFlags );
1220 0 : sTmpComm = aTmp;
1221 0 : sComment.Assign( sTmpComm, EXC_STR_DEFAULT, 255 );
1222 0 : if( sComment.Len() )
1223 0 : nRecLen += sComment.GetSize();
1224 0 : nProtected = (nFlags & SC_SCENARIO_PROTECT) ? 1 : 0;
1225 :
1226 0 : sUserName.Assign( rRoot.GetUserName(), EXC_STR_DEFAULT, 255 );
1227 0 : nRecLen += sUserName.GetSize();
1228 :
1229 0 : const ScRangeList* pRList = rDoc.GetScenarioRanges( nTab );
1230 0 : if( !pRList )
1231 0 : return;
1232 :
1233 0 : sal_Bool bContLoop = sal_True;
1234 : SCROW nRow;
1235 : SCCOL nCol;
1236 0 : String sText;
1237 : double fVal;
1238 :
1239 0 : for( size_t nRange = 0; (nRange < pRList->size()) && bContLoop; nRange++ )
1240 : {
1241 0 : const ScRange* pRange = (*pRList)[nRange];
1242 0 : for( nRow = pRange->aStart.Row(); (nRow <= pRange->aEnd.Row()) && bContLoop; nRow++ )
1243 0 : for( nCol = pRange->aStart.Col(); (nCol <= pRange->aEnd.Col()) && bContLoop; nCol++ )
1244 : {
1245 0 : if( rDoc.HasValueData( nCol, nRow, nTab ) )
1246 : {
1247 0 : rDoc.GetValue( nCol, nRow, nTab, fVal );
1248 : sText = ::rtl::math::doubleToUString( fVal,
1249 : rtl_math_StringFormat_Automatic,
1250 : rtl_math_DecimalPlaces_Max,
1251 0 : ScGlobal::pLocaleData->getNumDecimalSep()[0],
1252 0 : sal_True );
1253 : }
1254 : else
1255 0 : rDoc.GetString( nCol, nRow, nTab, sText );
1256 : bContLoop = Append( static_cast<sal_uInt16>(nCol),
1257 0 : static_cast<sal_uInt16>(nRow), sText );
1258 : }
1259 0 : }
1260 : }
1261 :
1262 0 : ExcEScenario::~ExcEScenario()
1263 : {
1264 0 : }
1265 :
1266 0 : sal_Bool ExcEScenario::Append( sal_uInt16 nCol, sal_uInt16 nRow, const String& rTxt )
1267 : {
1268 0 : if( aCells.size() == EXC_SCEN_MAXCELL )
1269 0 : return false;
1270 :
1271 0 : ExcEScenarioCell aCell(nCol, nRow, rTxt);
1272 0 : aCells.push_back(aCell);
1273 0 : nRecLen += 6 + aCell.GetStringBytes(); // 4 bytes address, 2 bytes ifmt
1274 0 : return sal_True;
1275 : }
1276 :
1277 0 : void ExcEScenario::SaveCont( XclExpStream& rStrm )
1278 : {
1279 0 : sal_uInt16 count = aCells.size();
1280 :
1281 0 : rStrm << (sal_uInt16) count // number of cells
1282 0 : << nProtected // fProtection
1283 0 : << (sal_uInt8) 0 // fHidden
1284 0 : << (sal_uInt8) sName.Len() // length of scen name
1285 0 : << (sal_uInt8) sComment.Len() // length of comment
1286 0 : << (sal_uInt8) sUserName.Len(); // length of user name
1287 0 : sName.WriteFlagField( rStrm );
1288 0 : sName.WriteBuffer( rStrm );
1289 :
1290 0 : rStrm << sUserName;
1291 :
1292 0 : if( sComment.Len() )
1293 0 : rStrm << sComment;
1294 :
1295 0 : std::vector<ExcEScenarioCell>::iterator pIter;
1296 0 : for( pIter = aCells.begin(); pIter != aCells.end(); ++pIter )
1297 0 : pIter->WriteAddress( rStrm ); // pos of cell
1298 0 : for( pIter = aCells.begin(); pIter != aCells.end(); ++pIter )
1299 0 : pIter->WriteText( rStrm ); // string content
1300 0 : rStrm.SetSliceSize( 2 );
1301 0 : rStrm.WriteZeroBytes( 2 * count ); // date format
1302 0 : }
1303 :
1304 0 : sal_uInt16 ExcEScenario::GetNum() const
1305 : {
1306 0 : return 0x00AF;
1307 : }
1308 :
1309 0 : sal_Size ExcEScenario::GetLen() const
1310 : {
1311 0 : return nRecLen;
1312 : }
1313 :
1314 0 : void ExcEScenario::SaveXml( XclExpXmlStream& rStrm )
1315 : {
1316 0 : sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
1317 : rWorkbook->startElement( XML_scenario,
1318 : XML_name, XclXmlUtils::ToOString( sName ).getStr(),
1319 : XML_locked, XclXmlUtils::ToPsz( nProtected ),
1320 : // OOXTODO: XML_hidden,
1321 0 : XML_count, OString::valueOf( (sal_Int32) aCells.size() ).getStr(),
1322 0 : XML_user, XESTRING_TO_PSZ( sUserName ),
1323 0 : XML_comment, XESTRING_TO_PSZ( sComment ),
1324 0 : FSEND );
1325 :
1326 0 : std::vector<ExcEScenarioCell>::iterator pIter;
1327 0 : for( pIter = aCells.begin(); pIter != aCells.end(); ++pIter )
1328 0 : pIter->SaveXml( rStrm );
1329 :
1330 0 : rWorkbook->endElement( XML_scenario );
1331 0 : }
1332 :
1333 :
1334 :
1335 :
1336 1 : ExcEScenarioManager::ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab ) :
1337 1 : nActive( 0 )
1338 : {
1339 1 : ScDocument& rDoc = rRoot.GetDoc();
1340 1 : if( rDoc.IsScenario( nTab ) )
1341 1 : return;
1342 :
1343 1 : SCTAB nFirstTab = nTab + 1;
1344 1 : SCTAB nNewTab = nFirstTab;
1345 :
1346 2 : while( rDoc.IsScenario( nNewTab ) )
1347 : {
1348 0 : aScenes.push_back( new ExcEScenario( rRoot, nNewTab ) );
1349 :
1350 0 : if( rDoc.IsActiveScenario( nNewTab ) )
1351 0 : nActive = static_cast<sal_uInt16>(nNewTab - nFirstTab);
1352 0 : nNewTab++;
1353 : }
1354 : }
1355 :
1356 3 : ExcEScenarioManager::~ExcEScenarioManager()
1357 : {
1358 1 : std::vector<ExcEScenario*>::iterator pIter;
1359 1 : for( pIter = aScenes.begin(); pIter != aScenes.end(); ++pIter )
1360 0 : delete *pIter;
1361 2 : }
1362 :
1363 0 : void ExcEScenarioManager::SaveCont( XclExpStream& rStrm )
1364 : {
1365 0 : rStrm << (sal_uInt16) aScenes.size() // number of scenarios
1366 0 : << nActive // active scen
1367 0 : << nActive // last displayed
1368 0 : << (sal_uInt16) 0; // reference areas
1369 0 : }
1370 :
1371 0 : void ExcEScenarioManager::Save( XclExpStream& rStrm )
1372 : {
1373 0 : if( !aScenes.empty() )
1374 0 : ExcRecord::Save( rStrm );
1375 :
1376 0 : std::vector<ExcEScenario*>::iterator pIter;
1377 0 : for( pIter = aScenes.begin(); pIter != aScenes.end(); ++pIter )
1378 0 : (*pIter)->Save( rStrm );
1379 0 : }
1380 :
1381 1 : void ExcEScenarioManager::SaveXml( XclExpXmlStream& rStrm )
1382 : {
1383 1 : if( aScenes.empty() )
1384 1 : return;
1385 :
1386 0 : sax_fastparser::FSHelperPtr& rWorkbook = rStrm.GetCurrentStream();
1387 : rWorkbook->startElement( XML_scenarios,
1388 : XML_current, OString::valueOf( (sal_Int32)nActive ).getStr(),
1389 : XML_show, OString::valueOf( (sal_Int32)nActive ).getStr(),
1390 : // OOXTODO: XML_sqref,
1391 0 : FSEND );
1392 :
1393 0 : std::vector<ExcEScenario*>::iterator pIter;
1394 0 : for( pIter = aScenes.begin(); pIter != aScenes.end(); ++pIter )
1395 0 : (*pIter)->SaveXml( rStrm );
1396 :
1397 0 : rWorkbook->endElement( XML_scenarios );
1398 : }
1399 :
1400 0 : sal_uInt16 ExcEScenarioManager::GetNum() const
1401 : {
1402 0 : return 0x00AE;
1403 : }
1404 :
1405 0 : sal_Size ExcEScenarioManager::GetLen() const
1406 : {
1407 0 : return 8;
1408 : }
1409 :
1410 : // ============================================================================
1411 :
1412 : struct XclExpTabProtectOption
1413 : {
1414 : ScTableProtection::Option eOption;
1415 : sal_uInt16 nMask;
1416 : };
1417 :
1418 0 : XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
1419 0 : XclExpRecord( 0x0867, 23 )
1420 : {
1421 : static const XclExpTabProtectOption aTable[] =
1422 : {
1423 : { ScTableProtection::OBJECTS, 0x0001 },
1424 : { ScTableProtection::SCENARIOS, 0x0002 },
1425 : { ScTableProtection::FORMAT_CELLS, 0x0004 },
1426 : { ScTableProtection::FORMAT_COLUMNS, 0x0008 },
1427 : { ScTableProtection::FORMAT_ROWS, 0x0010 },
1428 : { ScTableProtection::INSERT_COLUMNS, 0x0020 },
1429 : { ScTableProtection::INSERT_ROWS, 0x0040 },
1430 : { ScTableProtection::INSERT_HYPERLINKS, 0x0080 },
1431 :
1432 : { ScTableProtection::DELETE_COLUMNS, 0x0100 },
1433 : { ScTableProtection::DELETE_ROWS, 0x0200 },
1434 : { ScTableProtection::SELECT_LOCKED_CELLS, 0x0400 },
1435 : { ScTableProtection::SORT, 0x0800 },
1436 : { ScTableProtection::AUTOFILTER, 0x1000 },
1437 : { ScTableProtection::PIVOT_TABLES, 0x2000 },
1438 : { ScTableProtection::SELECT_UNLOCKED_CELLS, 0x4000 },
1439 :
1440 : { ScTableProtection::NONE, 0x0000 }
1441 : };
1442 :
1443 0 : mnOptions = 0x0000;
1444 0 : ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
1445 0 : if (!pProtect)
1446 0 : return;
1447 :
1448 0 : for (int i = 0; aTable[i].nMask != 0x0000; ++i)
1449 : {
1450 0 : if ( pProtect->isOptionEnabled(aTable[i].eOption) )
1451 0 : mnOptions |= aTable[i].nMask;
1452 : }
1453 : }
1454 :
1455 0 : void XclExpSheetProtectOptions::WriteBody( XclExpStream& rStrm )
1456 : {
1457 0 : sal_uInt16 nBytes = 0x0867;
1458 0 : rStrm << nBytes;
1459 :
1460 0 : sal_uChar nZero = 0x00;
1461 0 : for (int i = 0; i < 9; ++i)
1462 0 : rStrm << nZero;
1463 :
1464 0 : nBytes = 0x0200;
1465 0 : rStrm << nBytes;
1466 0 : nBytes = 0x0100;
1467 0 : rStrm << nBytes;
1468 0 : nBytes = 0xFFFF;
1469 0 : rStrm << nBytes << nBytes;
1470 :
1471 0 : rStrm << mnOptions;
1472 0 : nBytes = 0;
1473 0 : rStrm << nBytes;
1474 0 : }
1475 :
1476 : // ============================================================================
1477 :
1478 :
1479 :
1480 :
1481 0 : void XclCalccount::SaveCont( XclExpStream& rStrm )
1482 : {
1483 0 : rStrm << nCount;
1484 0 : }
1485 :
1486 :
1487 1 : XclCalccount::XclCalccount( const ScDocument& rDoc )
1488 : {
1489 1 : nCount = rDoc.GetDocOptions().GetIterCount();
1490 1 : }
1491 :
1492 :
1493 0 : sal_uInt16 XclCalccount::GetNum() const
1494 : {
1495 0 : return 0x000C;
1496 : }
1497 :
1498 :
1499 0 : sal_Size XclCalccount::GetLen() const
1500 : {
1501 0 : return 2;
1502 : }
1503 :
1504 :
1505 1 : void XclCalccount::SaveXml( XclExpXmlStream& rStrm )
1506 : {
1507 : rStrm.WriteAttributes(
1508 : XML_iterateCount, OString::valueOf( (sal_Int32)nCount ).getStr(),
1509 1 : FSEND );
1510 1 : }
1511 :
1512 :
1513 :
1514 :
1515 0 : void XclIteration::SaveCont( XclExpStream& rStrm )
1516 : {
1517 0 : rStrm << nIter;
1518 0 : }
1519 :
1520 :
1521 1 : XclIteration::XclIteration( const ScDocument& rDoc )
1522 : {
1523 1 : nIter = rDoc.GetDocOptions().IsIter()? 1 : 0;
1524 1 : }
1525 :
1526 :
1527 0 : sal_uInt16 XclIteration::GetNum() const
1528 : {
1529 0 : return 0x0011;
1530 : }
1531 :
1532 :
1533 0 : sal_Size XclIteration::GetLen() const
1534 : {
1535 0 : return 2;
1536 : }
1537 :
1538 :
1539 1 : void XclIteration::SaveXml( XclExpXmlStream& rStrm )
1540 : {
1541 : rStrm.WriteAttributes(
1542 : XML_iterate, XclXmlUtils::ToPsz( nIter == 1 ),
1543 1 : FSEND );
1544 1 : }
1545 :
1546 :
1547 :
1548 :
1549 0 : void XclDelta::SaveCont( XclExpStream& rStrm )
1550 : {
1551 0 : rStrm << fDelta;
1552 0 : }
1553 :
1554 :
1555 :
1556 1 : XclDelta::XclDelta( const ScDocument& rDoc )
1557 : {
1558 1 : fDelta = rDoc.GetDocOptions().GetIterEps();
1559 1 : }
1560 :
1561 :
1562 0 : sal_uInt16 XclDelta::GetNum() const
1563 : {
1564 0 : return 0x0010;
1565 : }
1566 :
1567 :
1568 0 : sal_Size XclDelta::GetLen() const
1569 : {
1570 0 : return 8;
1571 : }
1572 :
1573 :
1574 1 : void XclDelta::SaveXml( XclExpXmlStream& rStrm )
1575 : {
1576 : rStrm.WriteAttributes(
1577 : XML_iterateDelta, OString::valueOf( fDelta ).getStr(),
1578 1 : FSEND );
1579 1 : }
1580 :
1581 : // ============================================================================
1582 :
1583 0 : XclExpFileEncryption::XclExpFileEncryption( const XclExpRoot& rRoot ) :
1584 : XclExpRecord(0x002F, 54),
1585 0 : mrRoot(rRoot)
1586 : {
1587 0 : }
1588 :
1589 0 : XclExpFileEncryption::~XclExpFileEncryption()
1590 : {
1591 0 : }
1592 :
1593 0 : void XclExpFileEncryption::WriteBody( XclExpStream& rStrm )
1594 : {
1595 : // 0x0000 - neither standard nor strong encryption
1596 : // 0x0001 - standard or strong encryption
1597 0 : rStrm << static_cast<sal_uInt16>(0x0001);
1598 :
1599 : // 0x0000 - non standard encryption
1600 : // 0x0001 - standard encryption
1601 0 : sal_uInt16 nStdEnc = 0x0001;
1602 0 : rStrm << nStdEnc << nStdEnc;
1603 :
1604 : sal_uInt8 pnDocId[16];
1605 : sal_uInt8 pnSalt[16];
1606 : sal_uInt8 pnSaltHash[16];
1607 0 : XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot) );
1608 0 : xEnc->GetDocId(pnDocId);
1609 0 : xEnc->GetSalt(pnSalt);
1610 0 : xEnc->GetSaltDigest(pnSaltHash);
1611 :
1612 0 : rStrm.Write(pnDocId, 16);
1613 0 : rStrm.Write(pnSalt, 16);
1614 0 : rStrm.Write(pnSaltHash, 16);
1615 :
1616 0 : rStrm.SetEncrypter(xEnc);
1617 0 : }
1618 :
1619 : // ============================================================================
1620 :
1621 1 : XclExpInterfaceHdr::XclExpInterfaceHdr( sal_uInt16 nCodePage ) :
1622 1 : XclExpUInt16Record( EXC_ID_INTERFACEHDR, nCodePage )
1623 : {
1624 1 : }
1625 :
1626 0 : void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
1627 : {
1628 0 : rStrm.DisableEncryption();
1629 0 : rStrm << GetValue();
1630 0 : }
1631 :
1632 : // ============================================================================
1633 :
1634 1 : XclExpInterfaceEnd::XclExpInterfaceEnd() :
1635 1 : XclExpRecord(0x00E2, 0) {}
1636 :
1637 2 : XclExpInterfaceEnd::~XclExpInterfaceEnd() {}
1638 :
1639 0 : void XclExpInterfaceEnd::WriteBody( XclExpStream& rStrm )
1640 : {
1641 : // Don't forget to re-enable encryption.
1642 0 : rStrm.EnableEncryption();
1643 0 : }
1644 :
1645 : // ============================================================================
1646 :
1647 1 : XclExpWriteAccess::XclExpWriteAccess() :
1648 1 : XclExpRecord(0x005C, 112)
1649 : {
1650 1 : }
1651 :
1652 2 : XclExpWriteAccess::~XclExpWriteAccess()
1653 : {
1654 2 : }
1655 :
1656 0 : void XclExpWriteAccess::WriteBody( XclExpStream& rStrm )
1657 : {
1658 : static const sal_uInt8 aData[] = {
1659 : 0x04, 0x00, 0x00, 'C', 'a', 'l', 'c', 0x20,
1660 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1661 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1662 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1663 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1664 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1665 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1666 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1667 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1668 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1669 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1670 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1671 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1672 : 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 };
1673 :
1674 0 : sal_Size nDataSize = sizeof(aData);
1675 0 : for (sal_Size i = 0; i < nDataSize; ++i)
1676 0 : rStrm << aData[i];
1677 0 : }
1678 :
1679 : // ============================================================================
1680 :
1681 1 : XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly ) :
1682 : XclExpRecord( EXC_ID_FILESHARING ),
1683 : mnPasswordHash( nPasswordHash ),
1684 1 : mbRecommendReadOnly( bRecommendReadOnly )
1685 : {
1686 1 : if( rRoot.GetBiff() <= EXC_BIFF5 )
1687 0 : maUserName.AssignByte( rRoot.GetUserName(), rRoot.GetTextEncoding(), EXC_STR_8BITLENGTH );
1688 : else
1689 1 : maUserName.Assign( rRoot.GetUserName() );
1690 1 : }
1691 :
1692 0 : void XclExpFileSharing::Save( XclExpStream& rStrm )
1693 : {
1694 0 : if( (mnPasswordHash != 0) || mbRecommendReadOnly )
1695 0 : XclExpRecord::Save( rStrm );
1696 0 : }
1697 :
1698 0 : void XclExpFileSharing::WriteBody( XclExpStream& rStrm )
1699 : {
1700 0 : rStrm << sal_uInt16( mbRecommendReadOnly ? 1 : 0 ) << mnPasswordHash << maUserName;
1701 0 : }
1702 :
1703 : // ============================================================================
1704 :
1705 0 : XclExpProt4Rev::XclExpProt4Rev() :
1706 0 : XclExpRecord(0x01AF, 2)
1707 : {
1708 0 : }
1709 :
1710 0 : XclExpProt4Rev::~XclExpProt4Rev()
1711 : {
1712 0 : }
1713 :
1714 0 : void XclExpProt4Rev::WriteBody( XclExpStream& rStrm )
1715 : {
1716 0 : rStrm << static_cast<sal_uInt16>(0x0000);
1717 0 : }
1718 :
1719 : // ============================================================================
1720 :
1721 0 : XclExpProt4RevPass::XclExpProt4RevPass() :
1722 0 : XclExpRecord(0x01BC, 2)
1723 : {
1724 0 : }
1725 :
1726 0 : XclExpProt4RevPass::~XclExpProt4RevPass()
1727 : {
1728 0 : }
1729 :
1730 0 : void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm )
1731 : {
1732 0 : rStrm << static_cast<sal_uInt16>(0x0000);
1733 0 : }
1734 :
1735 : // ============================================================================
1736 :
1737 : static const sal_uInt8 nDataRecalcId[] = {
1738 : 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
1739 : };
1740 :
1741 1 : XclExpRecalcId::XclExpRecalcId() :
1742 1 : XclExpDummyRecord(0x01C1, nDataRecalcId, sizeof(nDataRecalcId))
1743 : {
1744 1 : }
1745 :
1746 : // ============================================================================
1747 :
1748 : static const sal_uInt8 nDataBookExt[] = {
1749 : 0x63, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1750 : 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1751 : 0x02
1752 : };
1753 :
1754 1 : XclExpBookExt::XclExpBookExt() :
1755 1 : XclExpDummyRecord(0x0863, nDataBookExt, sizeof(nDataBookExt))
1756 : {
1757 1 : }
1758 :
1759 : // ============================================================================
1760 :
1761 1 : XclRefmode::XclRefmode( const ScDocument& rDoc ) :
1762 1 : XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != formula::FormulaGrammar::CONV_XL_R1C1 )
1763 : {
1764 1 : }
1765 :
1766 1 : void XclRefmode::SaveXml( XclExpXmlStream& rStrm )
1767 : {
1768 : rStrm.WriteAttributes(
1769 1 : XML_refMode, GetBool() ? "A1" : "R1C1",
1770 1 : FSEND );
1771 10 : }
1772 :
1773 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|