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/XListEntrySink.hpp>
30 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
31 #include <com/sun/star/chart2/XChartDocument.hpp>
32 #include <com/sun/star/awt/Point.hpp>
33 #include <com/sun/star/awt/Size.hpp>
36 #include <rtl/ustrbuf.h>
37 #include <vcl/bitmapaccess.hxx>
38 #include <svx/svdoole2.hxx>
39 #include <svx/svdocapt.hxx>
40 #include <editeng/outlobj.hxx>
41 #include <editeng/editobj.hxx>
42 #include <unotools/tempfile.hxx>
43 #include <unotools/ucbstreamhelper.hxx>
44 #include <svtools/embedhlp.hxx>
46 #include "editutil.hxx"
47 #include "unonames.hxx"
48 #include "convuno.hxx"
51 #include "fapihelper.hxx"
52 #include "xechart.hxx"
53 #include "xeformula.hxx"
56 #include "xestyle.hxx"
57 #include "userdat.hxx"
58 #include "drwlayer.hxx"
59 #include <svx/unoapi.hxx>
60 #include <svx/algitem.hxx>
61 #include "scitems.hxx"
62 #include <editeng/justifyitem.hxx>
63 #include <svx/sdtaitm.hxx>
65 #include "document.hxx"
66 #include <svx/svdattr.hxx>
67 #include <svx/sdr/properties/properties.hxx>
68 #include "detfunc.hxx"
69 #include <svx/xflclit.hxx>
70 #include <svx/xlnstwit.hxx>
71 #include <svx/xlnstit.hxx>
73 #include <oox/token/tokens.hxx>
74 #include <oox/export/drawingml.hxx>
75 #include <oox/export/chartexport.hxx>
76 #include <oox/export/utils.hxx>
79 using namespace com::sun::star
;
80 using ::com::sun::star::uno::UNO_QUERY
;
81 using ::com::sun::star::uno::Reference
;
82 using ::com::sun::star::uno::Sequence
;
83 using ::com::sun::star::lang::XServiceInfo
;
84 using ::com::sun::star::beans::XPropertySet
;
85 using ::com::sun::star::drawing::XShape
;
86 using ::com::sun::star::drawing::XShapes
;
87 using ::com::sun::star::frame::XModel
;
88 using ::com::sun::star::awt::XControlModel
;
89 using ::com::sun::star::form::binding::XBindableValue
;
90 using ::com::sun::star::form::binding::XListEntrySink
;
91 using ::com::sun::star::script::ScriptEventDescriptor
;
92 using ::com::sun::star::table::CellAddress
;
93 using ::com::sun::star::table::CellRangeAddress
;
94 using ::com::sun::star::chart2::XChartDocument
;
95 using ::oox::drawingml::DrawingML
;
96 using ::oox::drawingml::ChartExport
;
102 inline long lcl_hmm2px(long nPixel
)
104 return static_cast<long>(nPixel
*PIXEL_PER_INCH
/1000.0/CM_PER_INCH
)+0.5;
107 const char *ToHorizAlign( SdrTextHorzAdjust eAdjust
)
111 case SDRTEXTHORZADJUST_CENTER
:
113 case SDRTEXTHORZADJUST_RIGHT
:
115 case SDRTEXTHORZADJUST_BLOCK
:
117 case SDRTEXTHORZADJUST_LEFT
:
123 const char *ToVertAlign( SdrTextVertAdjust eAdjust
)
127 case SDRTEXTVERTADJUST_CENTER
:
129 case SDRTEXTVERTADJUST_BOTTOM
:
131 case SDRTEXTVERTADJUST_BLOCK
:
133 case SDRTEXTVERTADJUST_TOP
:
139 void lcl_WriteAnchorVertex( sax_fastparser::FSHelperPtr rComments
, Rectangle
&aRect
)
141 rComments
->startElement( FSNS( XML_xdr
, XML_col
), FSEND
);
142 rComments
->writeEscaped( OUString::number( aRect
.Left() ) );
143 rComments
->endElement( FSNS( XML_xdr
, XML_col
) );
144 rComments
->startElement( FSNS( XML_xdr
, XML_colOff
), FSEND
);
145 rComments
->writeEscaped( OUString::number( aRect
.Top() ) );
146 rComments
->endElement( FSNS( XML_xdr
, XML_colOff
) );
147 rComments
->startElement( FSNS( XML_xdr
, XML_row
), FSEND
);
148 rComments
->writeEscaped( OUString::number( aRect
.Right() ) );
149 rComments
->endElement( FSNS( XML_xdr
, XML_row
) );
150 rComments
->startElement( FSNS( XML_xdr
, XML_rowOff
), FSEND
);
151 rComments
->writeEscaped( OUString::number( aRect
.Bottom() ) );
152 rComments
->endElement( FSNS( XML_xdr
, XML_rowOff
) );
155 void lcl_GetFromTo( const XclExpRoot
& rRoot
, const Rectangle
&aRect
, sal_Int32 nTab
, Rectangle
&aFrom
, Rectangle
&aTo
)
157 sal_Int32 nCol
= 0, nRow
= 0;
158 sal_Int32 nColOff
= 0, nRowOff
= 0;
160 const bool bRTL
= rRoot
.GetDocRef().IsNegativePage( nTab
);
165 Rectangle r
= rRoot
.GetDocRef().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
166 if( r
.Left() <= aRect
.Left() )
169 nColOff
= aRect
.Left() - r
.Left();
171 if( r
.Top() <= aRect
.Top() )
174 nRowOff
= aRect
.Top() - r
.Top();
176 if( r
.Left() > aRect
.Left() && r
.Top() > aRect
.Top() )
178 aFrom
= Rectangle( nCol
-1, lcl_hmm2px( nColOff
),
179 nRow
-1, lcl_hmm2px( nRowOff
) );
188 Rectangle r
= rRoot
.GetDocRef().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
189 if( r
.Left() >= aRect
.Left() )
192 nColOff
= r
.Left() - aRect
.Left();
194 if( r
.Top() <= aRect
.Top() )
197 nRowOff
= aRect
.Top() - r
.Top();
199 if( r
.Left() < aRect
.Left() && r
.Top() > aRect
.Top() )
201 aFrom
= Rectangle( nCol
-1, lcl_hmm2px( nColOff
),
202 nRow
-1, lcl_hmm2px( nRowOff
) );
211 Rectangle r
= rRoot
.GetDocRef().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
212 if( r
.Right() < aRect
.Right() )
214 if( r
.Bottom() < aRect
.Bottom() )
216 if( r
.Right() >= aRect
.Right() && r
.Bottom() >= aRect
.Bottom() )
218 aTo
= Rectangle( nCol
, lcl_hmm2px( aRect
.Right() - r
.Left() ),
219 nRow
, lcl_hmm2px( aRect
.Bottom() - r
.Top() ));
228 Rectangle r
= rRoot
.GetDocRef().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
229 if( r
.Right() >= aRect
.Right() )
231 if( r
.Bottom() < aRect
.Bottom() )
233 if( r
.Right() < aRect
.Right() && r
.Bottom() >= aRect
.Bottom() )
235 aTo
= Rectangle( nCol
, lcl_hmm2px( r
.Left() - aRect
.Right() ),
236 nRow
, lcl_hmm2px( aRect
.Bottom() - r
.Top() ));
245 // Escher client anchor =======================================================
247 XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot
& rRoot
, sal_uInt16 nFlags
) :
253 void XclExpDffAnchorBase::SetFlags( const SdrObject
& rSdrObj
)
255 ImplSetFlags( rSdrObj
);
258 void XclExpDffAnchorBase::SetSdrObject( const SdrObject
& rSdrObj
)
260 ImplSetFlags( rSdrObj
);
261 ImplCalcAnchorRect( rSdrObj
.GetCurrentBoundRect(), MAP_100TH_MM
);
264 void XclExpDffAnchorBase::WriteDffData( EscherEx
& rEscherEx
) const
266 rEscherEx
.AddAtom( 18, ESCHER_ClientAnchor
);
267 rEscherEx
.GetStream().WriteUInt16( mnFlags
);
268 WriteXclObjAnchor( rEscherEx
.GetStream(), maAnchor
);
271 void XclExpDffAnchorBase::WriteData( EscherEx
& rEscherEx
, const Rectangle
& rRect
)
273 // the passed rectangle is in twips
274 ImplCalcAnchorRect( rRect
, MAP_TWIP
);
275 WriteDffData( rEscherEx
);
278 void XclExpDffAnchorBase::ImplSetFlags( const SdrObject
& )
280 OSL_FAIL( "XclExpDffAnchorBase::ImplSetFlags - not implemented" );
283 void XclExpDffAnchorBase::ImplCalcAnchorRect( const Rectangle
&, MapUnit
)
285 OSL_FAIL( "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" );
288 XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot
& rRoot
) :
289 XclExpDffAnchorBase( rRoot
),
290 mnScTab( rRoot
.GetCurrScTab() )
294 void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject
& rSdrObj
)
296 // set flags for cell/page anchoring
297 if ( ScDrawLayer::GetAnchorType( rSdrObj
) == SCA_CELL
)
300 mnFlags
= EXC_ESC_ANCHOR_LOCKED
;
303 void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle
& rRect
, MapUnit eMapUnit
)
305 maAnchor
.SetRect( GetRoot(), mnScTab
, rRect
, eMapUnit
);
308 XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot
& rRoot
,
309 const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
310 XclExpDffAnchorBase( rRoot
),
311 maPageSize( rPageSize
),
317 void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject
& /*rSdrObj*/ )
319 // TODO (unsupported feature): fixed size
322 void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle
& rRect
, MapUnit eMapUnit
)
324 maAnchor
.SetRect( maPageSize
, mnScaleX
, mnScaleY
, rRect
, eMapUnit
);
327 XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot
& rRoot
, const Rectangle
& rRect
) :
328 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_SIZELOCKED
)
330 maAnchor
.SetRect( rRoot
, rRoot
.GetCurrScTab(), rRect
, MAP_100TH_MM
);
333 XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
) :
334 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_POSLOCKED
)
336 GetAddressConverter().ConvertAddress( maAnchor
.maFirst
, rScPos
, true );
337 maAnchor
.maLast
.mnCol
= maAnchor
.maFirst
.mnCol
+ 1;
338 maAnchor
.maLast
.mnRow
= maAnchor
.maFirst
.mnRow
+ 1;
339 maAnchor
.mnLX
= maAnchor
.mnTY
= maAnchor
.mnRX
= maAnchor
.mnBY
= 0;
342 // MSODRAWING* records ========================================================
344 XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx
& rEscherEx
, sal_uInt16 nRecId
) :
345 XclExpRecord( nRecId
),
346 mrEscherEx( rEscherEx
),
347 mnFragmentKey( rEscherEx
.InitNextDffFragment() )
351 void XclExpMsoDrawingBase::WriteBody( XclExpStream
& rStrm
)
353 OSL_ENSURE( mrEscherEx
.GetStreamPos() == mrEscherEx
.GetDffFragmentPos( mnFragmentKey
),
354 "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" );
355 rStrm
.CopyFromStream( mrEscherEx
.GetStream(), mrEscherEx
.GetDffFragmentSize( mnFragmentKey
) );
358 XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx
& rEscherEx
) :
359 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWINGGROUP
)
361 SvStream
& rDffStrm
= mrEscherEx
.GetStream();
363 // write the DGGCONTAINER with some default settings
364 mrEscherEx
.OpenContainer( ESCHER_DggContainer
);
366 // TODO: stuff the OPT atom with our own document defaults?
367 static const sal_uInt8 spnDffOpt
[] = {
368 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
369 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
372 mrEscherEx
.AddAtom( sizeof( spnDffOpt
), ESCHER_OPT
, 3, 3 );
373 rDffStrm
.Write( spnDffOpt
, sizeof( spnDffOpt
) );
375 // SPLITMENUCOLORS contains colors in toolbar
376 static const sal_uInt8 spnDffSplitMenuColors
[] = {
377 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
378 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
380 mrEscherEx
.AddAtom( sizeof( spnDffSplitMenuColors
), ESCHER_SplitMenuColors
, 0, 4 );
381 rDffStrm
.Write( spnDffSplitMenuColors
, sizeof( spnDffSplitMenuColors
) );
383 // close the DGGCONTAINER
384 mrEscherEx
.CloseContainer();
385 mrEscherEx
.UpdateDffFragmentEnd();
388 XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx
& rEscherEx
) :
389 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWING
)
393 XclExpImgData::XclExpImgData( const Graphic
& rGraphic
, sal_uInt16 nRecId
) :
394 maGraphic( rGraphic
),
399 void XclExpImgData::Save( XclExpStream
& rStrm
)
401 Bitmap aBmp
= maGraphic
.GetBitmap();
402 if( aBmp
.GetBitCount() != 24 )
403 aBmp
.Convert( BMP_CONVERSION_24BIT
);
405 if( BitmapReadAccess
* pAccess
= aBmp
.AcquireReadAccess() )
407 sal_Int32 nWidth
= ::std::min
< sal_Int32
>( pAccess
->Width(), 0xFFFF );
408 sal_Int32 nHeight
= ::std::min
< sal_Int32
>( pAccess
->Height(), 0xFFFF );
409 if( (nWidth
> 0) && (nHeight
> 0) )
411 sal_uInt8 nPadding
= static_cast< sal_uInt8
>( nWidth
& 0x03 );
412 sal_uInt32 nTmpSize
= static_cast< sal_uInt32
>( (nWidth
* 3 + nPadding
) * nHeight
+ 12 );
414 rStrm
.StartRecord( mnRecId
, nTmpSize
+ 4 );
416 rStrm
<< EXC_IMGDATA_BMP
// BMP format
417 << EXC_IMGDATA_WIN
// Windows
418 << nTmpSize
// size after _this_ field
419 << sal_uInt32( 12 ) // BITMAPCOREHEADER size
420 << static_cast< sal_uInt16
>( nWidth
) // width
421 << static_cast< sal_uInt16
>( nHeight
) // height
422 << sal_uInt16( 1 ) // planes
423 << sal_uInt16( 24 ); // bits per pixel
425 for( sal_Int32 nY
= nHeight
- 1; nY
>= 0; --nY
)
427 for( sal_Int32 nX
= 0; nX
< nWidth
; ++nX
)
429 const BitmapColor
& rBmpColor
= pAccess
->GetPixel( nY
, nX
);
430 rStrm
<< rBmpColor
.GetBlue() << rBmpColor
.GetGreen() << rBmpColor
.GetRed();
432 rStrm
.WriteZeroBytes( nPadding
);
437 Bitmap::ReleaseAccess( pAccess
);
441 void XclExpImgData::SaveXml( XclExpXmlStream
& rStrm
)
443 sax_fastparser::FSHelperPtr pWorksheet
= rStrm
.GetCurrentStream();
445 DrawingML
aDML(pWorksheet
, &rStrm
, drawingml::DOCUMENT_XLSX
);
446 OUString rId
= aDML
.WriteImage( maGraphic
);
447 pWorksheet
->singleElement( XML_picture
,
448 FSNS( XML_r
, XML_id
), XclXmlUtils::ToOString( rId
).getStr(),
452 XclExpControlHelper::XclExpControlHelper( const XclExpRoot
& rRoot
) :
458 XclExpControlHelper::~XclExpControlHelper()
462 void XclExpControlHelper::ConvertSheetLinks( Reference
< XShape
> xShape
)
469 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( xShape
);
470 if( !xCtrlModel
.is() )
473 // *** cell link *** ------------------------------------------------------
475 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY
);
478 Reference
< XServiceInfo
> xServInfo( xBindable
->getValueBinding(), UNO_QUERY
);
479 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_VALBIND
) )
481 ScfPropertySet
aBindProp( xServInfo
);
482 CellAddress aApiAddress
;
483 if( aBindProp
.GetProperty( aApiAddress
, SC_UNONAME_BOUNDCELL
) )
486 ScUnoConversion::FillScAddress( aCellLink
, aApiAddress
);
487 if( GetTabInfo().IsExportTab( aCellLink
.Tab() ) )
488 mxCellLink
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aCellLink
);
493 // *** source range *** ---------------------------------------------------
495 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY
);
496 if( xEntrySink
.is() )
498 Reference
< XServiceInfo
> xServInfo( xEntrySink
->getListEntrySource(), UNO_QUERY
);
499 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_LISTSOURCE
) )
501 ScfPropertySet
aSinkProp( xServInfo
);
502 CellRangeAddress aApiRange
;
503 if( aSinkProp
.GetProperty( aApiRange
, SC_UNONAME_CELLRANGE
) )
506 ScUnoConversion::FillScRange( aSrcRange
, aApiRange
);
507 if( (aSrcRange
.aStart
.Tab() == aSrcRange
.aEnd
.Tab()) && GetTabInfo().IsExportTab( aSrcRange
.aStart
.Tab() ) )
508 mxSrcRange
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aSrcRange
);
509 mnEntryCount
= static_cast< sal_uInt16
>( aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1 );
515 void XclExpControlHelper::WriteFormula( XclExpStream
& rStrm
, const XclTokenArray
& rTokArr
)
517 sal_uInt16 nFmlaSize
= rTokArr
.GetSize();
518 rStrm
<< nFmlaSize
<< sal_uInt32( 0 );
519 rTokArr
.WriteArray( rStrm
);
520 if( nFmlaSize
& 1 ) // pad to 16-bit
521 rStrm
<< sal_uInt8( 0 );
524 void XclExpControlHelper::WriteFormulaSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
, const XclTokenArray
& rTokArr
)
526 rStrm
.StartRecord( nSubRecId
, (rTokArr
.GetSize() + 5) & ~1 );
527 WriteFormula( rStrm
, rTokArr
);
531 //delete for exporting OCX
532 //#if EXC_EXP_OCX_CTRL
534 XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> xShape
,
535 const Rectangle
* pChildAnchor
, const OUString
& rClassName
, sal_uInt32 nStrmStart
, sal_uInt32 nStrmSize
) :
536 XclObj( rObjMgr
, EXC_OBJTYPE_PICTURE
, true ),
537 XclExpControlHelper( rObjMgr
.GetRoot() ),
538 maClassName( rClassName
),
539 mnStrmStart( nStrmStart
),
540 mnStrmSize( nStrmSize
)
542 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
546 SetPrintable( aCtrlProp
.GetBoolProperty( "Printable" ) );
547 SetAutoFill( false );
548 SetAutoLine( false );
550 // fill DFF property set
551 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
552 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVESPT
| SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_OLESHAPE
);
553 Rectangle aDummyRect
;
554 EscherPropertyContainer
aPropOpt( mrEscherEx
.GetGraphicProvider(), mrEscherEx
.QueryPictureStream(), aDummyRect
);
555 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 ); // bool field
556 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x08000040 );
557 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
559 // #i51348# name of the control, may overwrite shape name
561 if( aCtrlProp
.GetProperty( aCtrlName
, "Name" ) && !aCtrlName
.isEmpty() )
562 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
566 Reference
< XPropertySet
> xShapePS( xShape
, UNO_QUERY
);
567 if( xShapePS
.is() && aPropOpt
.CreateGraphicProperties( xShapePS
, "MetaFile", false ) )
570 if( aPropOpt
.GetOpt( ESCHER_Prop_pib
, nBlipId
) )
571 aPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nBlipId
);
574 // write DFF property set to stream
575 aPropOpt
.Commit( mrEscherEx
.GetStream() );
578 ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
580 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
581 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
582 mrEscherEx
.UpdateDffFragmentEnd();
585 ConvertSheetLinks( xShape
);
588 void XclExpOcxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
590 // OBJCF - clipboard format
591 rStrm
.StartRecord( EXC_ID_OBJCF
, 2 );
592 rStrm
<< sal_uInt16( 2 );
596 rStrm
.StartRecord( EXC_ID_OBJFLAGS
, 2 );
597 rStrm
<< sal_uInt16( 0x0031 );
601 XclExpString
aClass( maClassName
);
602 sal_uInt16 nClassNameSize
= static_cast< sal_uInt16
>( aClass
.GetSize() );
603 sal_uInt16 nClassNamePad
= nClassNameSize
& 1;
604 sal_uInt16 nFirstPartSize
= 12 + nClassNameSize
+ nClassNamePad
;
606 const XclTokenArray
* pCellLink
= GetCellLinkTokArr();
607 sal_uInt16 nCellLinkSize
= pCellLink
? ((pCellLink
->GetSize() + 7) & 0xFFFE) : 0;
609 const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr();
610 sal_uInt16 nSrcRangeSize
= pSrcRange
? ((pSrcRange
->GetSize() + 7) & 0xFFFE) : 0;
612 sal_uInt16 nPictFmlaSize
= nFirstPartSize
+ nCellLinkSize
+ nSrcRangeSize
+ 18;
613 rStrm
.StartRecord( EXC_ID_OBJPICTFMLA
, nPictFmlaSize
);
615 rStrm
<< sal_uInt16( nFirstPartSize
) // size of first part
616 << sal_uInt16( 5 ) // formula size
617 << sal_uInt32( 0 ) // unknown ID
618 << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
619 << sal_uInt8( 3 ) // pad to word
620 << aClass
; // "Forms.***.1"
621 rStrm
.WriteZeroBytes( nClassNamePad
); // pad to word
622 rStrm
<< mnStrmStart
// start in 'Ctls' stream
623 << mnStrmSize
// size in 'Ctls' stream
624 << sal_uInt32( 0 ); // class ID size
626 rStrm
<< nCellLinkSize
;
628 WriteFormula( rStrm
, *pCellLink
);
630 rStrm
<< nSrcRangeSize
;
632 WriteFormula( rStrm
, *pSrcRange
);
639 XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager
& rRoot
, Reference
< XShape
> xShape
, const Rectangle
* pChildAnchor
) :
640 XclObj( rRoot
, EXC_OBJTYPE_UNKNOWN
, true ),
641 XclMacroHelper( rRoot
),
642 meEventType( EXC_TBX_EVENT_ACTION
),
652 mbFlatButton( false ),
653 mbFlatBorder( false ),
657 namespace FormCompType
= css::form::FormComponentType
;
658 namespace AwtVisualEffect
= css::awt::VisualEffect
;
659 namespace AwtScrollOrient
= css::awt::ScrollBarOrientation
;
661 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
662 if( !xShape
.is() || !aCtrlProp
.Is() )
665 mnHeight
= xShape
->getSize().Height
;
670 sal_Int16 nClassId
= 0;
671 if( aCtrlProp
.GetProperty( nClassId
, "ClassId" ) )
675 case FormCompType::COMMANDBUTTON
: mnObjType
= EXC_OBJTYPE_BUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
676 case FormCompType::RADIOBUTTON
: mnObjType
= EXC_OBJTYPE_OPTIONBUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
677 case FormCompType::CHECKBOX
: mnObjType
= EXC_OBJTYPE_CHECKBOX
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
678 case FormCompType::LISTBOX
: mnObjType
= EXC_OBJTYPE_LISTBOX
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
679 case FormCompType::COMBOBOX
: mnObjType
= EXC_OBJTYPE_DROPDOWN
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
680 case FormCompType::GROUPBOX
: mnObjType
= EXC_OBJTYPE_GROUPBOX
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
681 case FormCompType::FIXEDTEXT
: mnObjType
= EXC_OBJTYPE_LABEL
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
682 case FormCompType::SCROLLBAR
: mnObjType
= EXC_OBJTYPE_SCROLLBAR
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
683 case FormCompType::SPINBUTTON
: mnObjType
= EXC_OBJTYPE_SPIN
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
686 if( mnObjType
== EXC_OBJTYPE_UNKNOWN
)
691 SetPrintable( aCtrlProp
.GetBoolProperty( "Printable" ) );
692 SetAutoFill( false );
693 SetAutoLine( false );
695 // fill DFF property set
696 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
697 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_HAVESPT
);
698 EscherPropertyContainer aPropOpt
;
699 bool bVisible
= aCtrlProp
.GetBoolProperty( "EnableVisible" );
700 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, bVisible
? 0x00080000 : 0x00080002 ); // visible flag
702 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01000100 ); // bool field
703 aPropOpt
.AddOpt( ESCHER_Prop_lTxid
, 0 ); // Text ID
704 aPropOpt
.AddOpt( ESCHER_Prop_WrapText
, 0x00000001 );
705 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x001A0008 ); // bool field
706 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00100000 ); // bool field
707 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
709 // #i51348# name of the control, may overwrite shape name
711 if( aCtrlProp
.GetProperty( aCtrlName
, "Name" ) && !aCtrlName
.isEmpty() )
712 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
714 //Export description as alt text
715 if( SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
) )
718 OUString aDescrText
= pSdrObj
->GetDescription();
719 if(!aDescrText
.isEmpty())
720 aAltTxt
= aDescrText
.copy( 0, std::min
<sal_Int32
>(MSPROP_DESCRIPTION_MAX_LEN
, aDescrText
.getLength()) );
721 aPropOpt
.AddOpt( ESCHER_Prop_wzDescription
, aAltTxt
);
724 // write DFF property set to stream
725 aPropOpt
.Commit( mrEscherEx
.GetStream() );
728 ImplWriteAnchor( GetRoot(), SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
730 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
731 mrEscherEx
.UpdateDffFragmentEnd();
735 if( aCtrlProp
.GetProperty( aString
, "Label" ) )
737 /* Be sure to construct the MSODRAWING record containing the
738 ClientTextbox atom after the base OBJ's MSODRAWING record data is
740 pClientTextbox
= new XclExpMsoDrawing( mrEscherEx
);
741 mrEscherEx
.AddAtom( 0, ESCHER_ClientTextbox
); // TXO record
742 mrEscherEx
.UpdateDffFragmentEnd();
744 sal_uInt16 nXclFont
= EXC_FONT_APP
;
745 if( !aString
.isEmpty() )
747 XclFontData aFontData
;
748 GetFontPropSetHelper().ReadFontProperties( aFontData
, aCtrlProp
, EXC_FONTPROPSET_CONTROL
);
749 if( (!aFontData
.maName
.isEmpty() ) && (aFontData
.mnHeight
> 0) )
750 nXclFont
= GetFontBuffer().Insert( aFontData
, EXC_COLOR_CTRLTEXT
);
753 pTxo
= new XclTxo( aString
, nXclFont
);
754 pTxo
->SetHorAlign( (mnObjType
== EXC_OBJTYPE_BUTTON
) ? EXC_OBJ_HOR_CENTER
: EXC_OBJ_HOR_LEFT
);
755 pTxo
->SetVerAlign( EXC_OBJ_VER_CENTER
);
758 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
761 aCtrlProp
.GetProperty( mnLineCount
, "LineCount" );
764 sal_Int16 nApiButton
= AwtVisualEffect::LOOK3D
;
765 sal_Int16 nApiBorder
= AwtVisualEffect::LOOK3D
;
768 case FormCompType::LISTBOX
:
769 case FormCompType::COMBOBOX
:
770 aCtrlProp
.GetProperty( nApiBorder
, "Border" );
772 case FormCompType::CHECKBOX
:
773 case FormCompType::RADIOBUTTON
:
774 aCtrlProp
.GetProperty( nApiButton
, "VisualEffect" );
775 nApiBorder
= AwtVisualEffect::NONE
;
777 // Push button cannot be set to flat in Excel
778 case FormCompType::COMMANDBUTTON
:
779 nApiBorder
= AwtVisualEffect::LOOK3D
;
781 // Label does not support a border in Excel
782 case FormCompType::FIXEDTEXT
:
783 nApiBorder
= AwtVisualEffect::NONE
;
785 /* Scroll bar and spin button have a "Border" property, but it is
786 really used for a border, and not for own 3D/flat look (#i34712#). */
787 case FormCompType::SCROLLBAR
:
788 case FormCompType::SPINBUTTON
:
789 nApiButton
= AwtVisualEffect::LOOK3D
;
790 nApiBorder
= AwtVisualEffect::NONE
;
792 // Group box does not support flat style (#i34712#)
793 case FormCompType::GROUPBOX
:
794 nApiBorder
= AwtVisualEffect::LOOK3D
;
797 mbFlatButton
= nApiButton
!= AwtVisualEffect::LOOK3D
;
798 mbFlatBorder
= nApiBorder
!= AwtVisualEffect::LOOK3D
;
801 sal_Int16 nApiState
= 0;
802 if( aCtrlProp
.GetProperty( nApiState
, "State" ) )
806 case 0: mnState
= EXC_OBJ_CHECKBOX_UNCHECKED
; break;
807 case 1: mnState
= EXC_OBJ_CHECKBOX_CHECKED
; break;
808 case 2: mnState
= EXC_OBJ_CHECKBOX_TRISTATE
; break;
812 // special control contents
815 case FormCompType::LISTBOX
:
817 mbMultiSel
= aCtrlProp
.GetBoolProperty( "MultiSelection" );
818 Sequence
< sal_Int16
> aSelection
;
819 if( aCtrlProp
.GetProperty( aSelection
, "SelectedItems" ) )
821 sal_Int32 nLen
= aSelection
.getLength();
824 mnSelEntry
= aSelection
[ 0 ] + 1;
825 maMultiSel
.resize( nLen
);
826 const sal_Int16
* pnBegin
= aSelection
.getConstArray();
827 ::std::copy( pnBegin
, pnBegin
+ nLen
, maMultiSel
.begin() );
831 // convert listbox with dropdown button to Excel dropdown
832 if( aCtrlProp
.GetBoolProperty( "Dropdown" ) )
833 mnObjType
= EXC_OBJTYPE_DROPDOWN
;
837 case FormCompType::COMBOBOX
:
839 Sequence
< OUString
> aStringList
;
841 if( aCtrlProp
.GetProperty( aStringList
, "StringItemList" ) &&
842 aCtrlProp
.GetProperty( aDefText
, "Text" ) &&
843 aStringList
.getLength() && !aDefText
.isEmpty() )
845 const OUString
* pBegin
= aStringList
.getConstArray();
846 const OUString
* pEnd
= pBegin
+ aStringList
.getLength();
847 const OUString
* pString
= ::std::find( pBegin
, pEnd
, aDefText
);
848 if( pString
!= pEnd
)
849 mnSelEntry
= static_cast< sal_Int16
>( pString
- pBegin
+ 1 ); // 1-based
851 maMultiSel
.resize( 1, mnSelEntry
- 1 );
854 // convert combobox without dropdown button to Excel listbox
855 if( !aCtrlProp
.GetBoolProperty( "Dropdown" ) )
856 mnObjType
= EXC_OBJTYPE_LISTBOX
;
860 case FormCompType::SCROLLBAR
:
862 sal_Int32 nApiValue
= 0;
863 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMin" ) )
864 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
865 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMax" ) )
866 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MIN
);
867 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValue" ) )
868 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
869 if( aCtrlProp
.GetProperty( nApiValue
, "LineIncrement" ) )
870 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
871 if( aCtrlProp
.GetProperty( nApiValue
, "BlockIncrement" ) )
872 mnScrollPage
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
873 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
874 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
878 case FormCompType::SPINBUTTON
:
880 sal_Int32 nApiValue
= 0;
881 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMin" ) )
882 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
883 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMax" ) )
884 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MAX
);
885 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValue" ) )
886 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
887 if( aCtrlProp
.GetProperty( nApiValue
, "SpinIncrement" ) )
888 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
889 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
890 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
896 ConvertSheetLinks( xShape
);
899 bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor
& rEvent
)
901 return XclMacroHelper::SetMacroLink( rEvent
, meEventType
);
904 void XclExpTbxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
908 // *** Push buttons, labels ***
910 case EXC_OBJTYPE_BUTTON
:
911 case EXC_OBJTYPE_LABEL
:
912 // ftMacro - macro link
913 WriteMacroSubRec( rStrm
);
916 // *** Check boxes, option buttons ***
918 case EXC_OBJTYPE_CHECKBOX
:
919 case EXC_OBJTYPE_OPTIONBUTTON
:
921 // ftCbls - box properties
922 sal_uInt16 nStyle
= 0;
923 ::set_flag( nStyle
, EXC_OBJ_CHECKBOX_FLAT
, mbFlatButton
);
925 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 12 );
927 rStrm
.WriteZeroBytes( 8 );
931 // ftMacro - macro link
932 WriteMacroSubRec( rStrm
);
933 // ftCblsFmla subrecord - cell link
934 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJCBLSFMLA
);
936 // ftCblsData subrecord - box properties, again
937 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 8 );
939 rStrm
.WriteZeroBytes( 4 );
945 // *** List boxes, combo boxes ***
947 case EXC_OBJTYPE_LISTBOX
:
948 case EXC_OBJTYPE_DROPDOWN
:
950 sal_uInt16 nEntryCount
= GetSourceEntryCount();
952 // ftSbs subrecord - Scroll bars
953 sal_Int32 nLineHeight
= XclTools::GetHmmFromTwips( 200 ); // always 10pt
954 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
955 mnLineCount
= static_cast< sal_uInt16
>( mnHeight
/ nLineHeight
);
958 sal_uInt16 nInvisLines
= (nEntryCount
>= mnLineCount
) ? (nEntryCount
- mnLineCount
) : 0;
959 mnScrollMax
= limit_cast
< sal_uInt16
>( nInvisLines
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
961 mnScrollPage
= limit_cast
< sal_uInt16
>( mnLineCount
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
965 // ftMacro - macro link
966 WriteMacroSubRec( rStrm
);
967 // ftSbsFmla subrecord - cell link
968 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
970 // ftLbsData - source data range and box properties
971 sal_uInt16 nStyle
= 0;
972 ::insert_value( nStyle
, mbMultiSel
? EXC_OBJ_LISTBOX_MULTI
: EXC_OBJ_LISTBOX_SINGLE
, 4, 2 );
973 ::set_flag( nStyle
, EXC_OBJ_LISTBOX_FLAT
, mbFlatBorder
);
975 rStrm
.StartRecord( EXC_ID_OBJLBSDATA
, 0 );
977 if( const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr() )
979 rStrm
<< static_cast< sal_uInt16
>( (pSrcRange
->GetSize() + 7) & 0xFFFE );
980 WriteFormula( rStrm
, *pSrcRange
);
983 rStrm
<< sal_uInt16( 0 );
985 rStrm
<< nEntryCount
<< mnSelEntry
<< nStyle
<< sal_uInt16( 0 );
986 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
990 ScfUInt8Vec
aSelEx( nEntryCount
, 0 );
991 for( ScfInt16Vec::const_iterator aIt
= maMultiSel
.begin(), aEnd
= maMultiSel
.end(); aIt
!= aEnd
; ++aIt
)
992 if( *aIt
< nEntryCount
)
994 rStrm
.Write( &aSelEx
[ 0 ], aSelEx
.size() );
997 else if( mnObjType
== EXC_OBJTYPE_DROPDOWN
)
999 rStrm
<< sal_uInt16( 0 ) << mnLineCount
<< sal_uInt16( 0 ) << sal_uInt16( 0 );
1006 // *** Spin buttons, scrollbars ***
1008 case EXC_OBJTYPE_SPIN
:
1009 case EXC_OBJTYPE_SCROLLBAR
:
1011 // ftSbs subrecord - scroll bars
1013 // ftMacro - macro link
1014 WriteMacroSubRec( rStrm
);
1015 // ftSbsFmla subrecord - cell link
1016 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
1020 // *** Group boxes ***
1022 case EXC_OBJTYPE_GROUPBOX
:
1024 // ftMacro - macro link
1025 WriteMacroSubRec( rStrm
);
1027 // ftGboData subrecord - group box properties
1028 sal_uInt16 nStyle
= 0;
1029 ::set_flag( nStyle
, EXC_OBJ_GROUPBOX_FLAT
, mbFlatBorder
);
1031 rStrm
.StartRecord( EXC_ID_OBJGBODATA
, 6 );
1032 rStrm
<< sal_uInt32( 0 )
1040 void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
)
1042 if( const XclTokenArray
* pCellLink
= GetCellLinkTokArr() )
1043 WriteFormulaSubRec( rStrm
, nSubRecId
, *pCellLink
);
1046 void XclExpTbxControlObj::WriteSbs( XclExpStream
& rStrm
)
1048 sal_uInt16 nOrient
= 0;
1049 ::set_flag( nOrient
, EXC_OBJ_SCROLLBAR_HOR
, mbScrollHor
);
1050 sal_uInt16 nStyle
= EXC_OBJ_SCROLLBAR_DEFFLAGS
;
1051 ::set_flag( nStyle
, EXC_OBJ_SCROLLBAR_FLAT
, mbFlatButton
);
1053 rStrm
.StartRecord( EXC_ID_OBJSBS
, 20 );
1054 rStrm
<< sal_uInt32( 0 ) // reserved
1055 << mnScrollValue
// thumb position
1056 << mnScrollMin
// thumb min pos
1057 << mnScrollMax
// thumb max pos
1058 << mnScrollStep
// line increment
1059 << mnScrollPage
// page increment
1060 << nOrient
// 0 = vertical, 1 = horizontal
1061 << sal_uInt16( 15 ) // thumb width
1062 << nStyle
; // flags/style
1068 XclExpChartObj::XclExpChartObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> xShape
, const Rectangle
* pChildAnchor
) :
1069 XclObj( rObjMgr
, EXC_OBJTYPE_CHART
),
1070 XclExpRoot( rObjMgr
.GetRoot() ), mxShape( xShape
)
1072 // create the MSODRAWING record contents for the chart object
1073 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
1074 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_HAVESPT
);
1075 EscherPropertyContainer aPropOpt
;
1076 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01040104 );
1077 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 );
1078 aPropOpt
.AddOpt( ESCHER_Prop_fillColor
, 0x0800004E );
1079 aPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0x0800004D );
1080 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00110010 );
1081 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x0800004D );
1082 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
1083 aPropOpt
.AddOpt( ESCHER_Prop_fshadowObscured
, 0x00020000 );
1084 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x00080000 );
1085 aPropOpt
.Commit( mrEscherEx
.GetStream() );
1088 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
);
1089 ImplWriteAnchor( GetRoot(), pSdrObj
, pChildAnchor
);
1091 // client data (the following OBJ record)
1092 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
);
1093 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
1094 mrEscherEx
.UpdateDffFragmentEnd();
1096 // load the chart OLE object
1097 if( SdrOle2Obj
* pSdrOleObj
= dynamic_cast< SdrOle2Obj
* >( pSdrObj
) )
1098 svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj
->GetObjRef() );
1100 // create the chart substream object
1101 ScfPropertySet
aShapeProp( xShape
);
1102 Reference
< XModel
> xModel
;
1103 aShapeProp
.GetProperty( xModel
, "Model" );
1104 mxChartDoc
.set( xModel
,UNO_QUERY
);
1105 css::awt::Rectangle aBoundRect
;
1106 aShapeProp
.GetProperty( aBoundRect
, "BoundRect" );
1107 Rectangle
aChartRect( Point( aBoundRect
.X
, aBoundRect
.Y
), Size( aBoundRect
.Width
, aBoundRect
.Height
) );
1108 mxChart
.reset( new XclExpChart( GetRoot(), xModel
, aChartRect
) );
1111 XclExpChartObj::~XclExpChartObj()
1115 void XclExpChartObj::Save( XclExpStream
& rStrm
)
1117 // content of OBJ record
1118 XclObj::Save( rStrm
);
1120 mxChart
->Save( rStrm
);
1123 void XclExpChartObj::SaveXml( XclExpXmlStream
& rStrm
)
1125 OSL_TRACE("XclExpChartObj::SaveXml -- Entry point to export chart");
1126 sax_fastparser::FSHelperPtr pDrawing
= rStrm
.GetCurrentStream();
1128 // FIXME: two cell? it seems the two cell anchor is incorrect.
1129 pDrawing
->startElement( FSNS( XML_xdr
, XML_twoCellAnchor
), // OOXTODO: oneCellAnchor, absoluteAnchor
1130 XML_editAs
, "oneCell",
1132 Reference
< XPropertySet
> xPropSet( mxShape
, UNO_QUERY
);
1135 XclObjAny::WriteFromTo( rStrm
, mxShape
, GetTab() );
1136 Reference
< XModel
> xModel( mxChartDoc
, UNO_QUERY
);
1137 ChartExport
aChartExport(XML_xdr
, pDrawing
, xModel
, &rStrm
, drawingml::DOCUMENT_XLSX
);
1138 static sal_Int32 nChartCount
= 0;
1140 aChartExport
.WriteChartObj( mxShape
, nChartCount
);
1141 // TODO: get the correcto chart number
1144 pDrawing
->singleElement( FSNS( XML_xdr
, XML_clientData
),
1145 // OOXTODO: XML_fLocksWithSheet
1146 // OOXTODO: XML_fPrintsWithSheet
1148 pDrawing
->endElement( FSNS( XML_xdr
, XML_twoCellAnchor
) );
1151 const css::uno::Reference
<css::chart::XChartDocument
>& XclExpChartObj::GetChartDoc() const
1156 XclExpNote::XclExpNote( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
,
1157 const ScPostIt
* pScNote
, const OUString
& rAddText
) :
1158 XclExpRecord( EXC_ID_NOTE
),
1160 mnObjId( EXC_OBJ_INVALID_ID
),
1161 mbVisible( pScNote
&& pScNote
->IsCaptionShown() )
1163 // get the main note text
1167 aNoteText
= pScNote
->GetText();
1168 const EditTextObject
*pEditObj
= pScNote
->GetEditTextObject();
1170 mpNoteContents
= XclExpStringHelper::CreateString( rRoot
, *pEditObj
);
1172 // append additional text
1173 aNoteText
= ScGlobal::addToken( aNoteText
, rAddText
, '\n', 2 );
1174 maOrigNoteText
= aNoteText
;
1176 // initialize record dependent on BIFF type
1177 switch( rRoot
.GetBiff() )
1180 maNoteText
= OUStringToOString(aNoteText
, rRoot
.GetTextEncoding());
1185 // TODO: additional text
1187 if( SdrCaptionObj
* pCaption
= pScNote
->GetOrCreateCaption( maScPos
) )
1189 lcl_GetFromTo( rRoot
, pCaption
->GetLogicRect(), maScPos
.Tab(), maCommentFrom
, maCommentTo
);
1190 if( const OutlinerParaObject
* pOPO
= pCaption
->GetOutlinerParaObject() )
1191 mnObjId
= rRoot
.GetObjectManager().AddObj( new XclObjComment( rRoot
.GetObjectManager(), pCaption
->GetLogicRect(), pOPO
->GetTextObject(), pCaption
, mbVisible
, maScPos
, maCommentFrom
, maCommentTo
) );
1193 SfxItemSet aItemSet
= pCaption
->GetMergedItemSet();
1194 meTVA
= pCaption
->GetTextVerticalAdjust();
1195 meTHA
= pCaption
->GetTextHorizontalAdjust();
1196 mbAutoScale
= pCaption
->GetFitToSize() != SDRTEXTFIT_NONE
;
1197 mbLocked
= pCaption
->IsMoveProtect() || pCaption
->IsResizeProtect();
1199 // AutoFill style would change if Postit.cxx object creation values are changed
1200 OUString
aCol(((XFillColorItem
&)GETITEM(aItemSet
, XFillColorItem
, XATTR_FILLCOLOR
)).GetValue());
1201 mbAutoFill
= aCol
.isEmpty() && (GETITEMVALUE(aItemSet
, XFillStyleItem
, XATTR_FILLSTYLE
, sal_uLong
) == drawing::FillStyle_SOLID
);
1203 mbRowHidden
= (rRoot
.GetDoc().RowHidden(maScPos
.Row(),maScPos
.Tab()));
1204 mbColHidden
= (rRoot
.GetDoc().ColHidden(maScPos
.Col(),maScPos
.Tab()));
1207 SetRecSize( 9 + maAuthor
.GetSize() );
1211 default: DBG_ERROR_BIFF();
1215 void XclExpNote::Save( XclExpStream
& rStrm
)
1217 switch( rStrm
.GetRoot().GetBiff() )
1221 // write the NOTE record directly, there may be the need to create more than one
1222 const sal_Char
* pcBuffer
= maNoteText
.getStr();
1223 sal_uInt16 nCharsLeft
= static_cast< sal_uInt16
>( maNoteText
.getLength() );
1227 sal_uInt16 nWriteChars
= ::std::min( nCharsLeft
, EXC_NOTE5_MAXLEN
);
1229 rStrm
.StartRecord( EXC_ID_NOTE
, 6 + nWriteChars
);
1230 if( pcBuffer
== maNoteText
.getStr() )
1232 // first record: row, col, length of complete text
1233 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1234 << static_cast< sal_uInt16
>( maScPos
.Col() )
1235 << nCharsLeft
; // still contains full length
1239 // next records: -1, 0, length of current text segment
1240 rStrm
<< sal_uInt16( 0xFFFF )
1244 rStrm
.Write( pcBuffer
, nWriteChars
);
1247 pcBuffer
+= nWriteChars
;
1248 nCharsLeft
= nCharsLeft
- nWriteChars
;
1254 if( mnObjId
!= EXC_OBJ_INVALID_ID
)
1255 XclExpRecord::Save( rStrm
);
1258 default: DBG_ERROR_BIFF();
1262 void XclExpNote::WriteBody( XclExpStream
& rStrm
)
1264 // BIFF5/BIFF7 is written separately
1265 OSL_ENSURE_BIFF( rStrm
.GetRoot().GetBiff() == EXC_BIFF8
);
1267 sal_uInt16 nFlags
= 0;
1268 ::set_flag( nFlags
, EXC_NOTE_VISIBLE
, mbVisible
);
1270 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1271 << static_cast< sal_uInt16
>( maScPos
.Col() )
1278 void XclExpNote::WriteXml( sal_Int32 nAuthorId
, XclExpXmlStream
& rStrm
)
1280 sax_fastparser::FSHelperPtr rComments
= rStrm
.GetCurrentStream();
1282 rComments
->startElement( XML_comment
,
1283 XML_ref
, XclXmlUtils::ToOString( maScPos
).getStr(),
1284 XML_authorId
, OString::number( nAuthorId
).getStr(),
1285 // OOXTODO: XML_guid,
1287 rComments
->startElement( XML_text
, FSEND
);
1288 // OOXTODO: phoneticPr, rPh, r
1289 if( mpNoteContents
)
1290 mpNoteContents
->WriteXml( rStrm
);
1291 rComments
->endElement( XML_text
);
1294 Export of commentPr is disabled, since the current (Oct 2010)
1295 version of MSO 2010 doesn't yet support commentPr
1297 #if 1//def XLSX_OOXML_FUTURE
1298 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1300 rComments
->startElement( FSNS( XML_mc
, XML_AlternateContent
), FSEND
);
1301 rComments
->startElement( FSNS( XML_mc
, XML_Choice
), XML_Requires
, "v2", FSEND
);
1302 rComments
->startElement( XML_commentPr
,
1303 XML_autoFill
, XclXmlUtils::ToPsz( mbAutoFill
),
1304 XML_autoScale
, XclXmlUtils::ToPsz( mbAutoScale
),
1305 XML_colHidden
, XclXmlUtils::ToPsz( mbColHidden
),
1306 XML_locked
, XclXmlUtils::ToPsz( mbLocked
),
1307 XML_rowHidden
, XclXmlUtils::ToPsz( mbRowHidden
),
1308 XML_textHAlign
, ToHorizAlign( meTHA
),
1309 XML_textVAlign
, ToVertAlign( meTVA
) ,
1311 rComments
->startElement( XML_anchor
,
1312 XML_moveWithCells
, "false",
1313 XML_sizeWithCells
, "false",
1315 rComments
->startElement( FSNS( XML_xdr
, XML_from
), FSEND
);
1316 lcl_WriteAnchorVertex( rComments
, maCommentFrom
);
1317 rComments
->endElement( FSNS( XML_xdr
, XML_from
) );
1318 rComments
->startElement( FSNS( XML_xdr
, XML_to
), FSEND
);
1319 lcl_WriteAnchorVertex( rComments
, maCommentTo
);
1320 rComments
->endElement( FSNS( XML_xdr
, XML_to
) );
1321 rComments
->endElement( XML_anchor
);
1322 rComments
->endElement( XML_commentPr
);
1324 rComments
->endElement( FSNS( XML_mc
, XML_Choice
) );
1325 rComments
->startElement( FSNS( XML_mc
, XML_Fallback
), FSEND
);
1326 // Any fallback code ?
1327 rComments
->endElement( FSNS( XML_mc
, XML_Fallback
) );
1328 rComments
->endElement( FSNS( XML_mc
, XML_AlternateContent
) );
1331 rComments
->endElement( XML_comment
);
1334 XclMacroHelper::XclMacroHelper( const XclExpRoot
& rRoot
) :
1335 XclExpControlHelper( rRoot
)
1339 XclMacroHelper::~XclMacroHelper()
1343 void XclMacroHelper::WriteMacroSubRec( XclExpStream
& rStrm
)
1346 WriteFormulaSubRec( rStrm
, EXC_ID_OBJMACRO
, *mxMacroLink
);
1350 XclMacroHelper::SetMacroLink( const ScriptEventDescriptor
& rEvent
, const XclTbxEventType
& nEventType
)
1352 OUString aMacroName
= XclControlHelper::ExtractFromMacroDescriptor( rEvent
, nEventType
, GetDocShell() );
1353 if( !aMacroName
.isEmpty() )
1355 return SetMacroLink( aMacroName
);
1361 XclMacroHelper::SetMacroLink( const OUString
& rMacroName
)
1363 OSL_TRACE("SetMacroLink( macroname:=%s )", OUStringToOString( rMacroName
, RTL_TEXTENCODING_UTF8
).getStr() );
1364 if( !rMacroName
.isEmpty() )
1366 sal_uInt16 nExtSheet
= GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC
);
1367 sal_uInt16 nNameIdx
= GetNameManager().InsertMacroCall( rMacroName
, true, false );
1368 mxMacroLink
= GetFormulaCompiler().CreateNameXFormula( nExtSheet
, nNameIdx
);
1374 XclExpShapeObj::XclExpShapeObj( XclExpObjectManager
& rRoot
, css::uno::Reference
< css::drawing::XShape
> xShape
, ScDocument
* pDoc
) :
1375 XclObjAny( rRoot
, xShape
, pDoc
),
1376 XclMacroHelper( rRoot
)
1378 if( SdrObject
* pSdrObj
= ::GetSdrObjectFromXShape( xShape
) )
1380 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pSdrObj
);
1381 if ( pInfo
&& !pInfo
->GetMacro().isEmpty() )
1382 // 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
1383 // SetMacroLink( XclControlHelper::GetXclMacroName( pInfo->GetMacro(), rRoot.GetDocShell() ) );
1384 SetMacroLink( XclTools::GetXclMacroName( pInfo
->GetMacro() ) );
1388 XclExpShapeObj::~XclExpShapeObj()
1392 void XclExpShapeObj::WriteSubRecs( XclExpStream
& rStrm
)
1394 XclObjAny::WriteSubRecs( rStrm
);
1395 WriteMacroSubRec( rStrm
);
1398 XclExpComments::XclExpComments( SCTAB nTab
, XclExpRecordList
< XclExpNote
>& rNotes
)
1399 : mnTab( nTab
), mrNotes( rNotes
)
1403 struct OUStringLess
: public std::binary_function
<OUString
, OUString
, bool>
1405 bool operator()(const OUString
& x
, const OUString
& y
) const
1407 return x
.compareTo( y
) < 0;
1411 void XclExpComments::SaveXml( XclExpXmlStream
& rStrm
)
1413 if( mrNotes
.IsEmpty() )
1416 sax_fastparser::FSHelperPtr rComments
= rStrm
.CreateOutputStream(
1417 XclXmlUtils::GetStreamName( "xl/", "comments", mnTab
+ 1 ),
1418 XclXmlUtils::GetStreamName( "../", "comments", mnTab
+ 1 ),
1419 rStrm
.GetCurrentStream()->getOutputStream(),
1420 "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
1421 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" );
1422 rStrm
.PushStream( rComments
);
1424 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1425 rComments
->startElement( XML_comments
,
1426 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1427 FSNS( XML_xmlns
, XML_mc
), "http://schemas.openxmlformats.org/markup-compatibility/2006",
1428 FSNS( XML_xmlns
, XML_xdr
), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
1429 FSNS( XML_xmlns
, XML_v2
), "http://schemas.openxmlformats.org/spreadsheetml/2006/main/v2",
1430 FSNS( XML_mc
, XML_Ignorable
), "v2",
1433 rComments
->startElement( XML_comments
,
1434 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1435 FSNS( XML_xmlns
, XML_xdr
), "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing",
1438 rComments
->startElement( XML_authors
, FSEND
);
1440 typedef std::set
< OUString
, OUStringLess
> Authors
;
1443 size_t nNotes
= mrNotes
.GetSize();
1444 for( size_t i
= 0; i
< nNotes
; ++i
)
1446 aAuthors
.insert( XclXmlUtils::ToOUString( mrNotes
.GetRecord( i
)->GetAuthor() ) );
1449 for( Authors::const_iterator b
= aAuthors
.begin(), e
= aAuthors
.end(); b
!= e
; ++b
)
1451 rComments
->startElement( XML_author
, FSEND
);
1452 rComments
->writeEscaped( *b
);
1453 rComments
->endElement( XML_author
);
1456 rComments
->endElement( XML_authors
);
1457 rComments
->startElement( XML_commentList
, FSEND
);
1459 Authors::const_iterator aAuthorsBegin
= aAuthors
.begin();
1460 for( size_t i
= 0; i
< nNotes
; ++i
)
1462 XclExpNoteList::RecordRefType xNote
= mrNotes
.GetRecord( i
);
1463 Authors::const_iterator aAuthor
= aAuthors
.find(
1464 XclXmlUtils::ToOUString( xNote
->GetAuthor() ) );
1465 sal_Int32 nAuthorId
= distance( aAuthorsBegin
, aAuthor
);
1466 xNote
->WriteXml( nAuthorId
, rStrm
);
1469 rComments
->endElement( XML_commentList
);
1470 rComments
->endElement( XML_comments
);
1475 // object manager =============================================================
1477 XclExpObjectManager::XclExpObjectManager( const XclExpRoot
& rRoot
) :
1481 mxEscherEx
.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm
) );
1484 XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager
& rParent
) :
1485 XclExpRoot( rParent
.GetRoot() )
1487 InitStream( false );
1488 mxEscherEx
.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm
, rParent
.mxEscherEx
.get() ) );
1491 XclExpObjectManager::~XclExpObjectManager()
1495 XclExpDffAnchorBase
* XclExpObjectManager::CreateDffAnchor() const
1497 return new XclExpDffSheetAnchor( GetRoot() );
1500 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::CreateDrawingGroup()
1502 return std::shared_ptr
< XclExpRecordBase
>( new XclExpMsoDrawingGroup( *mxEscherEx
) );
1505 void XclExpObjectManager::StartSheet()
1507 mxObjList
.reset( new XclExpObjList( GetRoot(), *mxEscherEx
) );
1510 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( SdrPage
* pSdrPage
)
1513 mxEscherEx
->AddSdrPage( *pSdrPage
);
1514 // the first dummy object may still be open
1515 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1516 while( mxEscherEx
->GetGroupLevel() )
1517 mxEscherEx
->LeaveGroup();
1518 mxObjList
->EndSheet();
1522 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( const Reference
< XShapes
>& rxShapes
)
1525 mxEscherEx
->AddUnoShapes( rxShapes
);
1526 // the first dummy object may still be open
1527 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1528 while( mxEscherEx
->GetGroupLevel() )
1529 mxEscherEx
->LeaveGroup();
1530 mxObjList
->EndSheet();
1534 void XclExpObjectManager::EndDocument()
1536 mxEscherEx
->EndDocument();
1539 XclExpMsoDrawing
* XclExpObjectManager::GetMsodrawingPerSheet()
1541 return mxObjList
->GetMsodrawingPerSheet();
1544 bool XclExpObjectManager::HasObj() const
1546 return !mxObjList
->empty();
1549 sal_uInt16
XclExpObjectManager::AddObj( XclObj
* pObjRec
)
1551 return mxObjList
->Add( pObjRec
);
1554 XclObj
* XclExpObjectManager::RemoveLastObj()
1556 XclObj
* pLastObj
= mxObjList
->back();
1557 mxObjList
->pop_back();
1561 void XclExpObjectManager::InitStream( bool bTempFile
)
1565 mxTempFile
.reset( new ::utl::TempFile
);
1566 if( mxTempFile
->IsValid() )
1568 mxTempFile
->EnableKillingFile();
1569 mxDffStrm
.reset( ::utl::UcbStreamHelper::CreateStream( mxTempFile
->GetURL(), STREAM_STD_READWRITE
) );
1573 if( !mxDffStrm
.get() )
1574 mxDffStrm
.reset( new SvMemoryStream
);
1576 mxDffStrm
->SetEndian( SvStreamEndian::LITTLE
);
1579 XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager(
1580 const XclExpObjectManager
& rParent
, const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
1581 XclExpObjectManager( rParent
),
1582 maPageSize( rPageSize
),
1583 mnScaleX( nScaleX
),
1588 XclExpDffAnchorBase
* XclExpEmbeddedObjectManager::CreateDffAnchor() const
1590 return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize
, mnScaleX
, mnScaleY
);
1593 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */