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