1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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"
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>
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
;
94 sal_Int32
XclExpObjList::mnDrawingMLCount
;
95 sal_Int32
XclExpObjList::mnVmlCount
;
97 XclExpObjList::XclExpObjList( const XclExpRoot
& rRoot
, XclEscherEx
& rEscherEx
) :
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
);
128 pObj
->SetId( nSize
);
129 pObj
->SetTab( mnScTab
);
140 void XclExpObjList::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
);
170 static bool IsVmlObject( const XclObj
*rObj
)
172 switch( rObj
->GetObjType() )
174 case EXC_OBJTYPE_NOTE
:
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
) )
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
);
206 uno::Reference
<chart2::XDiagram
> xDiagram
= xChartDoc
->getFirstDiagram();
210 uno::Reference
<chart2::XCoordinateSystemContainer
> xCooSysContainer(xDiagram
, uno::UNO_QUERY
);
211 if (!xCooSysContainer
.is())
214 uno::Sequence
<uno::Reference
<chart2::XCoordinateSystem
> > xCooSysSeq
= xCooSysContainer
->getCoordinateSystems();
215 if (!xCooSysSeq
.getLength())
218 for (sal_Int32 nCooSys
= 0; nCooSys
< xCooSysSeq
.getLength(); ++nCooSys
)
220 Reference
<chart2::XChartTypeContainer
> xChartTypeCont(xCooSysSeq
[nCooSys
], uno::UNO_QUERY
);
221 if (!xChartTypeCont
.is())
224 uno::Sequence
<uno::Reference
<chart2::XChartType
> > xChartTypeSeq
= xChartTypeCont
->getChartTypes();
225 if (!xChartTypeSeq
.getLength())
226 // No chart type. Not good.
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
))
244 aList
.push_back(*it
);
250 sal_Int32 nDrawing
= ++nDrawingMLCount
;
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",
260 rStrm
.GetCurrentStream()->singleElement( XML_drawing
,
261 FSNS( XML_r
, XML_id
), XclXmlUtils::ToOString( sId
).getStr(),
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",
271 for (it
= aList
.begin(), itEnd
= aList
.end(); it
!= itEnd
; ++it
)
272 (*it
)->SaveXml(rStrm
);
274 pDrawing
->endElement( FSNS( XML_xdr
, XML_wsDr
) );
279 static void SaveVmlObjects( XclExpObjList
& rList
, XclExpXmlStream
& rStrm
, sal_Int32
& nVmlCount
)
281 if( GetVmlObjectCount( rList
) == 0 )
284 sal_Int32 nDrawing
= ++nVmlCount
;
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",
294 rStrm
.GetCurrentStream()->singleElement( XML_legacyDrawing
,
295 FSNS( XML_r
, XML_id
), XclXmlUtils::ToOString( sId
).getStr(),
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",
306 std::vector
<XclObj
*>::iterator pIter
;
307 for ( pIter
= rList
.begin(); pIter
!= rList
.end(); ++pIter
)
309 if( !IsVmlObject( *pIter
) )
311 (*pIter
)->SaveXml( rStrm
);
314 pVmlDrawing
->endElement( XML_xml
);
321 void XclExpObjList::SaveXml( XclExpXmlStream
& rStrm
)
323 if( pSolverContainer
)
324 pSolverContainer
->SaveXml( rStrm
);
329 SaveDrawingMLObjects( *this, rStrm
, mnDrawingMLCount
);
330 SaveVmlObjects( *this, rStrm
, mnVmlCount
);
333 void XclExpObjList::ResetCounters()
335 mnDrawingMLCount
= 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
),
346 mnObjType( nObjType
),
348 nGrbit( 0x6011 ), // AutoLine, AutoFill, Printable, Locked
350 bFirstOnSheet( !rObjMgr
.HasObj() ),
351 mbOwnEscher( bOwnEscher
)
353 //! first object continues the first MSODRAWING record
355 pMsodrawing
= rObjMgr
.GetMsodrawingPerSheet();
357 pMsodrawing
= new XclExpMsoDrawing( mrEscherEx
);
362 if ( !bFirstOnSheet
)
364 delete pClientTextbox
;
368 void XclObj::ImplWriteAnchor( const XclExpRoot
& /*rRoot*/, const SdrObject
* pSdrObj
, const Rectangle
* pChildAnchor
)
372 mrEscherEx
.AddChildAnchor( *pChildAnchor
);
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?
386 case ESCHER_ShpInst_Line
:
387 mnObjType
= EXC_OBJTYPE_LINE
;
389 case ESCHER_ShpInst_Rectangle
:
390 case ESCHER_ShpInst_RoundRectangle
:
391 mnObjType
= EXC_OBJTYPE_RECTANGLE
;
393 case ESCHER_ShpInst_Ellipse
:
394 mnObjType
= EXC_OBJTYPE_OVAL
;
396 case ESCHER_ShpInst_Arc
:
397 mnObjType
= EXC_OBJTYPE_ARC
;
399 case ESCHER_ShpInst_TextBox
:
400 mnObjType
= EXC_OBJTYPE_TEXT
;
402 case ESCHER_ShpInst_PictureFrame
:
403 mnObjType
= EXC_OBJTYPE_PICTURE
;
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
447 rStrm
.CopyFromStream( aMemStrm
);
450 void XclObj::Save( XclExpStream
& rStrm
)
452 // MSODRAWING record (msofbtSpContainer)
453 if ( !bFirstOnSheet
)
454 pMsodrawing
->Save( rStrm
);
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
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
)
487 ProcessEscherObj( rObjMgr
.GetRoot(), rRect
, pCaption
, bVisible
);
489 pTxo
= new XclTxo( rObjMgr
.GetRoot(), rEditObj
, pCaption
);
492 static void lcl_FillProps( EscherPropertyContainer
& rPropOpt
, SdrObject
* pCaption
, bool bVisible
)
496 Reference
< XShape
> aXShape
= GetXShapeForSdrObject( pCaption
);
497 Reference
< XPropertySet
> aXPropSet( aXShape
, UNO_QUERY
);
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 );
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
578 SdrCaptionObj
* mpCaption
;
584 VmlCommentExporter ( sax_fastparser::FSHelperPtr p
, ScAddress aScPos
, SdrCaptionObj
* pCaption
, bool bVisible
, Rectangle
&aFrom
, Rectangle
&aTo
);
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
)
597 , mpCaption( pCaption
)
598 , mbVisible( bVisible
)
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();
634 void VmlCommentExporter::EndShape( sal_Int32 nShapeElement
)
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",
645 pVmlDrawing
->singleElement( FSNS( XML_x
, XML_MoveWithCells
),
647 pVmlDrawing
->singleElement( FSNS( XML_x
, XML_SizeWithCells
),
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 ),
671 SetPrintable( false );
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 );
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 );
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;
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;
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
) );
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
;
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
)
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());
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
);
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 );
862 sal_uInt16
XclTxo::GetNum() const
867 sal_Size
XclTxo::GetLen() const
872 // --- class XclObjOle -------------------------------------------
874 XclObjOle::XclObjOle( XclExpObjectManager
& rObjMgr
, const SdrObject
& rObj
) :
875 XclObj( rObjMgr
, EXC_OBJTYPE_PICTURE
),
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
);
898 uno::Reference
< embed::XEmbeddedObject
> xObj( static_cast<const SdrOle2Obj
&>(rOleObj
).GetObjRef() );
901 // set version to "old" version, because it must be
902 // saved in MS notation.
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);
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
);
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
);
940 << sal_uInt16( 5 ) << sal_uInt32( 0 ) << sal_uInt8( 2 )
941 << sal_uInt32( 0 ) << sal_uInt8( 3 )
944 rStrm
<< sal_uInt8( 0 ); // pad byte
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
)
965 XclObjAny::~XclObjAny()
969 void XclObjAny::WriteSubRecs( XclExpStream
& rStrm
)
971 if( mnObjType
== EXC_OBJTYPE_GROUP
)
973 rStrm
<< EXC_ID_OBJGMO
<< sal_uInt16(2) << sal_uInt16(0);
976 void XclObjAny::Save( XclExpStream
& rStrm
)
978 if( mnObjType
== EXC_OBJTYPE_GROUP
)
982 // content of this record
983 XclObj::Save( rStrm
);
986 // --- class ExcBof8_Base --------------------------------------------
988 ExcBof8_Base::ExcBof8_Base()
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,
1009 pDrawing
->startElement( FSNS( XML_xdr
, XML_from
),
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
),
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() );
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";
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" )
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 ),
1064 Reference
< XPropertySet
> xPropSet( mxShape
, UNO_QUERY
);
1067 WriteFromTo( rStrm
, *this );
1068 aDML
.WriteShape( mxShape
);
1071 pDrawing
->singleElement( FSNS( XML_xdr
, XML_clientData
),
1072 // OOXTODO: XML_fLocksWithSheet
1073 // OOXTODO: XML_fPrintsWithSheet
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
1090 sal_Size
ExcBof8_Base::GetLen() const
1095 // --- class ExcBof8 -------------------------------------------------
1102 // --- class ExcBofW8 ------------------------------------------------
1104 ExcBofW8::ExcBofW8()
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
)
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",
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(),
1157 // --- class XclObproj -----------------------------------------------
1159 sal_uInt16
XclObproj::GetNum() const
1164 sal_Size
XclObproj::GetLen() const
1169 // ---- class XclCodename --------------------------------------------
1171 XclCodename::XclCodename( const OUString
& r
) : aName( r
)
1175 void XclCodename::SaveCont( XclExpStream
& rStrm
)
1180 sal_uInt16
XclCodename::GetNum() const
1185 sal_Size
XclCodename::GetLen() const
1187 return aName
.GetSize();
1190 // ---- Scenarios ----------------------------------------------------
1192 ExcEScenarioCell::ExcEScenarioCell( sal_uInt16 nC
, sal_uInt16 nR
, const OUString
& rTxt
) :
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
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(),
1220 ExcEScenario::ExcEScenario( const XclExpRoot
& rRoot
, SCTAB nTab
)
1228 ScDocument
& rDoc
= rRoot
.GetDoc();
1229 rDoc
.GetName(nTab
, aTmp
);
1231 sName
.Assign( sTmpName
, EXC_STR_8BITLENGTH
);
1232 nRecLen
= 8 + sName
.GetBufferSize();
1234 rDoc
.GetScenarioData( nTab
, aTmp
, aDummyCol
, nFlags
);
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
);
1248 bool bContLoop
= true;
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],
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
)
1286 ExcEScenarioCell
aCell(nCol
, nRow
, rTxt
);
1287 aCells
.push_back(aCell
);
1288 nRecLen
+= 6 + aCell
.GetStringBytes(); // 4 bytes address, 2 bytes ifmt
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
);
1307 if( sComment
.Len() )
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
1324 sal_Size
ExcEScenario::GetLen() const
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
),
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
) :
1351 ScDocument
& rDoc
= rRoot
.GetDoc();
1352 if( rDoc
.IsScenario( nTab
) )
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
);
1368 ExcEScenarioManager::~ExcEScenarioManager()
1370 std::vector
<ExcEScenario
*>::iterator pIter
;
1371 for( pIter
= aScenes
.begin(); pIter
!= aScenes
.end(); ++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() )
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,
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
1417 sal_Size
ExcEScenarioManager::GetLen() const
1422 struct XclExpTabProtectOption
1424 ScTableProtection::Option eOption
;
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 }
1454 ScTableProtection
* pProtect
= rRoot
.GetDoc().GetTabProtection(nTab
);
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;
1470 unsigned char nZero
= 0x00;
1471 for (int i
= 0; i
< 9; ++i
)
1479 rStrm
<< nBytes
<< nBytes
;
1486 XclExpSheetEnhancedProtection::XclExpSheetEnhancedProtection( const XclExpRoot
& rRoot
,
1487 const ScEnhancedProtection
& rProt
) :
1488 XclExpRecord( 0x0868 ),
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)
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");
1523 rStrm
.Write( &maEnhancedProtection
.maSecurityDescriptor
.front(), nCbSD
);
1527 void XclCalccount::SaveCont( XclExpStream
& rStrm
)
1532 XclCalccount::XclCalccount( const ScDocument
& rDoc
)
1534 nCount
= rDoc
.GetDocOptions().GetIterCount();
1537 sal_uInt16
XclCalccount::GetNum() const
1542 sal_Size
XclCalccount::GetLen() const
1547 void XclCalccount::SaveXml( XclExpXmlStream
& rStrm
)
1549 rStrm
.WriteAttributes(
1550 XML_iterateCount
, OString::number( nCount
).getStr(),
1554 void XclIteration::SaveCont( XclExpStream
& rStrm
)
1559 XclIteration::XclIteration( const ScDocument
& rDoc
)
1561 nIter
= rDoc
.GetDocOptions().IsIter()? 1 : 0;
1564 sal_uInt16
XclIteration::GetNum() const
1569 sal_Size
XclIteration::GetLen() const
1574 void XclIteration::SaveXml( XclExpXmlStream
& rStrm
)
1576 rStrm
.WriteAttributes(
1577 XML_iterate
, XclXmlUtils::ToPsz( nIter
== 1 ),
1581 void XclDelta::SaveCont( XclExpStream
& rStrm
)
1586 XclDelta::XclDelta( const ScDocument
& rDoc
)
1588 fDelta
= rDoc
.GetDocOptions().GetIterEps();
1591 sal_uInt16
XclDelta::GetNum() const
1596 sal_Size
XclDelta::GetLen() const
1601 void XclDelta::SaveXml( XclExpXmlStream
& rStrm
)
1603 rStrm
.WriteAttributes(
1604 XML_iterateDelta
, OString::number( fDelta
).getStr(),
1608 XclExpFileEncryption::XclExpFileEncryption( const XclExpRoot
& rRoot
) :
1609 XclExpRecord(0x002F, 54),
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
)
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
);
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,
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",
1780 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */