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