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 "xeescher.hxx"
22 #include <com/sun/star/lang/XServiceInfo.hpp>
23 #include <com/sun/star/frame/XModel.hpp>
24 #include <com/sun/star/form/FormComponentType.hpp>
25 #include <com/sun/star/awt/VisualEffect.hpp>
26 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
27 #include <com/sun/star/drawing/XShape.hpp>
28 #include <com/sun/star/form/binding/XBindableValue.hpp>
29 #include <com/sun/star/form/binding/XValueBinding.hpp>
30 #include <com/sun/star/form/binding/XListEntrySink.hpp>
31 #include <com/sun/star/form/binding/XListEntrySource.hpp>
32 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
33 #include <com/sun/star/chart2/XChartDocument.hpp>
34 #include <com/sun/star/awt/Point.hpp>
35 #include <com/sun/star/awt/Size.hpp>
36 #include <com/sun/star/container/XNamed.hpp>
39 #include <rtl/ustrbuf.h>
40 #include <vcl/bmpacc.hxx>
41 #include <svx/svdoole2.hxx>
42 #include <svx/svdocapt.hxx>
43 #include <editeng/outlobj.hxx>
44 #include <editeng/editobj.hxx>
45 #include <unotools/tempfile.hxx>
46 #include <unotools/ucbstreamhelper.hxx>
47 #include <svtools/embedhlp.hxx>
49 #include "editutil.hxx"
50 #include "unonames.hxx"
51 #include "convuno.hxx"
54 #include "fapihelper.hxx"
55 #include "xechart.hxx"
56 #include "xeformula.hxx"
59 #include "xestyle.hxx"
60 #include "userdat.hxx"
61 #include "drwlayer.hxx"
62 #include <svx/unoapi.hxx>
63 #include <svx/algitem.hxx>
64 #include "scitems.hxx"
65 #include <editeng/justifyitem.hxx>
66 #include <svx/sdtaitm.hxx>
68 #include "document.hxx"
69 #include <svx/svdattr.hxx>
70 #include <svx/sdr/properties/properties.hxx>
71 #include "detfunc.hxx"
72 #include <svx/xflclit.hxx>
73 #include <svx/xlnstwit.hxx>
74 #include <svx/xlnstit.hxx>
75 #include <svx/sxmspitm.hxx>
77 #include <oox/token/tokens.hxx>
78 #include <oox/export/drawingml.hxx>
79 #include <oox/export/chartexport.hxx>
80 #include <oox/export/utils.hxx>
83 using namespace com::sun::star
;
84 using ::com::sun::star::uno::UNO_QUERY
;
85 using ::com::sun::star::uno::Reference
;
86 using ::com::sun::star::uno::Sequence
;
87 using ::com::sun::star::lang::XServiceInfo
;
88 using ::com::sun::star::beans::XPropertySet
;
89 using ::com::sun::star::drawing::XShape
;
90 using ::com::sun::star::drawing::XShapes
;
91 using ::com::sun::star::frame::XModel
;
92 using ::com::sun::star::embed::XEmbeddedObject
;
93 using ::com::sun::star::awt::XControlModel
;
94 using ::com::sun::star::form::binding::XBindableValue
;
95 using ::com::sun::star::form::binding::XValueBinding
;
96 using ::com::sun::star::form::binding::XListEntrySink
;
97 using ::com::sun::star::form::binding::XListEntrySource
;
98 using ::com::sun::star::script::ScriptEventDescriptor
;
99 using ::com::sun::star::table::CellAddress
;
100 using ::com::sun::star::table::CellRangeAddress
;
101 using ::com::sun::star::chart2::XChartDocument
;
102 using ::com::sun::star::container::XNamed
;
103 using ::oox::drawingml::DrawingML
;
104 using ::oox::drawingml::ChartExport
;
107 #define HMM2XL(x) ((x)/26.5)+0.5
109 #if 1//def XLSX_OOXML_FUTURE
110 // these function are only used within that context
111 // Static Function Helpers
112 static const char *ToHorizAlign( SdrTextHorzAdjust eAdjust
)
116 case SDRTEXTHORZADJUST_CENTER
:
118 case SDRTEXTHORZADJUST_RIGHT
:
120 case SDRTEXTHORZADJUST_BLOCK
:
122 case SDRTEXTHORZADJUST_LEFT
:
128 static const char *ToVertAlign( SdrTextVertAdjust eAdjust
)
132 case SDRTEXTVERTADJUST_CENTER
:
134 case SDRTEXTVERTADJUST_BOTTOM
:
136 case SDRTEXTVERTADJUST_BLOCK
:
138 case SDRTEXTVERTADJUST_TOP
:
144 static void lcl_WriteAnchorVertex( sax_fastparser::FSHelperPtr rComments
, Rectangle
&aRect
)
146 rComments
->startElement( FSNS( XML_xdr
, XML_col
), FSEND
);
147 rComments
->writeEscaped( OUString::number( aRect
.Left() ) );
148 rComments
->endElement( FSNS( XML_xdr
, XML_col
) );
149 rComments
->startElement( FSNS( XML_xdr
, XML_colOff
), FSEND
);
150 rComments
->writeEscaped( OUString::number( aRect
.Top() ) );
151 rComments
->endElement( FSNS( XML_xdr
, XML_colOff
) );
152 rComments
->startElement( FSNS( XML_xdr
, XML_row
), FSEND
);
153 rComments
->writeEscaped( OUString::number( aRect
.Right() ) );
154 rComments
->endElement( FSNS( XML_xdr
, XML_row
) );
155 rComments
->startElement( FSNS( XML_xdr
, XML_rowOff
), FSEND
);
156 rComments
->writeEscaped( OUString::number( aRect
.Bottom() ) );
157 rComments
->endElement( FSNS( XML_xdr
, XML_rowOff
) );
161 static void lcl_GetFromTo( const XclExpRoot
& rRoot
, const Rectangle
&aRect
, sal_Int32 nTab
, Rectangle
&aFrom
, Rectangle
&aTo
)
164 sal_Int32 nCol
= 0, nRow
= 0;
165 sal_Int32 nColOff
= 0, nRowOff
= 0;
169 Rectangle r
= rRoot
.GetDocPtr()->GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
172 if( r
.Left() <= aRect
.Left() )
175 nColOff
= aRect
.Left() - r
.Left();
177 if( r
.Top() <= aRect
.Top() )
180 nRowOff
= aRect
.Top() - r
.Top();
182 if( r
.Left() > aRect
.Left() && r
.Top() > aRect
.Top() )
184 aFrom
= Rectangle( nCol
-1, static_cast<long>(HMM2XL( nColOff
)),
185 nRow
-1, static_cast<long>(HMM2XL( nRowOff
)) );
191 if( r
.Right() < aRect
.Right() )
193 if( r
.Bottom() < aRect
.Bottom() )
195 if( r
.Right() >= aRect
.Right() && r
.Bottom() >= aRect
.Bottom() )
197 aTo
= Rectangle( nCol
, static_cast<long>(HMM2XL( aRect
.Right() - r
.Left() )),
198 nRow
, static_cast<long>(HMM2XL( aRect
.Bottom() - r
.Top() )));
206 // Escher client anchor =======================================================
208 XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot
& rRoot
, sal_uInt16 nFlags
) :
214 void XclExpDffAnchorBase::SetFlags( const SdrObject
& rSdrObj
)
216 ImplSetFlags( rSdrObj
);
219 void XclExpDffAnchorBase::SetSdrObject( const SdrObject
& rSdrObj
)
221 ImplSetFlags( rSdrObj
);
222 ImplCalcAnchorRect( rSdrObj
.GetCurrentBoundRect(), MAP_100TH_MM
);
225 void XclExpDffAnchorBase::WriteDffData( EscherEx
& rEscherEx
) const
227 rEscherEx
.AddAtom( 18, ESCHER_ClientAnchor
);
228 rEscherEx
.GetStream().WriteUInt16( mnFlags
);
229 WriteXclObjAnchor( rEscherEx
.GetStream(), maAnchor
);
232 void XclExpDffAnchorBase::WriteData( EscherEx
& rEscherEx
, const Rectangle
& rRect
)
234 // the passed rectangle is in twips
235 ImplCalcAnchorRect( rRect
, MAP_TWIP
);
236 WriteDffData( rEscherEx
);
239 void XclExpDffAnchorBase::ImplSetFlags( const SdrObject
& )
241 OSL_FAIL( "XclExpDffAnchorBase::ImplSetFlags - not implemented" );
244 void XclExpDffAnchorBase::ImplCalcAnchorRect( const Rectangle
&, MapUnit
)
246 OSL_FAIL( "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" );
249 XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot
& rRoot
) :
250 XclExpDffAnchorBase( rRoot
),
251 mnScTab( rRoot
.GetCurrScTab() )
255 void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject
& rSdrObj
)
257 // set flags for cell/page anchoring
258 if ( ScDrawLayer::GetAnchorType( rSdrObj
) == SCA_CELL
)
261 mnFlags
= EXC_ESC_ANCHOR_LOCKED
;
264 void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle
& rRect
, MapUnit eMapUnit
)
266 maAnchor
.SetRect( GetRoot(), mnScTab
, rRect
, eMapUnit
);
269 XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot
& rRoot
,
270 const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
271 XclExpDffAnchorBase( rRoot
),
272 maPageSize( rPageSize
),
278 void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject
& /*rSdrObj*/ )
280 // TODO (unsupported feature): fixed size
283 void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle
& rRect
, MapUnit eMapUnit
)
285 maAnchor
.SetRect( maPageSize
, mnScaleX
, mnScaleY
, rRect
, eMapUnit
, true );
288 XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot
& rRoot
, const Rectangle
& rRect
) :
289 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_SIZELOCKED
)
291 maAnchor
.SetRect( rRoot
, rRoot
.GetCurrScTab(), rRect
, MAP_100TH_MM
);
294 XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
) :
295 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_POSLOCKED
)
297 GetAddressConverter().ConvertAddress( maAnchor
.maFirst
, rScPos
, true );
298 maAnchor
.maLast
.mnCol
= maAnchor
.maFirst
.mnCol
+ 1;
299 maAnchor
.maLast
.mnRow
= maAnchor
.maFirst
.mnRow
+ 1;
300 maAnchor
.mnLX
= maAnchor
.mnTY
= maAnchor
.mnRX
= maAnchor
.mnBY
= 0;
303 // MSODRAWING* records ========================================================
305 XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx
& rEscherEx
, sal_uInt16 nRecId
) :
306 XclExpRecord( nRecId
),
307 mrEscherEx( rEscherEx
),
308 mnFragmentKey( rEscherEx
.InitNextDffFragment() )
312 void XclExpMsoDrawingBase::WriteBody( XclExpStream
& rStrm
)
314 OSL_ENSURE( mrEscherEx
.GetStreamPos() == mrEscherEx
.GetDffFragmentPos( mnFragmentKey
),
315 "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" );
316 rStrm
.CopyFromStream( mrEscherEx
.GetStream(), mrEscherEx
.GetDffFragmentSize( mnFragmentKey
) );
319 XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx
& rEscherEx
) :
320 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWINGGROUP
)
322 SvStream
& rDffStrm
= mrEscherEx
.GetStream();
324 // write the DGGCONTAINER with some default settings
325 mrEscherEx
.OpenContainer( ESCHER_DggContainer
);
327 // TODO: stuff the OPT atom with our own document defaults?
328 static const sal_uInt8 spnDffOpt
[] = {
329 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
330 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
333 mrEscherEx
.AddAtom( sizeof( spnDffOpt
), ESCHER_OPT
, 3, 3 );
334 rDffStrm
.Write( spnDffOpt
, sizeof( spnDffOpt
) );
336 // SPLITMENUCOLORS contains colors in toolbar
337 static const sal_uInt8 spnDffSplitMenuColors
[] = {
338 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
339 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
341 mrEscherEx
.AddAtom( sizeof( spnDffSplitMenuColors
), ESCHER_SplitMenuColors
, 0, 4 );
342 rDffStrm
.Write( spnDffSplitMenuColors
, sizeof( spnDffSplitMenuColors
) );
344 // close the DGGCONTAINER
345 mrEscherEx
.CloseContainer();
346 mrEscherEx
.UpdateDffFragmentEnd();
349 XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx
& rEscherEx
) :
350 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWING
)
354 XclExpImgData::XclExpImgData( const Graphic
& rGraphic
, sal_uInt16 nRecId
) :
355 maGraphic( rGraphic
),
360 void XclExpImgData::Save( XclExpStream
& rStrm
)
362 Bitmap aBmp
= maGraphic
.GetBitmap();
363 if( aBmp
.GetBitCount() != 24 )
364 aBmp
.Convert( BMP_CONVERSION_24BIT
);
366 if( BitmapReadAccess
* pAccess
= aBmp
.AcquireReadAccess() )
368 sal_Int32 nWidth
= ::std::min
< sal_Int32
>( pAccess
->Width(), 0xFFFF );
369 sal_Int32 nHeight
= ::std::min
< sal_Int32
>( pAccess
->Height(), 0xFFFF );
370 if( (nWidth
> 0) && (nHeight
> 0) )
372 sal_uInt8 nPadding
= static_cast< sal_uInt8
>( nWidth
& 0x03 );
373 sal_uInt32 nTmpSize
= static_cast< sal_uInt32
>( (nWidth
* 3 + nPadding
) * nHeight
+ 12 );
375 rStrm
.StartRecord( mnRecId
, nTmpSize
+ 4 );
377 rStrm
<< EXC_IMGDATA_BMP
// BMP format
378 << EXC_IMGDATA_WIN
// Windows
379 << nTmpSize
// size after _this_ field
380 << sal_uInt32( 12 ) // BITMAPCOREHEADER size
381 << static_cast< sal_uInt16
>( nWidth
) // width
382 << static_cast< sal_uInt16
>( nHeight
) // height
383 << sal_uInt16( 1 ) // planes
384 << sal_uInt16( 24 ); // bits per pixel
386 for( sal_Int32 nY
= nHeight
- 1; nY
>= 0; --nY
)
388 for( sal_Int32 nX
= 0; nX
< nWidth
; ++nX
)
390 const BitmapColor
& rBmpColor
= pAccess
->GetPixel( nY
, nX
);
391 rStrm
<< rBmpColor
.GetBlue() << rBmpColor
.GetGreen() << rBmpColor
.GetRed();
393 rStrm
.WriteZeroBytes( nPadding
);
398 Bitmap::ReleaseAccess( pAccess
);
402 void XclExpImgData::SaveXml( XclExpXmlStream
& rStrm
)
404 sax_fastparser::FSHelperPtr pWorksheet
= rStrm
.GetCurrentStream();
406 DrawingML
aDML( pWorksheet
, &rStrm
, DrawingML::DOCUMENT_XLSX
);
407 OUString rId
= aDML
.WriteImage( maGraphic
);
408 pWorksheet
->singleElement( XML_picture
,
409 FSNS( XML_r
, XML_id
), XclXmlUtils::ToOString( rId
).getStr(),
413 XclExpControlHelper::XclExpControlHelper( const XclExpRoot
& rRoot
) :
419 XclExpControlHelper::~XclExpControlHelper()
423 void XclExpControlHelper::ConvertSheetLinks( Reference
< XShape
> xShape
)
430 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( xShape
);
431 if( !xCtrlModel
.is() )
434 // *** cell link *** ------------------------------------------------------
436 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY
);
439 Reference
< XServiceInfo
> xServInfo( xBindable
->getValueBinding(), UNO_QUERY
);
440 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_VALBIND
) )
442 ScfPropertySet
aBindProp( xServInfo
);
443 CellAddress aApiAddress
;
444 if( aBindProp
.GetProperty( aApiAddress
, SC_UNONAME_BOUNDCELL
) )
447 ScUnoConversion::FillScAddress( aCellLink
, aApiAddress
);
448 if( GetTabInfo().IsExportTab( aCellLink
.Tab() ) )
449 mxCellLink
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aCellLink
);
454 // *** source range *** ---------------------------------------------------
456 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY
);
457 if( xEntrySink
.is() )
459 Reference
< XServiceInfo
> xServInfo( xEntrySink
->getListEntrySource(), UNO_QUERY
);
460 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_LISTSOURCE
) )
462 ScfPropertySet
aSinkProp( xServInfo
);
463 CellRangeAddress aApiRange
;
464 if( aSinkProp
.GetProperty( aApiRange
, SC_UNONAME_CELLRANGE
) )
467 ScUnoConversion::FillScRange( aSrcRange
, aApiRange
);
468 if( (aSrcRange
.aStart
.Tab() == aSrcRange
.aEnd
.Tab()) && GetTabInfo().IsExportTab( aSrcRange
.aStart
.Tab() ) )
469 mxSrcRange
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aSrcRange
);
470 mnEntryCount
= static_cast< sal_uInt16
>( aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1 );
476 void XclExpControlHelper::WriteFormula( XclExpStream
& rStrm
, const XclTokenArray
& rTokArr
)
478 sal_uInt16 nFmlaSize
= rTokArr
.GetSize();
479 rStrm
<< nFmlaSize
<< sal_uInt32( 0 );
480 rTokArr
.WriteArray( rStrm
);
481 if( nFmlaSize
& 1 ) // pad to 16-bit
482 rStrm
<< sal_uInt8( 0 );
485 void XclExpControlHelper::WriteFormulaSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
, const XclTokenArray
& rTokArr
)
487 rStrm
.StartRecord( nSubRecId
, (rTokArr
.GetSize() + 5) & ~1 );
488 WriteFormula( rStrm
, rTokArr
);
492 //delete for exporting OCX
493 //#if EXC_EXP_OCX_CTRL
495 XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> xShape
,
496 const Rectangle
* pChildAnchor
, const OUString
& rClassName
, sal_uInt32 nStrmStart
, sal_uInt32 nStrmSize
) :
497 XclObj( rObjMgr
, EXC_OBJTYPE_PICTURE
, true ),
498 XclExpControlHelper( rObjMgr
.GetRoot() ),
499 maClassName( rClassName
),
500 mnStrmStart( nStrmStart
),
501 mnStrmSize( nStrmSize
)
503 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
507 SetPrintable( aCtrlProp
.GetBoolProperty( "Printable" ) );
508 SetAutoFill( false );
509 SetAutoLine( false );
511 // fill DFF property set
512 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
513 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVESPT
| SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_OLESHAPE
);
514 Rectangle aDummyRect
;
515 EscherPropertyContainer
aPropOpt( mrEscherEx
.GetGraphicProvider(), mrEscherEx
.QueryPictureStream(), aDummyRect
);
516 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 ); // bool field
517 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x08000040 );
518 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
520 // #i51348# name of the control, may overwrite shape name
522 if( aCtrlProp
.GetProperty( aCtrlName
, "Name" ) && !aCtrlName
.isEmpty() )
523 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
527 Reference
< XPropertySet
> xShapePS( xShape
, UNO_QUERY
);
528 if( xShapePS
.is() && aPropOpt
.CreateGraphicProperties( xShapePS
, OUString( "MetaFile" ), false ) )
531 if( aPropOpt
.GetOpt( ESCHER_Prop_pib
, nBlipId
) )
532 aPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nBlipId
);
535 // write DFF property set to stream
536 aPropOpt
.Commit( mrEscherEx
.GetStream() );
539 ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
541 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
542 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
543 mrEscherEx
.UpdateDffFragmentEnd();
546 ConvertSheetLinks( xShape
);
549 void XclExpOcxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
551 // OBJCF - clipboard format
552 rStrm
.StartRecord( EXC_ID_OBJCF
, 2 );
553 rStrm
<< sal_uInt16( 2 );
557 rStrm
.StartRecord( EXC_ID_OBJFLAGS
, 2 );
558 rStrm
<< sal_uInt16( 0x0031 );
562 XclExpString
aClass( maClassName
);
563 sal_uInt16 nClassNameSize
= static_cast< sal_uInt16
>( aClass
.GetSize() );
564 sal_uInt16 nClassNamePad
= nClassNameSize
& 1;
565 sal_uInt16 nFirstPartSize
= 12 + nClassNameSize
+ nClassNamePad
;
567 const XclTokenArray
* pCellLink
= GetCellLinkTokArr();
568 sal_uInt16 nCellLinkSize
= pCellLink
? ((pCellLink
->GetSize() + 7) & 0xFFFE) : 0;
570 const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr();
571 sal_uInt16 nSrcRangeSize
= pSrcRange
? ((pSrcRange
->GetSize() + 7) & 0xFFFE) : 0;
573 sal_uInt16 nPictFmlaSize
= nFirstPartSize
+ nCellLinkSize
+ nSrcRangeSize
+ 18;
574 rStrm
.StartRecord( EXC_ID_OBJPICTFMLA
, nPictFmlaSize
);
576 rStrm
<< sal_uInt16( nFirstPartSize
) // size of first part
577 << sal_uInt16( 5 ) // formula size
578 << sal_uInt32( 0 ) // unknown ID
579 << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
580 << sal_uInt8( 3 ) // pad to word
581 << aClass
; // "Forms.***.1"
582 rStrm
.WriteZeroBytes( nClassNamePad
); // pad to word
583 rStrm
<< mnStrmStart
// start in 'Ctls' stream
584 << mnStrmSize
// size in 'Ctls' stream
585 << sal_uInt32( 0 ); // class ID size
587 rStrm
<< nCellLinkSize
;
589 WriteFormula( rStrm
, *pCellLink
);
591 rStrm
<< nSrcRangeSize
;
593 WriteFormula( rStrm
, *pSrcRange
);
600 XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager
& rRoot
, Reference
< XShape
> xShape
, const Rectangle
* pChildAnchor
) :
601 XclObj( rRoot
, EXC_OBJTYPE_UNKNOWN
, true ),
602 XclMacroHelper( rRoot
),
603 meEventType( EXC_TBX_EVENT_ACTION
),
613 mbFlatButton( false ),
614 mbFlatBorder( false ),
618 namespace FormCompType
= ::com::sun::star::form::FormComponentType
;
619 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
620 namespace AwtScrollOrient
= ::com::sun::star::awt::ScrollBarOrientation
;
622 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
623 if( !xShape
.is() || !aCtrlProp
.Is() )
626 mnHeight
= xShape
->getSize().Height
;
631 sal_Int16 nClassId
= 0;
632 if( aCtrlProp
.GetProperty( nClassId
, "ClassId" ) )
636 case FormCompType::COMMANDBUTTON
: mnObjType
= EXC_OBJTYPE_BUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
637 case FormCompType::RADIOBUTTON
: mnObjType
= EXC_OBJTYPE_OPTIONBUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
638 case FormCompType::CHECKBOX
: mnObjType
= EXC_OBJTYPE_CHECKBOX
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
639 case FormCompType::LISTBOX
: mnObjType
= EXC_OBJTYPE_LISTBOX
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
640 case FormCompType::COMBOBOX
: mnObjType
= EXC_OBJTYPE_DROPDOWN
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
641 case FormCompType::GROUPBOX
: mnObjType
= EXC_OBJTYPE_GROUPBOX
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
642 case FormCompType::FIXEDTEXT
: mnObjType
= EXC_OBJTYPE_LABEL
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
643 case FormCompType::SCROLLBAR
: mnObjType
= EXC_OBJTYPE_SCROLLBAR
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
644 case FormCompType::SPINBUTTON
: mnObjType
= EXC_OBJTYPE_SPIN
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
647 if( mnObjType
== EXC_OBJTYPE_UNKNOWN
)
652 SetPrintable( aCtrlProp
.GetBoolProperty( "Printable" ) );
653 SetAutoFill( false );
654 SetAutoLine( false );
656 // fill DFF property set
657 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
658 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_HAVESPT
);
659 EscherPropertyContainer aPropOpt
;
660 bool bVisible
= aCtrlProp
.GetBoolProperty( "EnableVisible" );
661 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, bVisible
? 0x00080000 : 0x00080002 ); // visible flag
663 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01000100 ); // bool field
664 aPropOpt
.AddOpt( ESCHER_Prop_lTxid
, 0 ); // Text ID
665 aPropOpt
.AddOpt( ESCHER_Prop_WrapText
, 0x00000001 );
666 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x001A0008 ); // bool field
667 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00100000 ); // bool field
668 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
670 // #i51348# name of the control, may overwrite shape name
672 if( aCtrlProp
.GetProperty( aCtrlName
, "Name" ) && !aCtrlName
.isEmpty() )
673 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
675 //Export description as alt text
676 if( SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
) )
679 OUString aDescrText
= pSdrObj
->GetDescription();
680 if(!aDescrText
.isEmpty())
681 aAltTxt
= aDescrText
.copy( 0, std::min
<sal_Int32
>(MSPROP_DESCRIPTION_MAX_LEN
, aDescrText
.getLength()) );
682 aPropOpt
.AddOpt( ESCHER_Prop_wzDescription
, aAltTxt
);
685 // write DFF property set to stream
686 aPropOpt
.Commit( mrEscherEx
.GetStream() );
689 ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
691 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
692 mrEscherEx
.UpdateDffFragmentEnd();
696 if( aCtrlProp
.GetProperty( aString
, "Label" ) )
698 /* Be sure to construct the MSODRAWING record containing the
699 ClientTextbox atom after the base OBJ's MSODRAWING record data is
701 pClientTextbox
= new XclExpMsoDrawing( mrEscherEx
);
702 mrEscherEx
.AddAtom( 0, ESCHER_ClientTextbox
); // TXO record
703 mrEscherEx
.UpdateDffFragmentEnd();
705 sal_uInt16 nXclFont
= EXC_FONT_APP
;
706 if( !aString
.isEmpty() )
708 XclFontData aFontData
;
709 GetFontPropSetHelper().ReadFontProperties( aFontData
, aCtrlProp
, EXC_FONTPROPSET_CONTROL
);
710 if( (!aFontData
.maName
.isEmpty() ) && (aFontData
.mnHeight
> 0) )
711 nXclFont
= GetFontBuffer().Insert( aFontData
, EXC_COLOR_CTRLTEXT
);
714 pTxo
= new XclTxo( aString
, nXclFont
);
715 pTxo
->SetHorAlign( (mnObjType
== EXC_OBJTYPE_BUTTON
) ? EXC_OBJ_HOR_CENTER
: EXC_OBJ_HOR_LEFT
);
716 pTxo
->SetVerAlign( EXC_OBJ_VER_CENTER
);
719 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
722 aCtrlProp
.GetProperty( mnLineCount
, "LineCount" );
725 sal_Int16 nApiButton
= AwtVisualEffect::LOOK3D
;
726 sal_Int16 nApiBorder
= AwtVisualEffect::LOOK3D
;
729 case FormCompType::LISTBOX
:
730 case FormCompType::COMBOBOX
:
731 aCtrlProp
.GetProperty( nApiBorder
, "Border" );
733 case FormCompType::CHECKBOX
:
734 case FormCompType::RADIOBUTTON
:
735 aCtrlProp
.GetProperty( nApiButton
, "VisualEffect" );
736 nApiBorder
= AwtVisualEffect::NONE
;
738 // Push button cannot be set to flat in Excel
739 case FormCompType::COMMANDBUTTON
:
740 nApiBorder
= AwtVisualEffect::LOOK3D
;
742 // Label does not support a border in Excel
743 case FormCompType::FIXEDTEXT
:
744 nApiBorder
= AwtVisualEffect::NONE
;
746 /* Scroll bar and spin button have a "Border" property, but it is
747 really used for a border, and not for own 3D/flat look (#i34712#). */
748 case FormCompType::SCROLLBAR
:
749 case FormCompType::SPINBUTTON
:
750 nApiButton
= AwtVisualEffect::LOOK3D
;
751 nApiBorder
= AwtVisualEffect::NONE
;
753 // Group box does not support flat style (#i34712#)
754 case FormCompType::GROUPBOX
:
755 nApiBorder
= AwtVisualEffect::LOOK3D
;
758 mbFlatButton
= nApiButton
!= AwtVisualEffect::LOOK3D
;
759 mbFlatBorder
= nApiBorder
!= AwtVisualEffect::LOOK3D
;
762 sal_Int16 nApiState
= 0;
763 if( aCtrlProp
.GetProperty( nApiState
, "State" ) )
767 case 0: mnState
= EXC_OBJ_CHECKBOX_UNCHECKED
; break;
768 case 1: mnState
= EXC_OBJ_CHECKBOX_CHECKED
; break;
769 case 2: mnState
= EXC_OBJ_CHECKBOX_TRISTATE
; break;
773 // special control contents
776 case FormCompType::LISTBOX
:
778 mbMultiSel
= aCtrlProp
.GetBoolProperty( "MultiSelection" );
779 Sequence
< sal_Int16
> aSelection
;
780 if( aCtrlProp
.GetProperty( aSelection
, "SelectedItems" ) )
782 sal_Int32 nLen
= aSelection
.getLength();
785 mnSelEntry
= aSelection
[ 0 ] + 1;
786 maMultiSel
.resize( nLen
);
787 const sal_Int16
* pnBegin
= aSelection
.getConstArray();
788 ::std::copy( pnBegin
, pnBegin
+ nLen
, maMultiSel
.begin() );
792 // convert listbox with dropdown button to Excel dropdown
793 if( aCtrlProp
.GetBoolProperty( "Dropdown" ) )
794 mnObjType
= EXC_OBJTYPE_DROPDOWN
;
798 case FormCompType::COMBOBOX
:
800 Sequence
< OUString
> aStringList
;
802 if( aCtrlProp
.GetProperty( aStringList
, "StringItemList" ) &&
803 aCtrlProp
.GetProperty( aDefText
, "Text" ) &&
804 aStringList
.getLength() && !aDefText
.isEmpty() )
806 const OUString
* pBegin
= aStringList
.getConstArray();
807 const OUString
* pEnd
= pBegin
+ aStringList
.getLength();
808 const OUString
* pString
= ::std::find( pBegin
, pEnd
, aDefText
);
809 if( pString
!= pEnd
)
810 mnSelEntry
= static_cast< sal_Int16
>( pString
- pBegin
+ 1 ); // 1-based
812 maMultiSel
.resize( 1, mnSelEntry
- 1 );
815 // convert combobox without dropdown button to Excel listbox
816 if( !aCtrlProp
.GetBoolProperty( "Dropdown" ) )
817 mnObjType
= EXC_OBJTYPE_LISTBOX
;
821 case FormCompType::SCROLLBAR
:
823 sal_Int32 nApiValue
= 0;
824 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMin" ) )
825 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
826 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMax" ) )
827 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MIN
);
828 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValue" ) )
829 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
830 if( aCtrlProp
.GetProperty( nApiValue
, "LineIncrement" ) )
831 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
832 if( aCtrlProp
.GetProperty( nApiValue
, "BlockIncrement" ) )
833 mnScrollPage
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
834 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
835 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
839 case FormCompType::SPINBUTTON
:
841 sal_Int32 nApiValue
= 0;
842 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMin" ) )
843 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
844 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMax" ) )
845 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MAX
);
846 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValue" ) )
847 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
848 if( aCtrlProp
.GetProperty( nApiValue
, "SpinIncrement" ) )
849 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
850 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
851 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
857 ConvertSheetLinks( xShape
);
860 bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor
& rEvent
)
862 return XclMacroHelper::SetMacroLink( rEvent
, meEventType
);
865 void XclExpTbxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
869 // *** Push buttons, labels ***
871 case EXC_OBJTYPE_BUTTON
:
872 case EXC_OBJTYPE_LABEL
:
873 // ftMacro - macro link
874 WriteMacroSubRec( rStrm
);
877 // *** Check boxes, option buttons ***
879 case EXC_OBJTYPE_CHECKBOX
:
880 case EXC_OBJTYPE_OPTIONBUTTON
:
882 // ftCbls - box properties
883 sal_uInt16 nStyle
= 0;
884 ::set_flag( nStyle
, EXC_OBJ_CHECKBOX_FLAT
, mbFlatButton
);
886 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 12 );
888 rStrm
.WriteZeroBytes( 8 );
892 // ftMacro - macro link
893 WriteMacroSubRec( rStrm
);
894 // ftCblsFmla subrecord - cell link
895 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJCBLSFMLA
);
897 // ftCblsData subrecord - box properties, again
898 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 8 );
900 rStrm
.WriteZeroBytes( 4 );
906 // *** List boxes, combo boxes ***
908 case EXC_OBJTYPE_LISTBOX
:
909 case EXC_OBJTYPE_DROPDOWN
:
911 sal_uInt16 nEntryCount
= GetSourceEntryCount();
913 // ftSbs subrecord - Scroll bars
914 sal_Int32 nLineHeight
= XclTools::GetHmmFromTwips( 200 ); // always 10pt
915 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
916 mnLineCount
= static_cast< sal_uInt16
>( mnHeight
/ nLineHeight
);
919 sal_uInt16 nInvisLines
= (nEntryCount
>= mnLineCount
) ? (nEntryCount
- mnLineCount
) : 0;
920 mnScrollMax
= limit_cast
< sal_uInt16
>( nInvisLines
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
922 mnScrollPage
= limit_cast
< sal_uInt16
>( mnLineCount
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
926 // ftMacro - macro link
927 WriteMacroSubRec( rStrm
);
928 // ftSbsFmla subrecord - cell link
929 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
931 // ftLbsData - source data range and box properties
932 sal_uInt16 nStyle
= 0;
933 ::insert_value( nStyle
, mbMultiSel
? EXC_OBJ_LISTBOX_MULTI
: EXC_OBJ_LISTBOX_SINGLE
, 4, 2 );
934 ::set_flag( nStyle
, EXC_OBJ_LISTBOX_FLAT
, mbFlatBorder
);
936 rStrm
.StartRecord( EXC_ID_OBJLBSDATA
, 0 );
938 if( const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr() )
940 rStrm
<< static_cast< sal_uInt16
>( (pSrcRange
->GetSize() + 7) & 0xFFFE );
941 WriteFormula( rStrm
, *pSrcRange
);
944 rStrm
<< sal_uInt16( 0 );
946 rStrm
<< nEntryCount
<< mnSelEntry
<< nStyle
<< sal_uInt16( 0 );
947 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
951 ScfUInt8Vec
aSelEx( nEntryCount
, 0 );
952 for( ScfInt16Vec::const_iterator aIt
= maMultiSel
.begin(), aEnd
= maMultiSel
.end(); aIt
!= aEnd
; ++aIt
)
953 if( *aIt
< nEntryCount
)
955 rStrm
.Write( &aSelEx
[ 0 ], aSelEx
.size() );
958 else if( mnObjType
== EXC_OBJTYPE_DROPDOWN
)
960 rStrm
<< sal_uInt16( 0 ) << mnLineCount
<< sal_uInt16( 0 ) << sal_uInt16( 0 );
967 // *** Spin buttons, scrollbars ***
969 case EXC_OBJTYPE_SPIN
:
970 case EXC_OBJTYPE_SCROLLBAR
:
972 // ftSbs subrecord - scroll bars
974 // ftMacro - macro link
975 WriteMacroSubRec( rStrm
);
976 // ftSbsFmla subrecord - cell link
977 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
981 // *** Group boxes ***
983 case EXC_OBJTYPE_GROUPBOX
:
985 // ftMacro - macro link
986 WriteMacroSubRec( rStrm
);
988 // ftGboData subrecord - group box properties
989 sal_uInt16 nStyle
= 0;
990 ::set_flag( nStyle
, EXC_OBJ_GROUPBOX_FLAT
, mbFlatBorder
);
992 rStrm
.StartRecord( EXC_ID_OBJGBODATA
, 6 );
993 rStrm
<< sal_uInt32( 0 )
1001 void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
)
1003 if( const XclTokenArray
* pCellLink
= GetCellLinkTokArr() )
1004 WriteFormulaSubRec( rStrm
, nSubRecId
, *pCellLink
);
1007 void XclExpTbxControlObj::WriteSbs( XclExpStream
& rStrm
)
1009 sal_uInt16 nOrient
= 0;
1010 ::set_flag( nOrient
, EXC_OBJ_SCROLLBAR_HOR
, mbScrollHor
);
1011 sal_uInt16 nStyle
= EXC_OBJ_SCROLLBAR_DEFFLAGS
;
1012 ::set_flag( nStyle
, EXC_OBJ_SCROLLBAR_FLAT
, mbFlatButton
);
1014 rStrm
.StartRecord( EXC_ID_OBJSBS
, 20 );
1015 rStrm
<< sal_uInt32( 0 ) // reserved
1016 << mnScrollValue
// thumb position
1017 << mnScrollMin
// thumb min pos
1018 << mnScrollMax
// thumb max pos
1019 << mnScrollStep
// line increment
1020 << mnScrollPage
// page increment
1021 << nOrient
// 0 = vertical, 1 = horizontal
1022 << sal_uInt16( 15 ) // thumb width
1023 << nStyle
; // flags/style
1029 XclExpChartObj::XclExpChartObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> xShape
, const Rectangle
* pChildAnchor
) :
1030 XclObj( rObjMgr
, EXC_OBJTYPE_CHART
),
1031 XclExpRoot( rObjMgr
.GetRoot() ), mxShape( xShape
)
1033 // create the MSODRAWING record contents for the chart object
1034 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
1035 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_HAVESPT
);
1036 EscherPropertyContainer aPropOpt
;
1037 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01040104 );
1038 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 );
1039 aPropOpt
.AddOpt( ESCHER_Prop_fillColor
, 0x0800004E );
1040 aPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0x0800004D );
1041 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00110010 );
1042 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x0800004D );
1043 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
1044 aPropOpt
.AddOpt( ESCHER_Prop_fshadowObscured
, 0x00020000 );
1045 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x00080000 );
1046 aPropOpt
.Commit( mrEscherEx
.GetStream() );
1049 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
);
1050 ImplWriteAnchor( GetRoot(), pSdrObj
, pChildAnchor
);
1052 // client data (the following OBJ record)
1053 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
);
1054 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
1055 mrEscherEx
.UpdateDffFragmentEnd();
1057 // load the chart OLE object
1058 if( SdrOle2Obj
* pSdrOleObj
= dynamic_cast< SdrOle2Obj
* >( pSdrObj
) )
1059 svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj
->GetObjRef() );
1061 // create the chart substream object
1062 ScfPropertySet
aShapeProp( xShape
);
1063 Reference
< XModel
> xModel
;
1064 aShapeProp
.GetProperty( xModel
, "Model" );
1065 mxChartDoc
.set( xModel
,UNO_QUERY
);
1066 ::com::sun::star::awt::Rectangle aBoundRect
;
1067 aShapeProp
.GetProperty( aBoundRect
, "BoundRect" );
1068 Rectangle
aChartRect( Point( aBoundRect
.X
, aBoundRect
.Y
), Size( aBoundRect
.Width
, aBoundRect
.Height
) );
1069 mxChart
.reset( new XclExpChart( GetRoot(), xModel
, aChartRect
) );
1072 XclExpChartObj::~XclExpChartObj()
1076 void XclExpChartObj::Save( XclExpStream
& rStrm
)
1078 // content of OBJ record
1079 XclObj::Save( rStrm
);
1081 mxChart
->Save( rStrm
);
1084 void XclExpChartObj::SaveXml( XclExpXmlStream
& rStrm
)
1086 OSL_TRACE("XclExpChartObj::SaveXml -- Entry point to export chart");
1087 sax_fastparser::FSHelperPtr pDrawing
= rStrm
.GetCurrentStream();
1089 // FIXME: two cell? it seems the two cell anchor is incorrect.
1090 pDrawing
->startElement( FSNS( XML_xdr
, XML_twoCellAnchor
), // OOXTODO: oneCellAnchor, absoluteAnchor
1091 XML_editAs
, "oneCell",
1093 Reference
< XPropertySet
> xPropSet( mxShape
, UNO_QUERY
);
1096 XclObjAny::WriteFromTo( rStrm
, mxShape
, GetTab() );
1097 Reference
< XModel
> xModel( mxChartDoc
, UNO_QUERY
);
1098 ChartExport
aChartExport( XML_xdr
, pDrawing
, xModel
, &rStrm
, DrawingML::DOCUMENT_XLSX
);
1099 static sal_Int32 nChartCount
= 0;
1101 aChartExport
.WriteChartObj( mxShape
, nChartCount
);
1102 // TODO: get the correcto chart number
1105 pDrawing
->singleElement( FSNS( XML_xdr
, XML_clientData
),
1106 // OOXTODO: XML_fLocksWithSheet
1107 // OOXTODO: XML_fPrintsWithSheet
1109 pDrawing
->endElement( FSNS( XML_xdr
, XML_twoCellAnchor
) );
1112 const css::uno::Reference
<css::chart::XChartDocument
>& XclExpChartObj::GetChartDoc() const
1117 XclExpNote::XclExpNote( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
,
1118 const ScPostIt
* pScNote
, const OUString
& rAddText
) :
1119 XclExpRecord( EXC_ID_NOTE
),
1121 mnObjId( EXC_OBJ_INVALID_ID
),
1122 mbVisible( pScNote
&& pScNote
->IsCaptionShown() )
1124 // get the main note text
1128 aNoteText
= pScNote
->GetText();
1129 const EditTextObject
*pEditObj
= pScNote
->GetEditTextObject();
1131 mpNoteContents
= XclExpStringHelper::CreateString( rRoot
, *pEditObj
);
1133 // append additional text
1134 aNoteText
= ScGlobal::addToken( aNoteText
, rAddText
, '\n', 2 );
1135 maOrigNoteText
= aNoteText
;
1137 // initialize record dependent on BIFF type
1138 switch( rRoot
.GetBiff() )
1141 maNoteText
= OUStringToOString(aNoteText
, rRoot
.GetTextEncoding());
1146 // TODO: additional text
1148 if( SdrCaptionObj
* pCaption
= pScNote
->GetOrCreateCaption( maScPos
) )
1150 lcl_GetFromTo( rRoot
, pCaption
->GetLogicRect(), maScPos
.Tab(), maCommentFrom
, maCommentTo
);
1151 if( const OutlinerParaObject
* pOPO
= pCaption
->GetOutlinerParaObject() )
1152 mnObjId
= rRoot
.GetObjectManager().AddObj( new XclObjComment( rRoot
.GetObjectManager(), pCaption
->GetLogicRect(), pOPO
->GetTextObject(), pCaption
, mbVisible
, maScPos
, maCommentFrom
, maCommentTo
) );
1154 SfxItemSet aItemSet
= pCaption
->GetMergedItemSet();
1155 meTVA
= pCaption
->GetTextVerticalAdjust();
1156 meTHA
= pCaption
->GetTextHorizontalAdjust();
1157 mbAutoScale
= pCaption
->GetFitToSize() != SDRTEXTFIT_NONE
;
1158 mbLocked
= pCaption
->IsMoveProtect() || pCaption
->IsResizeProtect();
1160 // AutoFill style would change if Postit.cxx object creation values are changed
1161 OUString
aCol(((XFillColorItem
&)GETITEM(aItemSet
, XFillColorItem
, XATTR_FILLCOLOR
)).GetValue());
1162 mbAutoFill
= aCol
.isEmpty() && (GETITEMVALUE(aItemSet
, XFillStyleItem
, XATTR_FILLSTYLE
, sal_uLong
) == drawing::FillStyle_SOLID
);
1164 mbRowHidden
= (rRoot
.GetDoc().RowHidden(maScPos
.Row(),maScPos
.Tab()));
1165 mbColHidden
= (rRoot
.GetDoc().ColHidden(maScPos
.Col(),maScPos
.Tab()));
1168 SetRecSize( 9 + maAuthor
.GetSize() );
1172 default: DBG_ERROR_BIFF();
1176 void XclExpNote::Save( XclExpStream
& rStrm
)
1178 switch( rStrm
.GetRoot().GetBiff() )
1182 // write the NOTE record directly, there may be the need to create more than one
1183 const sal_Char
* pcBuffer
= maNoteText
.getStr();
1184 sal_uInt16 nCharsLeft
= static_cast< sal_uInt16
>( maNoteText
.getLength() );
1188 sal_uInt16 nWriteChars
= ::std::min( nCharsLeft
, EXC_NOTE5_MAXLEN
);
1190 rStrm
.StartRecord( EXC_ID_NOTE
, 6 + nWriteChars
);
1191 if( pcBuffer
== maNoteText
.getStr() )
1193 // first record: row, col, length of complete text
1194 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1195 << static_cast< sal_uInt16
>( maScPos
.Col() )
1196 << nCharsLeft
; // still contains full length
1200 // next records: -1, 0, length of current text segment
1201 rStrm
<< sal_uInt16( 0xFFFF )
1205 rStrm
.Write( pcBuffer
, nWriteChars
);
1208 pcBuffer
+= nWriteChars
;
1209 nCharsLeft
= nCharsLeft
- nWriteChars
;
1215 if( mnObjId
!= EXC_OBJ_INVALID_ID
)
1216 XclExpRecord::Save( rStrm
);
1219 default: DBG_ERROR_BIFF();
1223 void XclExpNote::WriteBody( XclExpStream
& rStrm
)
1225 // BIFF5/BIFF7 is written separately
1226 OSL_ENSURE_BIFF( rStrm
.GetRoot().GetBiff() == EXC_BIFF8
);
1228 sal_uInt16 nFlags
= 0;
1229 ::set_flag( nFlags
, EXC_NOTE_VISIBLE
, mbVisible
);
1231 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1232 << static_cast< sal_uInt16
>( maScPos
.Col() )
1239 void XclExpNote::WriteXml( sal_Int32 nAuthorId
, XclExpXmlStream
& rStrm
)
1241 sax_fastparser::FSHelperPtr rComments
= rStrm
.GetCurrentStream();
1243 rComments
->startElement( XML_comment
,
1244 XML_ref
, XclXmlUtils::ToOString( maScPos
).getStr(),
1245 XML_authorId
, OString::number( nAuthorId
).getStr(),
1246 // OOXTODO: XML_guid,
1248 rComments
->startElement( XML_text
, FSEND
);
1249 // OOXTODO: phoneticPr, rPh, r
1250 if( mpNoteContents
)
1251 mpNoteContents
->WriteXml( rStrm
);
1252 rComments
->endElement( XML_text
);
1255 Export of commentPr is disabled, since the current (Oct 2010)
1256 version of MSO 2010 doesn't yet support commentPr
1258 #if 1//def XLSX_OOXML_FUTURE
1259 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1261 rComments
->startElement( FSNS( XML_mc
, XML_AlternateContent
), FSEND
);
1262 rComments
->startElement( FSNS( XML_mc
, XML_Choice
), XML_Requires
, "v2", FSEND
);
1263 rComments
->startElement( XML_commentPr
,
1264 XML_autoFill
, XclXmlUtils::ToPsz( mbAutoFill
),
1265 XML_autoScale
, XclXmlUtils::ToPsz( mbAutoScale
),
1266 XML_colHidden
, XclXmlUtils::ToPsz( mbColHidden
),
1267 XML_locked
, XclXmlUtils::ToPsz( mbLocked
),
1268 XML_rowHidden
, XclXmlUtils::ToPsz( mbRowHidden
),
1269 XML_textHAlign
, ToHorizAlign( meTHA
),
1270 XML_textVAlign
, ToVertAlign( meTVA
) ,
1272 rComments
->startElement( XML_anchor
,
1273 XML_moveWithCells
, "false",
1274 XML_sizeWithCells
, "false",
1276 rComments
->startElement( FSNS( XML_xdr
, XML_from
), FSEND
);
1277 lcl_WriteAnchorVertex( rComments
, maCommentFrom
);
1278 rComments
->endElement( FSNS( XML_xdr
, XML_from
) );
1279 rComments
->startElement( FSNS( XML_xdr
, XML_to
), FSEND
);
1280 lcl_WriteAnchorVertex( rComments
, maCommentTo
);
1281 rComments
->endElement( FSNS( XML_xdr
, XML_to
) );
1282 rComments
->endElement( XML_anchor
);
1283 rComments
->endElement( XML_commentPr
);
1285 rComments
->endElement( FSNS( XML_mc
, XML_Choice
) );
1286 rComments
->startElement( FSNS( XML_mc
, XML_Fallback
), FSEND
);
1287 // Any fallback code ?
1288 rComments
->endElement( FSNS( XML_mc
, XML_Fallback
) );
1289 rComments
->endElement( FSNS( XML_mc
, XML_AlternateContent
) );
1292 rComments
->endElement( XML_comment
);
1295 XclMacroHelper::XclMacroHelper( const XclExpRoot
& rRoot
) :
1296 XclExpControlHelper( rRoot
)
1300 XclMacroHelper::~XclMacroHelper()
1304 void XclMacroHelper::WriteMacroSubRec( XclExpStream
& rStrm
)
1307 WriteFormulaSubRec( rStrm
, EXC_ID_OBJMACRO
, *mxMacroLink
);
1311 XclMacroHelper::SetMacroLink( const ScriptEventDescriptor
& rEvent
, const XclTbxEventType
& nEventType
)
1313 OUString aMacroName
= XclControlHelper::ExtractFromMacroDescriptor( rEvent
, nEventType
, GetDocShell() );
1314 if( !aMacroName
.isEmpty() )
1316 return SetMacroLink( aMacroName
);
1322 XclMacroHelper::SetMacroLink( const OUString
& rMacroName
)
1324 OSL_TRACE("SetMacroLink( macroname:=%s )", OUStringToOString( rMacroName
, RTL_TEXTENCODING_UTF8
).getStr() );
1325 if( !rMacroName
.isEmpty() )
1327 sal_uInt16 nExtSheet
= GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC
);
1328 sal_uInt16 nNameIdx
= GetNameManager().InsertMacroCall( rMacroName
, true, false );
1329 mxMacroLink
= GetFormulaCompiler().CreateNameXFormula( nExtSheet
, nNameIdx
);
1335 XclExpShapeObj::XclExpShapeObj( XclExpObjectManager
& rRoot
, ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> xShape
) :
1336 XclObjAny( rRoot
, xShape
),
1337 XclMacroHelper( rRoot
)
1339 if( SdrObject
* pSdrObj
= ::GetSdrObjectFromXShape( xShape
) )
1341 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pSdrObj
);
1342 if ( pInfo
&& !pInfo
->GetMacro().isEmpty() )
1343 // FIXME ooo330-m2: XclControlHelper::GetXclMacroName was removed in upstream sources; they started to call XclTools::GetXclMacroName instead; is this enough? it has only one parameter
1344 // SetMacroLink( XclControlHelper::GetXclMacroName( pInfo->GetMacro(), rRoot.GetDocShell() ) );
1345 SetMacroLink( XclTools::GetXclMacroName( pInfo
->GetMacro() ) );
1349 XclExpShapeObj::~XclExpShapeObj()
1353 void XclExpShapeObj::WriteSubRecs( XclExpStream
& rStrm
)
1355 XclObjAny::WriteSubRecs( rStrm
);
1356 WriteMacroSubRec( rStrm
);
1359 XclExpComments::XclExpComments( SCTAB nTab
, XclExpRecordList
< XclExpNote
>& rNotes
)
1360 : mnTab( nTab
), mrNotes( rNotes
)
1364 struct OUStringLess
: public std::binary_function
<OUString
, OUString
, bool>
1366 bool operator()(const OUString
& x
, const OUString
& y
) const
1368 return x
.compareTo( y
) < 0;
1372 void XclExpComments::SaveXml( XclExpXmlStream
& rStrm
)
1374 if( mrNotes
.IsEmpty() )
1377 sax_fastparser::FSHelperPtr rComments
= rStrm
.CreateOutputStream(
1378 XclXmlUtils::GetStreamName( "xl/", "comments", mnTab
+ 1 ),
1379 XclXmlUtils::GetStreamName( "../", "comments", mnTab
+ 1 ),
1380 rStrm
.GetCurrentStream()->getOutputStream(),
1381 "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
1382 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" );
1383 rStrm
.PushStream( rComments
);
1385 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1386 rComments
->startElement( XML_comments
,
1387 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1388 FSNS( XML_xmlns
, XML_mc
), "http://schemas.openxmlformats.org/markup-compatibility/2006",
1389 FSNS( XML_xmlns
, XML_xdr
), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
1390 FSNS( XML_xmlns
, XML_v2
), "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
1391 FSNS( XML_mc
, XML_Ignorable
), "v2",
1394 rComments
->startElement( XML_comments
,
1395 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1396 FSNS( XML_xmlns
, XML_xdr
), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
1399 rComments
->startElement( XML_authors
, FSEND
);
1401 typedef std::set
< OUString
, OUStringLess
> Authors
;
1404 size_t nNotes
= mrNotes
.GetSize();
1405 for( size_t i
= 0; i
< nNotes
; ++i
)
1407 aAuthors
.insert( XclXmlUtils::ToOUString( mrNotes
.GetRecord( i
)->GetAuthor() ) );
1410 for( Authors::const_iterator b
= aAuthors
.begin(), e
= aAuthors
.end(); b
!= e
; ++b
)
1412 rComments
->startElement( XML_author
, FSEND
);
1413 rComments
->writeEscaped( *b
);
1414 rComments
->endElement( XML_author
);
1417 rComments
->endElement( XML_authors
);
1418 rComments
->startElement( XML_commentList
, FSEND
);
1420 Authors::const_iterator aAuthorsBegin
= aAuthors
.begin();
1421 for( size_t i
= 0; i
< nNotes
; ++i
)
1423 XclExpNoteList::RecordRefType xNote
= mrNotes
.GetRecord( i
);
1424 Authors::const_iterator aAuthor
= aAuthors
.find(
1425 XclXmlUtils::ToOUString( xNote
->GetAuthor() ) );
1426 sal_Int32 nAuthorId
= distance( aAuthorsBegin
, aAuthor
);
1427 xNote
->WriteXml( nAuthorId
, rStrm
);
1430 rComments
->endElement( XML_commentList
);
1431 rComments
->endElement( XML_comments
);
1436 // object manager =============================================================
1438 XclExpObjectManager::XclExpObjectManager( const XclExpRoot
& rRoot
) :
1442 mxEscherEx
.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm
) );
1445 XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager
& rParent
) :
1446 XclExpRoot( rParent
.GetRoot() )
1448 InitStream( false );
1449 mxEscherEx
.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm
, rParent
.mxEscherEx
.get() ) );
1452 XclExpObjectManager::~XclExpObjectManager()
1456 XclExpDffAnchorBase
* XclExpObjectManager::CreateDffAnchor() const
1458 return new XclExpDffSheetAnchor( GetRoot() );
1461 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::CreateDrawingGroup()
1463 return std::shared_ptr
< XclExpRecordBase
>( new XclExpMsoDrawingGroup( *mxEscherEx
) );
1466 void XclExpObjectManager::StartSheet()
1468 mxObjList
.reset( new XclExpObjList( GetRoot(), *mxEscherEx
) );
1471 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( SdrPage
* pSdrPage
)
1474 mxEscherEx
->AddSdrPage( *pSdrPage
);
1475 // the first dummy object may still be open
1476 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1477 while( mxEscherEx
->GetGroupLevel() )
1478 mxEscherEx
->LeaveGroup();
1479 mxObjList
->EndSheet();
1483 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( const Reference
< XShapes
>& rxShapes
)
1486 mxEscherEx
->AddUnoShapes( rxShapes
);
1487 // the first dummy object may still be open
1488 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1489 while( mxEscherEx
->GetGroupLevel() )
1490 mxEscherEx
->LeaveGroup();
1491 mxObjList
->EndSheet();
1495 void XclExpObjectManager::EndDocument()
1497 mxEscherEx
->EndDocument();
1500 XclExpMsoDrawing
* XclExpObjectManager::GetMsodrawingPerSheet()
1502 return mxObjList
->GetMsodrawingPerSheet();
1505 bool XclExpObjectManager::HasObj() const
1507 return !mxObjList
->empty();
1510 sal_uInt16
XclExpObjectManager::AddObj( XclObj
* pObjRec
)
1512 return mxObjList
->Add( pObjRec
);
1515 XclObj
* XclExpObjectManager::RemoveLastObj()
1517 XclObj
* pLastObj
= mxObjList
->back();
1518 mxObjList
->pop_back();
1522 void XclExpObjectManager::InitStream( bool bTempFile
)
1526 mxTempFile
.reset( new ::utl::TempFile
);
1527 if( mxTempFile
->IsValid() )
1529 mxTempFile
->EnableKillingFile();
1530 mxDffStrm
.reset( ::utl::UcbStreamHelper::CreateStream( mxTempFile
->GetURL(), STREAM_STD_READWRITE
) );
1534 if( !mxDffStrm
.get() )
1535 mxDffStrm
.reset( new SvMemoryStream
);
1537 mxDffStrm
->SetEndian( SvStreamEndian::LITTLE
);
1540 XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager(
1541 const XclExpObjectManager
& rParent
, const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
1542 XclExpObjectManager( rParent
),
1543 maPageSize( rPageSize
),
1544 mnScaleX( nScaleX
),
1549 XclExpDffAnchorBase
* XclExpEmbeddedObjectManager::CreateDffAnchor() const
1551 return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize
, mnScaleX
, mnScaleY
);
1554 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */