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