fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / sc / source / filter / xcl97 / xcl97rec.cxx
blobae8b93b67cc20e6721646331842beec3e3874ecf
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
34 #include <rtl/math.hxx>
35 #include <svl/zformat.hxx>
36 #include "formulacell.hxx"
37 #include "drwlayer.hxx"
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"
47 #include "scitems.hxx"
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>
57 #include <unotools/localedatawrapper.hxx>
59 #include <stdio.h>
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"
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>
81 #include <boost/checked_delete.hpp>
82 #include <boost/scoped_ptr.hpp>
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;
94 sal_Int32 XclExpObjList::mnDrawingMLCount;
95 sal_Int32 XclExpObjList::mnVmlCount;
97 XclExpObjList::XclExpObjList( const XclExpRoot& rRoot, XclEscherEx& rEscherEx ) :
98 XclExpRoot( rRoot ),
99 mnScTab( rRoot.GetCurrScTab() ),
100 mrEscherEx( rEscherEx ),
101 pSolverContainer( 0 )
103 pMsodrawingPerSheet = new XclExpMsoDrawing( rEscherEx );
104 // open the DGCONTAINER and the patriarch group shape
105 mrEscherEx.OpenContainer( ESCHER_DgContainer );
106 Rectangle aRect( 0, 0, 0, 0 );
107 mrEscherEx.EnterGroup( &aRect );
108 mrEscherEx.UpdateDffFragmentEnd();
111 XclExpObjList::~XclExpObjList()
113 std::for_each(maObjs.begin(), maObjs.end(), boost::checked_deleter<XclObj>());
114 delete pMsodrawingPerSheet;
115 delete pSolverContainer;
118 sal_uInt16 XclExpObjList::Add( XclObj* pObj )
120 OSL_ENSURE( maObjs.size() < 0xFFFF, "XclExpObjList::Add: too much for Xcl" );
122 size_t nSize = maObjs.size();
124 if ( nSize < 0xFFFF )
126 maObjs.push_back(pObj);
127 ++nSize;
128 pObj->SetId( nSize );
129 pObj->SetTab( mnScTab );
131 else
133 delete pObj;
134 nSize = 0;
137 return nSize;
140 void XclExpObjList::pop_back ()
142 maObjs.pop_back();
145 void XclExpObjList::EndSheet()
147 // Is there still something in the stream? -> The solver container
148 if( mrEscherEx.HasPendingDffData() )
149 pSolverContainer = new XclExpMsoDrawing( mrEscherEx );
151 // close the DGCONTAINER created by XclExpObjList ctor MSODRAWING
152 mrEscherEx.CloseContainer();
155 void XclExpObjList::Save( XclExpStream& rStrm )
157 //! Escher must be written, even if there are no objects
158 pMsodrawingPerSheet->Save( rStrm );
160 std::vector<XclObj*>::iterator pIter;
161 for ( pIter = maObjs.begin(); pIter != maObjs.end(); ++pIter )
162 (*pIter)->Save( rStrm );
164 if( pSolverContainer )
165 pSolverContainer->Save( rStrm );
168 namespace {
170 static bool IsVmlObject( const XclObj *rObj )
172 switch( rObj->GetObjType() )
174 case EXC_OBJTYPE_NOTE:
175 return true;
176 default:
177 return false;
181 static sal_Int32 GetVmlObjectCount( XclExpObjList& rList )
183 sal_Int32 nNumVml = 0;
185 std::vector<XclObj*>::iterator pIter;
186 for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
187 if( IsVmlObject( *pIter ) )
188 ++nNumVml;
190 return nNumVml;
193 bool IsValidObject( const XclObj& rObj )
195 if (rObj.GetObjType() == EXC_OBJTYPE_CHART)
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.
201 const XclExpChartObj& rChartObj = static_cast<const XclExpChartObj&>(rObj);
202 uno::Reference<chart2::XChartDocument> xChartDoc(rChartObj.GetChartDoc(), uno::UNO_QUERY);
203 if (!xChartDoc.is())
204 return false;
206 uno::Reference<chart2::XDiagram> xDiagram = xChartDoc->getFirstDiagram();
207 if (!xDiagram.is())
208 return false;
210 uno::Reference<chart2::XCoordinateSystemContainer> xCooSysContainer(xDiagram, uno::UNO_QUERY);
211 if (!xCooSysContainer.is())
212 return false;
214 uno::Sequence<uno::Reference<chart2::XCoordinateSystem> > xCooSysSeq = xCooSysContainer->getCoordinateSystems();
215 if (!xCooSysSeq.getLength())
216 return false;
218 for (sal_Int32 nCooSys = 0; nCooSys < xCooSysSeq.getLength(); ++nCooSys)
220 Reference<chart2::XChartTypeContainer> xChartTypeCont(xCooSysSeq[nCooSys], uno::UNO_QUERY);
221 if (!xChartTypeCont.is())
222 return false;
224 uno::Sequence<uno::Reference<chart2::XChartType> > xChartTypeSeq = xChartTypeCont->getChartTypes();
225 if (!xChartTypeSeq.getLength())
226 // No chart type. Not good.
227 return false;
231 return true;
234 static void SaveDrawingMLObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nDrawingMLCount )
236 std::vector<XclObj*> aList;
237 aList.reserve(rList.size());
238 std::vector<XclObj*>::iterator it = rList.begin(), itEnd = rList.end();
239 for (; it != itEnd; ++it)
241 if (IsVmlObject(*it) || !IsValidObject(**it))
242 continue;
244 aList.push_back(*it);
247 if (aList.empty())
248 return;
250 sal_Int32 nDrawing = ++nDrawingMLCount;
251 OUString sId;
252 sax_fastparser::FSHelperPtr pDrawing = rStrm.CreateOutputStream(
253 XclXmlUtils::GetStreamName( "xl/", "drawings/drawing", nDrawing ),
254 XclXmlUtils::GetStreamName( "../", "drawings/drawing", nDrawing ),
255 rStrm.GetCurrentStream()->getOutputStream(),
256 "application/vnd.openxmlformats-officedocument.drawing+xml",
257 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
258 &sId );
260 rStrm.GetCurrentStream()->singleElement( XML_drawing,
261 FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
262 FSEND );
264 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 FSEND );
271 for (it = aList.begin(), itEnd = aList.end(); it != itEnd; ++it)
272 (*it)->SaveXml(rStrm);
274 pDrawing->endElement( FSNS( XML_xdr, XML_wsDr ) );
276 rStrm.PopStream();
279 static void SaveVmlObjects( XclExpObjList& rList, XclExpXmlStream& rStrm, sal_Int32& nVmlCount )
281 if( GetVmlObjectCount( rList ) == 0 )
282 return;
284 sal_Int32 nDrawing = ++nVmlCount;
285 OUString sId;
286 sax_fastparser::FSHelperPtr pVmlDrawing = rStrm.CreateOutputStream(
287 XclXmlUtils::GetStreamName( "xl/", "drawings/vmlDrawing", nDrawing ),
288 XclXmlUtils::GetStreamName( "../", "drawings/vmlDrawing", nDrawing ),
289 rStrm.GetCurrentStream()->getOutputStream(),
290 "application/vnd.openxmlformats-officedocument.vmlDrawing",
291 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
292 &sId );
294 rStrm.GetCurrentStream()->singleElement( XML_legacyDrawing,
295 FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
296 FSEND );
298 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 FSEND );
306 std::vector<XclObj*>::iterator pIter;
307 for ( pIter = rList.begin(); pIter != rList.end(); ++pIter )
309 if( !IsVmlObject( *pIter ) )
310 continue;
311 (*pIter)->SaveXml( rStrm );
314 pVmlDrawing->endElement( XML_xml );
316 rStrm.PopStream();
321 void XclExpObjList::SaveXml( XclExpXmlStream& rStrm )
323 if( pSolverContainer )
324 pSolverContainer->SaveXml( rStrm );
326 if( maObjs.empty())
327 return;
329 SaveDrawingMLObjects( *this, rStrm, mnDrawingMLCount );
330 SaveVmlObjects( *this, rStrm, mnVmlCount );
333 void XclExpObjList::ResetCounters()
335 mnDrawingMLCount = 0;
336 mnVmlCount = 0;
339 // --- class XclObj --------------------------------------------------
341 XclObj::XclObj( XclExpObjectManager& rObjMgr, sal_uInt16 nObjType, bool bOwnEscher ) :
342 XclExpRecord( EXC_ID_OBJ, 26 ),
343 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 bFirstOnSheet( !rObjMgr.HasObj() ),
351 mbOwnEscher( bOwnEscher )
353 //! first object continues the first MSODRAWING record
354 if ( bFirstOnSheet )
355 pMsodrawing = rObjMgr.GetMsodrawingPerSheet();
356 else
357 pMsodrawing = new XclExpMsoDrawing( mrEscherEx );
360 XclObj::~XclObj()
362 if ( !bFirstOnSheet )
363 delete pMsodrawing;
364 delete pClientTextbox;
365 delete pTxo;
368 void XclObj::ImplWriteAnchor( const XclExpRoot& /*rRoot*/, const SdrObject* pSdrObj, const Rectangle* pChildAnchor )
370 if( pChildAnchor )
372 mrEscherEx.AddChildAnchor( *pChildAnchor );
374 else if( pSdrObj )
376 boost::scoped_ptr< XclExpDffAnchorBase > xDffAnchor( mrEscherEx.CreateDffAnchor( *pSdrObj ) );
377 xDffAnchor->WriteDffData( mrEscherEx );
381 void XclObj::SetEscherShapeType( sal_uInt16 nType )
383 //2do: what about the other defined ot... types?
384 switch ( nType )
386 case ESCHER_ShpInst_Line :
387 mnObjType = EXC_OBJTYPE_LINE;
388 break;
389 case ESCHER_ShpInst_Rectangle :
390 case ESCHER_ShpInst_RoundRectangle :
391 mnObjType = EXC_OBJTYPE_RECTANGLE;
392 break;
393 case ESCHER_ShpInst_Ellipse :
394 mnObjType = EXC_OBJTYPE_OVAL;
395 break;
396 case ESCHER_ShpInst_Arc :
397 mnObjType = EXC_OBJTYPE_ARC;
398 break;
399 case ESCHER_ShpInst_TextBox :
400 mnObjType = EXC_OBJTYPE_TEXT;
401 break;
402 case ESCHER_ShpInst_PictureFrame :
403 mnObjType = EXC_OBJTYPE_PICTURE;
404 break;
405 default:
406 mnObjType = EXC_OBJTYPE_DRAWING;
410 void XclObj::SetText( const XclExpRoot& rRoot, const SdrTextObj& rObj )
412 OSL_ENSURE( !pClientTextbox, "XclObj::SetText: already set" );
413 if ( !pClientTextbox )
415 mrEscherEx.UpdateDffFragmentEnd();
416 pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
417 mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
418 mrEscherEx.UpdateDffFragmentEnd();
419 pTxo = new XclTxo( rRoot, rObj );
423 void XclObj::WriteBody( XclExpStream& rStrm )
425 OSL_ENSURE( mnObjType != EXC_OBJTYPE_UNKNOWN, "XclObj::WriteBody - unknown type" );
427 // create a substream to be able to create subrecords
428 SvMemoryStream aMemStrm;
429 boost::scoped_ptr< XclExpStream > pXclStrm( new XclExpStream( aMemStrm, rStrm.GetRoot() ) );
431 // write the ftCmo subrecord
432 pXclStrm->StartRecord( EXC_ID_OBJCMO, 18 );
433 *pXclStrm << mnObjType << nObjId << nGrbit;
434 pXclStrm->WriteZeroBytes( 12 );
435 pXclStrm->EndRecord();
437 // write other subrecords
438 WriteSubRecs( *pXclStrm );
440 // write the ftEnd subrecord
441 pXclStrm->StartRecord( EXC_ID_OBJEND, 0 );
442 pXclStrm->EndRecord();
444 // copy the data to the OBJ record
445 pXclStrm.reset();
446 aMemStrm.Seek( 0 );
447 rStrm.CopyFromStream( aMemStrm );
450 void XclObj::Save( XclExpStream& rStrm )
452 // MSODRAWING record (msofbtSpContainer)
453 if ( !bFirstOnSheet )
454 pMsodrawing->Save( rStrm );
456 // OBJ
457 XclExpRecord::Save( rStrm );
459 // second MSODRAWING record and TXO and CONTINUE records
460 SaveTextRecs( rStrm );
463 void XclObj::WriteSubRecs( XclExpStream& /*rStrm*/ )
467 void XclObj::SaveTextRecs( XclExpStream& rStrm )
469 // MSODRAWING record (msofbtClientTextbox)
470 if ( pClientTextbox )
471 pClientTextbox->Save( rStrm );
472 // TXO and CONTINUE records
473 if ( pTxo )
474 pTxo->Save( rStrm );
477 // --- class XclObjComment ------------------------------------------
479 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 , mpCaption( static_cast< SdrCaptionObj* >( pCaption->Clone() ) )
483 , mbVisible( bVisible )
484 , maFrom ( rFrom )
485 , maTo ( rTo )
487 ProcessEscherObj( rObjMgr.GetRoot(), rRect, pCaption, bVisible);
488 // TXO
489 pTxo = new XclTxo( rObjMgr.GetRoot(), rEditObj, pCaption );
492 static void lcl_FillProps( EscherPropertyContainer& rPropOpt, SdrObject* pCaption, bool bVisible )
494 if( pCaption )
496 Reference< XShape > aXShape = GetXShapeForSdrObject( pCaption );
497 Reference< XPropertySet > aXPropSet( aXShape, UNO_QUERY );
498 if( aXPropSet.is() )
500 rPropOpt.CreateFillProperties( aXPropSet, true);
502 rPropOpt.AddOpt( ESCHER_Prop_lTxid, 0 ); // undocumented
503 rPropOpt.AddOpt( 0x0158, 0x00000000 ); // undocumented
505 sal_uInt32 nValue = 0;
506 if( !rPropOpt.GetOpt( ESCHER_Prop_FitTextToShape, nValue ) )
507 rPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
509 if( rPropOpt.GetOpt( ESCHER_Prop_fillColor, nValue ) )
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 Color aColor = Color( (sal_uInt8)nValue, (sal_uInt8)( nValue >> 8 ), (sal_uInt8)( nValue >> 16 ) );
515 const StyleSettings& rSett = Application::GetSettings().GetStyleSettings();
516 if( aColor == rSett.GetHelpColor().GetColor() )
518 rPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
519 rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
522 else
523 rPropOpt.AddOpt( ESCHER_Prop_fillColor, 0x08000050 );
525 if( !rPropOpt.GetOpt( ESCHER_Prop_fillBackColor, nValue ) )
526 rPropOpt.AddOpt( ESCHER_Prop_fillBackColor, 0x08000050 );
527 if( !rPropOpt.GetOpt( ESCHER_Prop_fNoFillHitTest, nValue ) )
528 rPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00110010 ); // bool field
529 if( !rPropOpt.GetOpt( ESCHER_Prop_shadowColor, nValue ) )
530 rPropOpt.AddOpt( ESCHER_Prop_shadowColor, 0x00000000 );
531 if( !rPropOpt.GetOpt( ESCHER_Prop_fshadowObscured, nValue ) ) // bool field
532 rPropOpt.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // bool field
536 sal_uInt32 nFlags = 0x000A0000;
537 ::set_flag( nFlags, sal_uInt32(2), !bVisible );
538 rPropOpt.AddOpt( ESCHER_Prop_fPrint, nFlags ); // bool field
541 void XclObjComment::ProcessEscherObj( const XclExpRoot& rRoot, const Rectangle& rRect, SdrObject* pCaption, const bool bVisible )
543 EscherPropertyContainer aPropOpt;
545 lcl_FillProps( aPropOpt, pCaption, bVisible );
547 nGrbit = 0; // all off: AutoLine, AutoFill, Printable, Locked
548 mrEscherEx.OpenContainer( ESCHER_SpContainer );
549 mrEscherEx.AddShape( ESCHER_ShpInst_TextBox, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
550 aPropOpt.Commit( mrEscherEx.GetStream() );
552 XclExpDffNoteAnchor( rRoot, rRect ).WriteDffData( mrEscherEx );
554 mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
555 mrEscherEx.UpdateDffFragmentEnd();
557 //! Be sure to construct the MSODRAWING ClientTextbox record _after_ the
558 //! base OBJ's MSODRAWING record Escher data is completed.
559 pClientTextbox = new XclExpMsoDrawing( mrEscherEx );
560 mrEscherEx.AddAtom( 0, ESCHER_ClientTextbox ); // TXO record
561 mrEscherEx.UpdateDffFragmentEnd();
562 mrEscherEx.CloseContainer(); // ESCHER_SpContainer
565 XclObjComment::~XclObjComment()
569 void XclObjComment::Save( XclExpStream& rStrm )
571 // content of this record
572 XclObj::Save( rStrm );
575 class VmlCommentExporter : public VMLExport
577 ScAddress maScPos;
578 SdrCaptionObj* mpCaption;
579 bool mbVisible;
580 Rectangle maFrom;
581 Rectangle maTo;
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;
593 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 , maTo ( aTo )
604 void VmlCommentExporter::Commit( EscherPropertyContainer& rProps, const Rectangle& rRect )
606 lcl_FillProps( rProps, mpCaption, mbVisible );
607 rProps.AddOpt( ESCHER_Prop_fHidden, sal_uInt32(mbVisible) ); // bool field
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 rProps.AddOpt( ESCHER_Prop_fshadowObscured, 0x00030003 ); // force value for comments
622 VMLExport::Commit( rProps, rRect );
625 sal_Int32 VmlCommentExporter::StartShape()
627 AddShapeAttribute( XML_type, OString( "#_x0000_t202") );
629 sal_Int32 nId = VMLExport::StartShape();
631 return nId;
634 void VmlCommentExporter::EndShape( sal_Int32 nShapeElement )
636 char pAnchor[100];
637 sax_fastparser::FSHelperPtr pVmlDrawing = GetFS();
638 snprintf( pAnchor, 100, "%ld, %ld, %ld, %ld, %ld, %ld, %ld, %ld",
639 maFrom.Left(), maFrom.Top(), maFrom.Right(), maFrom.Bottom(),
640 maTo.Left(), maTo.Top(), maTo.Right(), maTo.Bottom() );
642 pVmlDrawing->startElement( FSNS( XML_x, XML_ClientData ),
643 XML_ObjectType, "Note",
644 FSEND );
645 pVmlDrawing->singleElement( FSNS( XML_x, XML_MoveWithCells ),
646 FSEND );
647 pVmlDrawing->singleElement( FSNS( XML_x, XML_SizeWithCells ),
648 FSEND );
649 XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Anchor ), pAnchor );
650 XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_AutoFill ), "False" );
651 XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Row ), maScPos.Row() );
652 XclXmlUtils::WriteElement( pVmlDrawing, FSNS( XML_x, XML_Column ), sal_Int32( maScPos.Col() ) );
653 pVmlDrawing->endElement( FSNS( XML_x, XML_ClientData ) );
655 VMLExport::EndShape( nShapeElement );
658 void XclObjComment::SaveXml( XclExpXmlStream& rStrm )
660 VmlCommentExporter aCommentExporter( rStrm.GetCurrentStream(), maScPos, mpCaption.get(), mbVisible, maFrom, maTo );
661 aCommentExporter.AddSdrObject( *mpCaption );
664 // --- class XclObjDropDown ------------------------------------------
666 XclObjDropDown::XclObjDropDown( XclExpObjectManager& rObjMgr, const ScAddress& rPos, bool bFilt ) :
667 XclObj( rObjMgr, EXC_OBJTYPE_DROPDOWN, true ),
668 bIsFiltered( bFilt )
670 SetLocked( true );
671 SetPrintable( false );
672 SetAutoFill( true );
673 SetAutoLine( false );
674 nGrbit |= 0x0100; // undocumented
675 mrEscherEx.OpenContainer( ESCHER_SpContainer );
676 mrEscherEx.AddShape( ESCHER_ShpInst_HostControl, SHAPEFLAG_HAVEANCHOR | SHAPEFLAG_HAVESPT );
677 EscherPropertyContainer aPropOpt;
678 aPropOpt.AddOpt( ESCHER_Prop_LockAgainstGrouping, 0x01040104 ); // bool field
679 aPropOpt.AddOpt( ESCHER_Prop_FitTextToShape, 0x00080008 ); // bool field
680 aPropOpt.AddOpt( ESCHER_Prop_fNoFillHitTest, 0x00010000 ); // bool field
681 aPropOpt.AddOpt( ESCHER_Prop_fNoLineDrawDash, 0x00080000 ); // bool field
682 aPropOpt.AddOpt( ESCHER_Prop_fPrint, 0x000A0000 ); // bool field
683 aPropOpt.Commit( mrEscherEx.GetStream() );
685 XclExpDffDropDownAnchor( rObjMgr.GetRoot(), rPos ).WriteDffData( mrEscherEx );
687 mrEscherEx.AddAtom( 0, ESCHER_ClientData ); // OBJ record
688 mrEscherEx.UpdateDffFragmentEnd();
689 mrEscherEx.CloseContainer(); // ESCHER_SpContainer
691 // old size + ftSbs + ftLbsData
692 AddRecSize( 24 + 20 );
695 XclObjDropDown::~XclObjDropDown()
699 void XclObjDropDown::WriteSubRecs( XclExpStream& rStrm )
701 // ftSbs subrecord - Scroll bars (dummy)
702 rStrm.StartRecord( EXC_ID_OBJSBS, 20 );
703 rStrm.WriteZeroBytes( 20 );
704 rStrm.EndRecord();
706 // ftLbsData subrecord - Listbox data
707 sal_uInt16 nDropDownFlags = 0;
708 ::insert_value( nDropDownFlags, EXC_OBJ_DROPDOWN_SIMPLE, 0, 2 );
709 ::set_flag( nDropDownFlags, EXC_OBJ_DROPDOWN_FILTERED, bIsFiltered );
710 rStrm.StartRecord( EXC_ID_OBJLBSDATA, 16 );
711 rStrm << (sal_uInt32)0 << (sal_uInt16)0 << (sal_uInt16)0x0301 << (sal_uInt16)0
712 << nDropDownFlags << sal_uInt16( 20 ) << sal_uInt16( 130 );
713 rStrm.EndRecord();
716 // --- class XclTxo --------------------------------------------------
718 static sal_uInt8 lcl_GetHorAlignFromItemSet( const SfxItemSet& rItemSet )
720 sal_uInt8 nHorAlign = EXC_OBJ_HOR_LEFT;
722 switch( static_cast< const SvxAdjustItem& >( rItemSet.Get( EE_PARA_JUST ) ).GetAdjust() )
724 case SVX_ADJUST_LEFT: nHorAlign = EXC_OBJ_HOR_LEFT; break;
725 case SVX_ADJUST_CENTER: nHorAlign = EXC_OBJ_HOR_CENTER; break;
726 case SVX_ADJUST_RIGHT: nHorAlign = EXC_OBJ_HOR_RIGHT; break;
727 case SVX_ADJUST_BLOCK: nHorAlign = EXC_OBJ_HOR_JUSTIFY; break;
728 default:;
730 return nHorAlign;
733 static sal_uInt8 lcl_GetVerAlignFromItemSet( const SfxItemSet& rItemSet )
735 sal_uInt8 nVerAlign = EXC_OBJ_VER_TOP;
737 switch( static_cast< const SdrTextVertAdjustItem& >( rItemSet.Get( SDRATTR_TEXT_VERTADJUST ) ).GetValue() )
739 case SDRTEXTVERTADJUST_TOP: nVerAlign = EXC_OBJ_VER_TOP; break;
740 case SDRTEXTVERTADJUST_CENTER: nVerAlign = EXC_OBJ_VER_CENTER; break;
741 case SDRTEXTVERTADJUST_BOTTOM: nVerAlign = EXC_OBJ_VER_BOTTOM; break;
742 case SDRTEXTVERTADJUST_BLOCK: nVerAlign = EXC_OBJ_VER_JUSTIFY; break;
744 return nVerAlign;
747 XclTxo::XclTxo( const OUString& rString, sal_uInt16 nFontIx ) :
748 mpString( new XclExpString( rString ) ),
749 mnRotation( EXC_OBJ_ORIENT_NONE ),
750 mnHorAlign( EXC_OBJ_HOR_LEFT ),
751 mnVerAlign( EXC_OBJ_VER_TOP )
753 if( mpString->Len() )
755 // If there is text, Excel *needs* the 2nd CONTINUE record with at least two format runs
756 mpString->AppendFormat( 0, nFontIx );
757 mpString->AppendFormat( mpString->Len(), EXC_FONT_APP );
761 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 mnVerAlign( EXC_OBJ_VER_TOP )
767 // additional alignment and orientation items
768 const SfxItemSet& rItemSet = rTextObj.GetMergedItemSet();
770 // horizontal alignment
771 SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
773 // vertical alignment
774 SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
776 // rotation
777 long nAngle = rTextObj.GetRotateAngle();
778 if( (4500 < nAngle) && (nAngle < 13500) )
779 mnRotation = EXC_OBJ_ORIENT_90CCW;
780 else if( (22500 < nAngle) && (nAngle < 31500) )
781 mnRotation = EXC_OBJ_ORIENT_90CW;
782 else
783 mnRotation = EXC_OBJ_ORIENT_NONE;
786 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 mnVerAlign( EXC_OBJ_VER_TOP )
792 if(pCaption)
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 OUString aParaText( rEditObj.GetText( 0 ) );
798 if( !aParaText.isEmpty() )
800 SfxItemSet aSet( rEditObj.GetParaAttribs( 0));
801 const SfxPoolItem* pItem = NULL;
802 if( aSet.GetItemState( EE_PARA_JUST, true, &pItem ) == SfxItemState::SET )
804 SvxAdjust eEEAlign = static_cast< const SvxAdjustItem& >( *pItem ).GetAdjust();
805 pCaption->SetMergedItem( SvxAdjustItem( eEEAlign, EE_PARA_JUST ) );
808 const SfxItemSet& rItemSet = pCaption->GetMergedItemSet();
810 // horizontal alignment
811 SetHorAlign( lcl_GetHorAlignFromItemSet( rItemSet ) );
813 // vertical alignment
814 SetVerAlign( lcl_GetVerAlignFromItemSet( rItemSet ) );
816 // orientation alignment
817 const SvxWritingModeItem& rItem = static_cast< const SvxWritingModeItem& >( rItemSet.Get( SDRATTR_TEXTDIRECTION ) );
818 if( rItem.GetValue() == com::sun::star::text::WritingMode_TB_RL )
819 mnRotation = EXC_OBJ_ORIENT_90CW;
823 void XclTxo::SaveCont( XclExpStream& rStrm )
825 OSL_ENSURE( mpString.get(), "XclTxo::SaveCont - missing string" );
827 // #i96858# do not save existing string formatting if text is empty
828 sal_uInt16 nRunLen = mpString->IsEmpty() ? 0 : (8 * mpString->GetFormatsCount());
829 // alignment
830 sal_uInt16 nFlags = 0;
831 ::insert_value( nFlags, mnHorAlign, 1, 3 );
832 ::insert_value( nFlags, mnVerAlign, 4, 3 );
834 rStrm << nFlags << mnRotation;
835 rStrm.WriteZeroBytes( 6 );
836 rStrm << mpString->Len() << nRunLen << sal_uInt32( 0 );
839 void XclTxo::Save( XclExpStream& rStrm )
841 // Write the TXO part
842 ExcRecord::Save( rStrm );
844 // CONTINUE records are only written if there is some text
845 if( !mpString->IsEmpty() )
847 // CONTINUE for character array
848 rStrm.StartRecord( EXC_ID_CONT, mpString->GetBufferSize() + 1 );
849 rStrm << static_cast< sal_uInt8 >( mpString->GetFlagField() & EXC_STRF_16BIT ); // only Unicode flag
850 mpString->WriteBuffer( rStrm );
851 rStrm.EndRecord();
853 // CONTINUE for formatting runs
854 rStrm.StartRecord( EXC_ID_CONT, 8 * mpString->GetFormatsCount() );
855 const XclFormatRunVec& rFormats = mpString->GetFormats();
856 for( XclFormatRunVec::const_iterator aIt = rFormats.begin(), aEnd = rFormats.end(); aIt != aEnd; ++aIt )
857 rStrm << aIt->mnChar << aIt->mnFontIdx << sal_uInt32( 0 );
858 rStrm.EndRecord();
862 sal_uInt16 XclTxo::GetNum() const
864 return EXC_ID_TXO;
867 sal_Size XclTxo::GetLen() const
869 return 18;
872 // --- class XclObjOle -------------------------------------------
874 XclObjOle::XclObjOle( XclExpObjectManager& rObjMgr, const SdrObject& rObj ) :
875 XclObj( rObjMgr, EXC_OBJTYPE_PICTURE ),
876 rOleObj( rObj ),
877 pRootStorage( rObjMgr.GetRoot().GetRootStorage() )
881 XclObjOle::~XclObjOle()
885 void XclObjOle::WriteSubRecs( XclExpStream& rStrm )
887 // write only as embedded, not linked
888 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 sal_uInt32 nPictureId = sal_uInt32(sal_uIntPtr(this) >> 2);
892 sprintf( aBuf, "%08X", static_cast< unsigned int >( nPictureId ) );
893 aStorageName += OUString::createFromAscii(aBuf);
894 tools::SvRef<SotStorage> xOleStg = pRootStorage->OpenSotStorage( aStorageName,
895 STREAM_READWRITE| StreamMode::SHARE_DENYALL );
896 if( xOleStg.Is() )
898 uno::Reference < embed::XEmbeddedObject > xObj( static_cast<const SdrOle2Obj&>(rOleObj).GetObjRef() );
899 if ( xObj.is() )
901 // set version to "old" version, because it must be
902 // saved in MS notation.
903 sal_uInt32 nFl = 0;
904 const SvtFilterOptions& rFltOpts = SvtFilterOptions::Get();
905 if( rFltOpts.IsMath2MathType() )
906 nFl |= OLE_STARMATH_2_MATHTYPE;
908 if( rFltOpts.IsWriter2WinWord() )
909 nFl |= OLE_STARWRITER_2_WINWORD;
911 if( rFltOpts.IsCalc2Excel() )
912 nFl |= OLE_STARCALC_2_EXCEL;
914 if( rFltOpts.IsImpress2PowerPoint() )
915 nFl |= OLE_STARIMPRESS_2_POWERPOINT;
917 SvxMSExportOLEObjects aOLEExpFilt( nFl );
918 aOLEExpFilt.ExportOLEObject( xObj, *xOleStg );
920 // OBJCF subrecord, undocumented as usual
921 rStrm.StartRecord( EXC_ID_OBJCF, 2 );
922 rStrm << sal_uInt16(0x0002);
923 rStrm.EndRecord();
925 // OBJFLAGS subrecord, undocumented as usual
926 rStrm.StartRecord( EXC_ID_OBJFLAGS, 2 );
927 sal_uInt16 nFlags = EXC_OBJ_PIC_MANUALSIZE;
928 ::set_flag( nFlags, EXC_OBJ_PIC_SYMBOL, static_cast<const SdrOle2Obj&>(rOleObj).GetAspect() == embed::Aspects::MSOLE_ICON );
929 rStrm << nFlags;
930 rStrm.EndRecord();
932 // OBJPICTFMLA subrecord, undocumented as usual
933 XclExpString aName( xOleStg->GetUserName() );
934 sal_uInt16 nPadLen = (sal_uInt16)(aName.GetSize() & 0x01);
935 sal_uInt16 nFmlaLen = static_cast< sal_uInt16 >( 12 + aName.GetSize() + nPadLen );
936 sal_uInt16 nSubRecLen = nFmlaLen + 6;
938 rStrm.StartRecord( EXC_ID_OBJPICTFMLA, nSubRecLen );
939 rStrm << nFmlaLen
940 << sal_uInt16( 5 ) << sal_uInt32( 0 ) << sal_uInt8( 2 )
941 << sal_uInt32( 0 ) << sal_uInt8( 3 )
942 << aName;
943 if( nPadLen )
944 rStrm << sal_uInt8( 0 ); // pad byte
945 rStrm << nPictureId;
946 rStrm.EndRecord();
951 void XclObjOle::Save( XclExpStream& rStrm )
953 // content of this record
954 XclObj::Save( rStrm );
957 // --- class XclObjAny -------------------------------------------
959 XclObjAny::XclObjAny( XclExpObjectManager& rObjMgr, const Reference< XShape >& rShape )
960 : XclObj( rObjMgr, EXC_OBJTYPE_UNKNOWN )
961 , mxShape( rShape )
965 XclObjAny::~XclObjAny()
969 void XclObjAny::WriteSubRecs( XclExpStream& rStrm )
971 if( mnObjType == EXC_OBJTYPE_GROUP )
972 // ftGmo subrecord
973 rStrm << EXC_ID_OBJGMO << sal_uInt16(2) << sal_uInt16(0);
976 void XclObjAny::Save( XclExpStream& rStrm )
978 if( mnObjType == EXC_OBJTYPE_GROUP )
979 // old size + ftGmo
980 AddRecSize( 6 );
982 // content of this record
983 XclObj::Save( rStrm );
986 // --- class ExcBof8_Base --------------------------------------------
988 ExcBof8_Base::ExcBof8_Base()
990 nVers = 0x0600;
991 nRupBuild = 0x0dbb;
992 nRupYear = 0x07cc;
993 // nFileHistory = 0x00000001; // last edited by Microsoft Excel for Windows
994 nFileHistory = 0x00000000;
995 nLowestBiffVer = 0x00000006; // Biff8
997 void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const Reference< XShape >& rShape, SCTAB nTab )
999 sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
1001 awt::Point aTopLeft = rShape->getPosition();
1002 awt::Size aSize = rShape->getSize();
1003 Rectangle aLocation( aTopLeft.X, aTopLeft.Y, aTopLeft.X + aSize.Width, aTopLeft.Y + aSize.Height );
1004 ScRange aRange = rStrm.GetRoot().GetDoc().GetRange( nTab, aLocation );
1005 Rectangle aRangeRect = rStrm.GetRoot().GetDoc().GetMMRect( aRange.aStart.Col(), aRange.aStart.Row(),
1006 aRange.aEnd.Col()-1, aRange.aEnd.Row()-1,
1007 nTab );
1009 pDrawing->startElement( FSNS( XML_xdr, XML_from ),
1010 FSEND );
1011 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_col ), (sal_Int32) aRange.aStart.Col() );
1012 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_colOff ),
1013 oox::drawingml::convertHmmToEmu( aLocation.Left() - aRangeRect.Left() ) );
1014 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_row ), (sal_Int32) aRange.aStart.Row() );
1015 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_rowOff ),
1016 oox::drawingml::convertHmmToEmu( aLocation.Top() - aRangeRect.Top() ) );
1017 pDrawing->endElement( FSNS( XML_xdr, XML_from ) );
1019 pDrawing->startElement( FSNS( XML_xdr, XML_to ),
1020 FSEND );
1021 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_col ), (sal_Int32) aRange.aEnd.Col() );
1022 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_colOff ),
1023 oox::drawingml::convertHmmToEmu( aLocation.Right() - aRangeRect.Right() ) );
1024 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_row ), (sal_Int32) aRange.aEnd.Row() );
1025 XclXmlUtils::WriteElement( pDrawing, FSNS( XML_xdr, XML_rowOff ),
1026 oox::drawingml::convertHmmToEmu( aLocation.Bottom() - aRangeRect.Bottom() ) );
1027 pDrawing->endElement( FSNS( XML_xdr, XML_to ) );
1030 void XclObjAny::WriteFromTo( XclExpXmlStream& rStrm, const XclObjAny& rObj )
1032 WriteFromTo( rStrm, rObj.GetShape(), rObj.GetTab() );
1035 static const char*
1036 GetEditAs( XclObjAny& rObj )
1038 if( const SdrObject* pShape = EscherEx::GetSdrObject( rObj.GetShape() ) )
1040 // OOXTODO: returning "twoCell"
1041 switch( ScDrawLayer::GetAnchorType( *pShape ) )
1043 case SCA_CELL: return "oneCell";
1044 default: break;
1047 return "absolute";
1050 void XclObjAny::SaveXml( XclExpXmlStream& rStrm )
1052 // ignore group shapes at the moment, we don't process them correctly
1053 // leading to ms2010 rejecting the content
1054 if( !mxShape.is() || mxShape->getShapeType() == "com.sun.star.drawing.GroupShape" )
1055 return;
1057 sax_fastparser::FSHelperPtr pDrawing = rStrm.GetCurrentStream();
1059 ShapeExport aDML( XML_xdr, pDrawing, NULL, &rStrm, DrawingML::DOCUMENT_XLSX );
1061 pDrawing->startElement( FSNS( XML_xdr, XML_twoCellAnchor ), // OOXTODO: oneCellAnchor, absoluteAnchor
1062 XML_editAs, GetEditAs( *this ),
1063 FSEND );
1064 Reference< XPropertySet > xPropSet( mxShape, UNO_QUERY );
1065 if (xPropSet.is())
1067 WriteFromTo( rStrm, *this );
1068 aDML.WriteShape( mxShape );
1071 pDrawing->singleElement( FSNS( XML_xdr, XML_clientData),
1072 // OOXTODO: XML_fLocksWithSheet
1073 // OOXTODO: XML_fPrintsWithSheet
1074 FSEND );
1075 pDrawing->endElement( FSNS( XML_xdr, XML_twoCellAnchor ) );
1078 void ExcBof8_Base::SaveCont( XclExpStream& rStrm )
1080 rStrm.DisableEncryption();
1081 rStrm << nVers << nDocType << nRupBuild << nRupYear
1082 << nFileHistory << nLowestBiffVer;
1085 sal_uInt16 ExcBof8_Base::GetNum() const
1087 return 0x0809;
1090 sal_Size ExcBof8_Base::GetLen() const
1092 return 16;
1095 // --- class ExcBof8 -------------------------------------------------
1097 ExcBof8::ExcBof8()
1099 nDocType = 0x0010;
1102 // --- class ExcBofW8 ------------------------------------------------
1104 ExcBofW8::ExcBofW8()
1106 nDocType = 0x0005;
1109 // --- class ExcBundlesheet8 -----------------------------------------
1111 ExcBundlesheet8::ExcBundlesheet8( RootData& rRootData, SCTAB _nTab ) :
1112 ExcBundlesheetBase( rRootData, static_cast<sal_uInt16>(_nTab) ),
1113 sUnicodeName( rRootData.pER->GetTabInfo().GetScTabName( _nTab ) )
1117 ExcBundlesheet8::ExcBundlesheet8( const OUString& rString ) :
1118 ExcBundlesheetBase(),
1119 sUnicodeName( rString )
1123 void ExcBundlesheet8::SaveCont( XclExpStream& rStrm )
1125 m_nOwnPos = rStrm.GetSvStreamPos();
1126 // write dummy position, real position comes later
1127 rStrm.DisableEncryption();
1128 rStrm << sal_uInt32(0);
1129 rStrm.EnableEncryption();
1130 rStrm << nGrbit << GetName();
1133 sal_Size ExcBundlesheet8::GetLen() const
1134 { // Text max 255 chars
1135 return 8 + GetName().GetBufferSize();
1138 void ExcBundlesheet8::SaveXml( XclExpXmlStream& rStrm )
1140 OUString sId;
1141 rStrm.CreateOutputStream(
1142 XclXmlUtils::GetStreamName( "xl/", "worksheets/sheet", nTab+1),
1143 XclXmlUtils::GetStreamName( NULL, "worksheets/sheet", nTab+1),
1144 rStrm.GetCurrentStream()->getOutputStream(),
1145 "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
1146 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet",
1147 &sId );
1149 rStrm.GetCurrentStream()->singleElement( XML_sheet,
1150 XML_name, XclXmlUtils::ToOString( sUnicodeName ).getStr(),
1151 XML_sheetId, OString::number( ( nTab+1 ) ).getStr(),
1152 XML_state, nGrbit == 0x0000 ? "visible" : "hidden",
1153 FSNS( XML_r, XML_id ), XclXmlUtils::ToOString( sId ).getStr(),
1154 FSEND );
1157 // --- class XclObproj -----------------------------------------------
1159 sal_uInt16 XclObproj::GetNum() const
1161 return 0x00D3;
1164 sal_Size XclObproj::GetLen() const
1166 return 0;
1169 // ---- class XclCodename --------------------------------------------
1171 XclCodename::XclCodename( const OUString& r ) : aName( r )
1175 void XclCodename::SaveCont( XclExpStream& rStrm )
1177 rStrm << aName;
1180 sal_uInt16 XclCodename::GetNum() const
1182 return 0x01BA;
1185 sal_Size XclCodename::GetLen() const
1187 return aName.GetSize();
1190 // ---- Scenarios ----------------------------------------------------
1192 ExcEScenarioCell::ExcEScenarioCell( sal_uInt16 nC, sal_uInt16 nR, const OUString& rTxt ) :
1193 nCol( nC ),
1194 nRow( nR ),
1195 sText( rTxt, EXC_STR_DEFAULT, 255 )
1199 void ExcEScenarioCell::WriteAddress( XclExpStream& rStrm ) const
1201 rStrm << nRow << nCol;
1204 void ExcEScenarioCell::WriteText( XclExpStream& rStrm ) const
1206 rStrm << sText;
1209 void ExcEScenarioCell::SaveXml( XclExpXmlStream& rStrm ) const
1211 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 FSEND );
1220 ExcEScenario::ExcEScenario( const XclExpRoot& rRoot, SCTAB nTab )
1222 OUString sTmpName;
1223 OUString sTmpComm;
1224 OUString aTmp;
1225 Color aDummyCol;
1226 sal_uInt16 nFlags;
1228 ScDocument& rDoc = rRoot.GetDoc();
1229 rDoc.GetName(nTab, aTmp);
1230 sTmpName = aTmp;
1231 sName.Assign( sTmpName, EXC_STR_8BITLENGTH );
1232 nRecLen = 8 + sName.GetBufferSize();
1234 rDoc.GetScenarioData( nTab, aTmp, aDummyCol, nFlags );
1235 sTmpComm = aTmp;
1236 sComment.Assign( sTmpComm, EXC_STR_DEFAULT, 255 );
1237 if( sComment.Len() )
1238 nRecLen += sComment.GetSize();
1239 nProtected = (nFlags & SC_SCENARIO_PROTECT);
1241 sUserName.Assign( rRoot.GetUserName(), EXC_STR_DEFAULT, 255 );
1242 nRecLen += sUserName.GetSize();
1244 const ScRangeList* pRList = rDoc.GetScenarioRanges( nTab );
1245 if( !pRList )
1246 return;
1248 bool bContLoop = true;
1249 SCROW nRow;
1250 SCCOL nCol;
1251 OUString sText;
1252 double fVal;
1254 for( size_t nRange = 0; (nRange < pRList->size()) && bContLoop; nRange++ )
1256 const ScRange* pRange = (*pRList)[nRange];
1257 for( nRow = pRange->aStart.Row(); (nRow <= pRange->aEnd.Row()) && bContLoop; nRow++ )
1258 for( nCol = pRange->aStart.Col(); (nCol <= pRange->aEnd.Col()) && bContLoop; nCol++ )
1260 if( rDoc.HasValueData( nCol, nRow, nTab ) )
1262 rDoc.GetValue( nCol, nRow, nTab, fVal );
1263 sText = ::rtl::math::doubleToUString( fVal,
1264 rtl_math_StringFormat_Automatic,
1265 rtl_math_DecimalPlaces_Max,
1266 ScGlobal::pLocaleData->getNumDecimalSep()[0],
1267 true );
1269 else
1270 sText = rDoc.GetString(nCol, nRow, nTab);
1271 bContLoop = Append( static_cast<sal_uInt16>(nCol),
1272 static_cast<sal_uInt16>(nRow), sText );
1277 ExcEScenario::~ExcEScenario()
1281 bool ExcEScenario::Append( sal_uInt16 nCol, sal_uInt16 nRow, const OUString& rTxt )
1283 if( aCells.size() == EXC_SCEN_MAXCELL )
1284 return false;
1286 ExcEScenarioCell aCell(nCol, nRow, rTxt);
1287 aCells.push_back(aCell);
1288 nRecLen += 6 + aCell.GetStringBytes(); // 4 bytes address, 2 bytes ifmt
1289 return true;
1292 void ExcEScenario::SaveCont( XclExpStream& rStrm )
1294 sal_uInt16 count = aCells.size();
1296 rStrm << (sal_uInt16) count // number of cells
1297 << sal_uInt8(nProtected) // fProtection
1298 << (sal_uInt8) 0 // fHidden
1299 << (sal_uInt8) sName.Len() // length of scen name
1300 << (sal_uInt8) sComment.Len() // length of comment
1301 << (sal_uInt8) sUserName.Len(); // length of user name
1302 sName.WriteFlagField( rStrm );
1303 sName.WriteBuffer( rStrm );
1305 rStrm << sUserName;
1307 if( sComment.Len() )
1308 rStrm << sComment;
1310 std::vector<ExcEScenarioCell>::iterator pIter;
1311 for( pIter = aCells.begin(); pIter != aCells.end(); ++pIter )
1312 pIter->WriteAddress( rStrm ); // pos of cell
1313 for( pIter = aCells.begin(); pIter != aCells.end(); ++pIter )
1314 pIter->WriteText( rStrm ); // string content
1315 rStrm.SetSliceSize( 2 );
1316 rStrm.WriteZeroBytes( 2 * count ); // date format
1319 sal_uInt16 ExcEScenario::GetNum() const
1321 return 0x00AF;
1324 sal_Size ExcEScenario::GetLen() const
1326 return nRecLen;
1329 void ExcEScenario::SaveXml( XclExpXmlStream& rStrm )
1331 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 XML_user, XESTRING_TO_PSZ( sUserName ),
1338 XML_comment, XESTRING_TO_PSZ( sComment ),
1339 FSEND );
1341 std::vector<ExcEScenarioCell>::iterator pIter;
1342 for( pIter = aCells.begin(); pIter != aCells.end(); ++pIter )
1343 pIter->SaveXml( rStrm );
1345 rWorkbook->endElement( XML_scenario );
1348 ExcEScenarioManager::ExcEScenarioManager( const XclExpRoot& rRoot, SCTAB nTab ) :
1349 nActive( 0 )
1351 ScDocument& rDoc = rRoot.GetDoc();
1352 if( rDoc.IsScenario( nTab ) )
1353 return;
1355 SCTAB nFirstTab = nTab + 1;
1356 SCTAB nNewTab = nFirstTab;
1358 while( rDoc.IsScenario( nNewTab ) )
1360 aScenes.push_back( new ExcEScenario( rRoot, nNewTab ) );
1362 if( rDoc.IsActiveScenario( nNewTab ) )
1363 nActive = static_cast<sal_uInt16>(nNewTab - nFirstTab);
1364 nNewTab++;
1368 ExcEScenarioManager::~ExcEScenarioManager()
1370 std::vector<ExcEScenario*>::iterator pIter;
1371 for( pIter = aScenes.begin(); pIter != aScenes.end(); ++pIter )
1372 delete *pIter;
1375 void ExcEScenarioManager::SaveCont( XclExpStream& rStrm )
1377 rStrm << (sal_uInt16) aScenes.size() // number of scenarios
1378 << nActive // active scen
1379 << nActive // last displayed
1380 << (sal_uInt16) 0; // reference areas
1383 void ExcEScenarioManager::Save( XclExpStream& rStrm )
1385 if( !aScenes.empty() )
1386 ExcRecord::Save( rStrm );
1388 std::vector<ExcEScenario*>::iterator pIter;
1389 for( pIter = aScenes.begin(); pIter != aScenes.end(); ++pIter )
1390 (*pIter)->Save( rStrm );
1393 void ExcEScenarioManager::SaveXml( XclExpXmlStream& rStrm )
1395 if( aScenes.empty() )
1396 return;
1398 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 FSEND );
1405 std::vector<ExcEScenario*>::iterator pIter;
1406 for( pIter = aScenes.begin(); pIter != aScenes.end(); ++pIter )
1407 (*pIter)->SaveXml( rStrm );
1409 rWorkbook->endElement( XML_scenarios );
1412 sal_uInt16 ExcEScenarioManager::GetNum() const
1414 return 0x00AE;
1417 sal_Size ExcEScenarioManager::GetLen() const
1419 return 8;
1422 struct XclExpTabProtectOption
1424 ScTableProtection::Option eOption;
1425 sal_uInt16 nMask;
1428 XclExpSheetProtectOptions::XclExpSheetProtectOptions( const XclExpRoot& rRoot, SCTAB nTab ) :
1429 XclExpRecord( 0x0867, 23 )
1431 static const XclExpTabProtectOption aTable[] =
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 },
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 },
1450 { ScTableProtection::NONE, 0x0000 }
1453 mnOptions = 0x0000;
1454 ScTableProtection* pProtect = rRoot.GetDoc().GetTabProtection(nTab);
1455 if (!pProtect)
1456 return;
1458 for (int i = 0; aTable[i].nMask != 0x0000; ++i)
1460 if ( pProtect->isOptionEnabled(aTable[i].eOption) )
1461 mnOptions |= aTable[i].nMask;
1465 void XclExpSheetProtectOptions::WriteBody( XclExpStream& rStrm )
1467 sal_uInt16 nBytes = 0x0867;
1468 rStrm << nBytes;
1470 unsigned char nZero = 0x00;
1471 for (int i = 0; i < 9; ++i)
1472 rStrm << nZero;
1474 nBytes = 0x0200;
1475 rStrm << nBytes;
1476 nBytes = 0x0100;
1477 rStrm << nBytes;
1478 nBytes = 0xFFFF;
1479 rStrm << nBytes << nBytes;
1481 rStrm << mnOptions;
1482 nBytes = 0;
1483 rStrm << nBytes;
1486 XclExpSheetEnhancedProtection::XclExpSheetEnhancedProtection( const XclExpRoot& rRoot,
1487 const ScEnhancedProtection & rProt ) :
1488 XclExpRecord( 0x0868 ),
1489 mrRoot( rRoot ),
1490 maEnhancedProtection( rProt )
1494 void XclExpSheetEnhancedProtection::WriteBody( XclExpStream& rStrm )
1496 sal_uInt16 nRecordType = 0x0868;
1497 rStrm << nRecordType; // frtHeader rt
1498 rStrm.WriteZeroBytesToRecord(10); // frtHeader unused
1499 rStrm << EXC_ISFPROTECTION; // isf
1500 rStrm.WriteZeroBytesToRecord(5); // reserved1 (1 bytes) and reserved2 (4 bytes)
1502 XclRangeList aRefs;
1503 if (maEnhancedProtection.maRangeList.Is())
1504 mrRoot.GetAddressConverter().ConvertRangeList( aRefs, *maEnhancedProtection.maRangeList, false);
1505 sal_uInt16 nCref = ulimit_cast<sal_uInt16>(aRefs.size());
1506 rStrm << nCref; // cref
1507 rStrm.WriteZeroBytesToRecord(6); // cbFeatData if EXC_ISFFEC2 (4 bytes) and reserved3 (2 bytes)
1508 aRefs.Write( rStrm, true, nCref); // refs
1510 // FeatProtection structure
1511 rStrm << maEnhancedProtection.mnAreserved; // 1 bit A and 31 bits reserved
1512 rStrm << maEnhancedProtection.mnPasswordVerifier; // wPassword
1513 rStrm << XclExpString( maEnhancedProtection.maTitle); // stTitle
1514 bool bSDContainer = ((maEnhancedProtection.mnAreserved & 0x00000001) == 0x00000001);
1515 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 if (bSDContainer)
1522 rStrm << nCbSD;
1523 rStrm.Write( &maEnhancedProtection.maSecurityDescriptor.front(), nCbSD);
1527 void XclCalccount::SaveCont( XclExpStream& rStrm )
1529 rStrm << nCount;
1532 XclCalccount::XclCalccount( const ScDocument& rDoc )
1534 nCount = rDoc.GetDocOptions().GetIterCount();
1537 sal_uInt16 XclCalccount::GetNum() const
1539 return 0x000C;
1542 sal_Size XclCalccount::GetLen() const
1544 return 2;
1547 void XclCalccount::SaveXml( XclExpXmlStream& rStrm )
1549 rStrm.WriteAttributes(
1550 XML_iterateCount, OString::number( nCount ).getStr(),
1551 FSEND );
1554 void XclIteration::SaveCont( XclExpStream& rStrm )
1556 rStrm << nIter;
1559 XclIteration::XclIteration( const ScDocument& rDoc )
1561 nIter = rDoc.GetDocOptions().IsIter()? 1 : 0;
1564 sal_uInt16 XclIteration::GetNum() const
1566 return 0x0011;
1569 sal_Size XclIteration::GetLen() const
1571 return 2;
1574 void XclIteration::SaveXml( XclExpXmlStream& rStrm )
1576 rStrm.WriteAttributes(
1577 XML_iterate, XclXmlUtils::ToPsz( nIter == 1 ),
1578 FSEND );
1581 void XclDelta::SaveCont( XclExpStream& rStrm )
1583 rStrm << fDelta;
1586 XclDelta::XclDelta( const ScDocument& rDoc )
1588 fDelta = rDoc.GetDocOptions().GetIterEps();
1591 sal_uInt16 XclDelta::GetNum() const
1593 return 0x0010;
1596 sal_Size XclDelta::GetLen() const
1598 return 8;
1601 void XclDelta::SaveXml( XclExpXmlStream& rStrm )
1603 rStrm.WriteAttributes(
1604 XML_iterateDelta, OString::number( fDelta ).getStr(),
1605 FSEND );
1608 XclExpFileEncryption::XclExpFileEncryption( const XclExpRoot& rRoot ) :
1609 XclExpRecord(0x002F, 54),
1610 mrRoot(rRoot)
1614 XclExpFileEncryption::~XclExpFileEncryption()
1618 void XclExpFileEncryption::WriteBody( XclExpStream& rStrm )
1620 // 0x0000 - neither standard nor strong encryption
1621 // 0x0001 - standard or strong encryption
1622 rStrm << static_cast<sal_uInt16>(0x0001);
1624 // 0x0000 - non standard encryption
1625 // 0x0001 - standard encryption
1626 sal_uInt16 nStdEnc = 0x0001;
1627 rStrm << nStdEnc << nStdEnc;
1629 sal_uInt8 pnDocId[16];
1630 sal_uInt8 pnSalt[16];
1631 sal_uInt8 pnSaltHash[16];
1632 XclExpEncrypterRef xEnc( new XclExpBiff8Encrypter(mrRoot) );
1633 xEnc->GetDocId(pnDocId);
1634 xEnc->GetSalt(pnSalt);
1635 xEnc->GetSaltDigest(pnSaltHash);
1637 rStrm.Write(pnDocId, 16);
1638 rStrm.Write(pnSalt, 16);
1639 rStrm.Write(pnSaltHash, 16);
1641 rStrm.SetEncrypter(xEnc);
1644 XclExpInterfaceHdr::XclExpInterfaceHdr( sal_uInt16 nCodePage ) :
1645 XclExpUInt16Record( EXC_ID_INTERFACEHDR, nCodePage )
1649 void XclExpInterfaceHdr::WriteBody( XclExpStream& rStrm )
1651 rStrm.DisableEncryption();
1652 rStrm << GetValue();
1655 XclExpInterfaceEnd::XclExpInterfaceEnd() :
1656 XclExpRecord(0x00E2, 0) {}
1658 XclExpInterfaceEnd::~XclExpInterfaceEnd() {}
1660 void XclExpInterfaceEnd::WriteBody( XclExpStream& rStrm )
1662 // Don't forget to re-enable encryption.
1663 rStrm.EnableEncryption();
1666 XclExpWriteAccess::XclExpWriteAccess() :
1667 XclExpRecord(0x005C, 112)
1671 XclExpWriteAccess::~XclExpWriteAccess()
1675 void XclExpWriteAccess::WriteBody( XclExpStream& rStrm )
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 };
1693 sal_Size nDataSize = sizeof(aData);
1694 for (sal_Size i = 0; i < nDataSize; ++i)
1695 rStrm << aData[i];
1698 XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly ) :
1699 XclExpRecord( EXC_ID_FILESHARING ),
1700 mnPasswordHash( nPasswordHash ),
1701 mbRecommendReadOnly( bRecommendReadOnly )
1703 if( rRoot.GetBiff() <= EXC_BIFF5 )
1704 maUserName.AssignByte( rRoot.GetUserName(), rRoot.GetTextEncoding(), EXC_STR_8BITLENGTH );
1705 else
1706 maUserName.Assign( rRoot.GetUserName() );
1709 void XclExpFileSharing::Save( XclExpStream& rStrm )
1711 if( (mnPasswordHash != 0) || mbRecommendReadOnly )
1712 XclExpRecord::Save( rStrm );
1715 void XclExpFileSharing::WriteBody( XclExpStream& rStrm )
1717 rStrm << sal_uInt16( mbRecommendReadOnly ? 1 : 0 ) << mnPasswordHash << maUserName;
1720 XclExpProt4Rev::XclExpProt4Rev() :
1721 XclExpRecord(0x01AF, 2)
1725 XclExpProt4Rev::~XclExpProt4Rev()
1729 void XclExpProt4Rev::WriteBody( XclExpStream& rStrm )
1731 rStrm << static_cast<sal_uInt16>(0x0000);
1734 XclExpProt4RevPass::XclExpProt4RevPass() :
1735 XclExpRecord(0x01BC, 2)
1739 XclExpProt4RevPass::~XclExpProt4RevPass()
1743 void XclExpProt4RevPass::WriteBody( XclExpStream& rStrm )
1745 rStrm << static_cast<sal_uInt16>(0x0000);
1748 static const sal_uInt8 nDataRecalcId[] = {
1749 0xC1, 0x01, 0x00, 0x00, 0x54, 0x8D, 0x01, 0x00
1752 XclExpRecalcId::XclExpRecalcId() :
1753 XclExpDummyRecord(0x01C1, nDataRecalcId, sizeof(nDataRecalcId))
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
1763 XclExpBookExt::XclExpBookExt() :
1764 XclExpDummyRecord(0x0863, nDataBookExt, sizeof(nDataBookExt))
1768 XclRefmode::XclRefmode( const ScDocument& rDoc ) :
1769 XclExpBoolRecord( 0x000F, rDoc.GetAddressConvention() != formula::FormulaGrammar::CONV_XL_R1C1 )
1773 void XclRefmode::SaveXml( XclExpXmlStream& rStrm )
1775 rStrm.WriteAttributes(
1776 XML_refMode, GetBool() ? "A1" : "R1C1",
1777 FSEND );
1780 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */