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/awt/Size.hpp>
31 #include <com/sun/star/chart/XChartDocument.hpp>
34 #include <vcl/bitmapaccess.hxx>
35 #include <svx/svdoole2.hxx>
36 #include <svx/svdocapt.hxx>
37 #include <editeng/outlobj.hxx>
38 #include <unotools/tempfile.hxx>
39 #include <unotools/ucbstreamhelper.hxx>
40 #include <svtools/embedhlp.hxx>
42 #include <unonames.hxx>
43 #include <convuno.hxx>
46 #include <fapihelper.hxx>
47 #include <xcl97esc.hxx>
48 #include <xechart.hxx>
49 #include <xeformula.hxx>
50 #include <xehelper.hxx>
53 #include <xestyle.hxx>
55 #include <xltools.hxx>
56 #include <userdat.hxx>
57 #include <drwlayer.hxx>
58 #include <svl/itemset.hxx>
59 #include <svx/unoapi.hxx>
60 #include <svx/sdtaitm.hxx>
61 #include <document.hxx>
62 #include <svx/xfillit0.hxx>
63 #include <svx/xflclit.hxx>
65 #include <comphelper/sequence.hxx>
66 #include <oox/token/tokens.hxx>
67 #include <oox/token/relationship.hxx>
68 #include <oox/export/drawingml.hxx>
69 #include <oox/export/chartexport.hxx>
70 #include <oox/export/utils.hxx>
71 #include <oox/token/namespaces.hxx>
74 using namespace com::sun::star
;
75 using ::com::sun::star::uno::UNO_QUERY
;
76 using ::com::sun::star::uno::Reference
;
77 using ::com::sun::star::uno::Sequence
;
78 using ::com::sun::star::lang::XServiceInfo
;
79 using ::com::sun::star::beans::XPropertySet
;
80 using ::com::sun::star::drawing::XShape
;
81 using ::com::sun::star::drawing::XShapes
;
82 using ::com::sun::star::frame::XModel
;
83 using ::com::sun::star::awt::XControlModel
;
84 using ::com::sun::star::form::binding::XBindableValue
;
85 using ::com::sun::star::form::binding::XListEntrySink
;
86 using ::com::sun::star::script::ScriptEventDescriptor
;
87 using ::com::sun::star::table::CellAddress
;
88 using ::com::sun::star::table::CellRangeAddress
;
89 using ::oox::drawingml::DrawingML
;
90 using ::oox::drawingml::ChartExport
;
96 long lcl_hmm2px(long nPixel
)
98 return static_cast<long>(nPixel
*PIXEL_PER_INCH
/1000.0/CM_PER_INCH
+ 0.5);
101 const char *ToHorizAlign( SdrTextHorzAdjust eAdjust
)
105 case SDRTEXTHORZADJUST_CENTER
:
107 case SDRTEXTHORZADJUST_RIGHT
:
109 case SDRTEXTHORZADJUST_BLOCK
:
111 case SDRTEXTHORZADJUST_LEFT
:
117 const char *ToVertAlign( SdrTextVertAdjust eAdjust
)
121 case SDRTEXTVERTADJUST_CENTER
:
123 case SDRTEXTVERTADJUST_BOTTOM
:
125 case SDRTEXTVERTADJUST_BLOCK
:
127 case SDRTEXTVERTADJUST_TOP
:
133 void lcl_WriteAnchorVertex( sax_fastparser::FSHelperPtr
const & rComments
, const tools::Rectangle
&aRect
)
135 rComments
->startElement(FSNS(XML_xdr
, XML_col
));
136 rComments
->writeEscaped( OUString::number( aRect
.Left() ) );
137 rComments
->endElement( FSNS( XML_xdr
, XML_col
) );
138 rComments
->startElement(FSNS(XML_xdr
, XML_colOff
));
139 rComments
->writeEscaped( OUString::number( aRect
.Top() ) );
140 rComments
->endElement( FSNS( XML_xdr
, XML_colOff
) );
141 rComments
->startElement(FSNS(XML_xdr
, XML_row
));
142 rComments
->writeEscaped( OUString::number( aRect
.Right() ) );
143 rComments
->endElement( FSNS( XML_xdr
, XML_row
) );
144 rComments
->startElement(FSNS(XML_xdr
, XML_rowOff
));
145 rComments
->writeEscaped( OUString::number( aRect
.Bottom() ) );
146 rComments
->endElement( FSNS( XML_xdr
, XML_rowOff
) );
149 void lcl_GetFromTo( const XclExpRoot
& rRoot
, const tools::Rectangle
&aRect
, sal_Int32 nTab
, tools::Rectangle
&aFrom
, tools::Rectangle
&aTo
)
151 sal_Int32 nCol
= 0, nRow
= 0;
152 sal_Int32 nColOff
= 0, nRowOff
= 0;
154 const bool bRTL
= rRoot
.GetDoc().IsNegativePage( nTab
);
159 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
160 if( r
.Left() <= aRect
.Left() )
163 nColOff
= aRect
.Left() - r
.Left();
165 if( r
.Top() <= aRect
.Top() )
168 nRowOff
= aRect
.Top() - r
.Top();
170 if( r
.Left() > aRect
.Left() && r
.Top() > aRect
.Top() )
172 aFrom
= tools::Rectangle( nCol
-1, lcl_hmm2px( nColOff
),
173 nRow
-1, lcl_hmm2px( nRowOff
) );
182 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
183 if( r
.Left() >= aRect
.Left() )
186 nColOff
= r
.Left() - aRect
.Left();
188 if( r
.Top() <= aRect
.Top() )
191 nRowOff
= aRect
.Top() - r
.Top();
193 if( r
.Left() < aRect
.Left() && r
.Top() > aRect
.Top() )
195 aFrom
= tools::Rectangle( nCol
-1, lcl_hmm2px( nColOff
),
196 nRow
-1, lcl_hmm2px( nRowOff
) );
205 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
206 if( r
.Right() < aRect
.Right() )
208 if( r
.Bottom() < aRect
.Bottom() )
210 if( r
.Right() >= aRect
.Right() && r
.Bottom() >= aRect
.Bottom() )
212 aTo
= tools::Rectangle( nCol
, lcl_hmm2px( aRect
.Right() - r
.Left() ),
213 nRow
, lcl_hmm2px( aRect
.Bottom() - r
.Top() ));
222 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
223 if( r
.Right() >= aRect
.Right() )
225 if( r
.Bottom() < aRect
.Bottom() )
227 if( r
.Right() < aRect
.Right() && r
.Bottom() >= aRect
.Bottom() )
229 aTo
= tools::Rectangle( nCol
, lcl_hmm2px( r
.Left() - aRect
.Right() ),
230 nRow
, lcl_hmm2px( aRect
.Bottom() - r
.Top() ));
239 // Escher client anchor =======================================================
241 XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot
& rRoot
, sal_uInt16 nFlags
) :
247 void XclExpDffAnchorBase::SetFlags( const SdrObject
& rSdrObj
)
249 ImplSetFlags( rSdrObj
);
252 void XclExpDffAnchorBase::SetSdrObject( const SdrObject
& rSdrObj
)
254 ImplSetFlags( rSdrObj
);
255 ImplCalcAnchorRect( rSdrObj
.GetCurrentBoundRect(), MapUnit::Map100thMM
);
258 void XclExpDffAnchorBase::WriteDffData( EscherEx
& rEscherEx
) const
260 rEscherEx
.AddAtom( 18, ESCHER_ClientAnchor
);
261 rEscherEx
.GetStream().WriteUInt16( mnFlags
);
262 WriteXclObjAnchor( rEscherEx
.GetStream(), maAnchor
);
265 void XclExpDffAnchorBase::WriteData( EscherEx
& rEscherEx
, const tools::Rectangle
& rRect
)
267 // the passed rectangle is in twips
268 ImplCalcAnchorRect( rRect
, MapUnit::MapTwip
);
269 WriteDffData( rEscherEx
);
272 void XclExpDffAnchorBase::ImplSetFlags( const SdrObject
& )
274 OSL_FAIL( "XclExpDffAnchorBase::ImplSetFlags - not implemented" );
277 void XclExpDffAnchorBase::ImplCalcAnchorRect( const tools::Rectangle
&, MapUnit
)
279 OSL_FAIL( "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" );
282 XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot
& rRoot
) :
283 XclExpDffAnchorBase( rRoot
),
284 mnScTab( rRoot
.GetCurrScTab() )
288 void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject
& rSdrObj
)
290 // set flags for cell/page anchoring
291 if ( ScDrawLayer::GetAnchorType( rSdrObj
) == SCA_CELL
)
294 mnFlags
= EXC_ESC_ANCHOR_LOCKED
;
297 void XclExpDffSheetAnchor::ImplCalcAnchorRect( const tools::Rectangle
& rRect
, MapUnit eMapUnit
)
299 maAnchor
.SetRect( GetRoot(), mnScTab
, rRect
, eMapUnit
);
302 XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot
& rRoot
,
303 const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
304 XclExpDffAnchorBase( rRoot
),
305 maPageSize( rPageSize
),
311 void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject
& /*rSdrObj*/ )
313 // TODO (unsupported feature): fixed size
316 void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const tools::Rectangle
& rRect
, MapUnit eMapUnit
)
318 maAnchor
.SetRect( maPageSize
, mnScaleX
, mnScaleY
, rRect
, eMapUnit
);
321 XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot
& rRoot
, const tools::Rectangle
& rRect
) :
322 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_SIZELOCKED
)
324 maAnchor
.SetRect( rRoot
, rRoot
.GetCurrScTab(), rRect
, MapUnit::Map100thMM
);
327 XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
) :
328 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_POSLOCKED
)
330 GetAddressConverter().ConvertAddress( maAnchor
.maFirst
, rScPos
, true );
331 maAnchor
.maLast
.mnCol
= maAnchor
.maFirst
.mnCol
+ 1;
332 maAnchor
.maLast
.mnRow
= maAnchor
.maFirst
.mnRow
+ 1;
333 maAnchor
.mnLX
= maAnchor
.mnTY
= maAnchor
.mnRX
= maAnchor
.mnBY
= 0;
336 // MSODRAWING* records ========================================================
338 XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx
& rEscherEx
, sal_uInt16 nRecId
) :
339 XclExpRecord( nRecId
),
340 mrEscherEx( rEscherEx
),
341 mnFragmentKey( rEscherEx
.InitNextDffFragment() )
345 void XclExpMsoDrawingBase::WriteBody( XclExpStream
& rStrm
)
347 OSL_ENSURE( mrEscherEx
.GetStreamPos() == mrEscherEx
.GetDffFragmentPos( mnFragmentKey
),
348 "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" );
349 rStrm
.CopyFromStream( mrEscherEx
.GetStream(), mrEscherEx
.GetDffFragmentSize( mnFragmentKey
) );
352 XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx
& rEscherEx
) :
353 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWINGGROUP
)
355 SvStream
& rDffStrm
= mrEscherEx
.GetStream();
357 // write the DGGCONTAINER with some default settings
358 mrEscherEx
.OpenContainer( ESCHER_DggContainer
);
360 // TODO: stuff the OPT atom with our own document defaults?
361 static const sal_uInt8 spnDffOpt
[] = {
362 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
363 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
366 mrEscherEx
.AddAtom( sizeof( spnDffOpt
), ESCHER_OPT
, 3, 3 );
367 rDffStrm
.WriteBytes(spnDffOpt
, sizeof(spnDffOpt
));
369 // SPLITMENUCOLORS contains colors in toolbar
370 static const sal_uInt8 spnDffSplitMenuColors
[] = {
371 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
372 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
374 mrEscherEx
.AddAtom( sizeof( spnDffSplitMenuColors
), ESCHER_SplitMenuColors
, 0, 4 );
375 rDffStrm
.WriteBytes(spnDffSplitMenuColors
, sizeof(spnDffSplitMenuColors
));
377 // close the DGGCONTAINER
378 mrEscherEx
.CloseContainer();
379 mrEscherEx
.UpdateDffFragmentEnd();
382 XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx
& rEscherEx
) :
383 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWING
)
387 XclExpImgData::XclExpImgData( const Graphic
& rGraphic
, sal_uInt16 nRecId
) :
388 maGraphic( rGraphic
),
393 void XclExpImgData::Save( XclExpStream
& rStrm
)
395 Bitmap aBmp
= maGraphic
.GetBitmapEx().GetBitmap();
396 if( aBmp
.GetBitCount() != 24 )
397 aBmp
.Convert( BmpConversion::N24Bit
);
399 Bitmap::ScopedReadAccess
pAccess(aBmp
);
402 sal_Int32 nWidth
= ::std::min
< sal_Int32
>( pAccess
->Width(), 0xFFFF );
403 sal_Int32 nHeight
= ::std::min
< sal_Int32
>( pAccess
->Height(), 0xFFFF );
404 if( (nWidth
> 0) && (nHeight
> 0) )
406 sal_uInt8 nPadding
= static_cast< sal_uInt8
>( nWidth
& 0x03 );
407 sal_uInt32 nTmpSize
= static_cast< sal_uInt32
>( (nWidth
* 3 + nPadding
) * nHeight
+ 12 );
409 rStrm
.StartRecord( mnRecId
, nTmpSize
+ 4 );
411 rStrm
<< EXC_IMGDATA_BMP
// BMP format
412 << EXC_IMGDATA_WIN
// Windows
413 << nTmpSize
// size after _this_ field
414 << sal_uInt32( 12 ) // BITMAPCOREHEADER size
415 << static_cast< sal_uInt16
>( nWidth
) // width
416 << static_cast< sal_uInt16
>( nHeight
) // height
417 << sal_uInt16( 1 ) // planes
418 << sal_uInt16( 24 ); // bits per pixel
420 for( sal_Int32 nY
= nHeight
- 1; nY
>= 0; --nY
)
422 Scanline pScanline
= pAccess
->GetScanline( nY
);
423 for( sal_Int32 nX
= 0; nX
< nWidth
; ++nX
)
425 const BitmapColor
& rBmpColor
= pAccess
->GetPixelFromData( pScanline
, nX
);
426 rStrm
<< rBmpColor
.GetBlue() << rBmpColor
.GetGreen() << rBmpColor
.GetRed();
428 rStrm
.WriteZeroBytes( nPadding
);
436 void XclExpImgData::SaveXml( XclExpXmlStream
& rStrm
)
438 sax_fastparser::FSHelperPtr pWorksheet
= rStrm
.GetCurrentStream();
440 DrawingML
aDML(pWorksheet
, &rStrm
, drawingml::DOCUMENT_XLSX
);
441 OUString rId
= aDML
.WriteImage( maGraphic
);
442 pWorksheet
->singleElement(XML_picture
, FSNS(XML_r
, XML_id
), rId
.toUtf8());
445 XclExpControlHelper::XclExpControlHelper( const XclExpRoot
& rRoot
) :
451 XclExpControlHelper::~XclExpControlHelper()
455 void XclExpControlHelper::ConvertSheetLinks( Reference
< XShape
> const & xShape
)
462 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( xShape
);
463 if( !xCtrlModel
.is() )
466 // *** cell link *** ------------------------------------------------------
468 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY
);
471 Reference
< XServiceInfo
> xServInfo( xBindable
->getValueBinding(), UNO_QUERY
);
472 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_VALBIND
) )
474 ScfPropertySet
aBindProp( xServInfo
);
475 CellAddress aApiAddress
;
476 if( aBindProp
.GetProperty( aApiAddress
, SC_UNONAME_BOUNDCELL
) )
479 ScUnoConversion::FillScAddress( aCellLink
, aApiAddress
);
480 if( GetTabInfo().IsExportTab( aCellLink
.Tab() ) )
481 mxCellLink
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aCellLink
);
486 // *** source range *** ---------------------------------------------------
488 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY
);
489 if( xEntrySink
.is() )
491 Reference
< XServiceInfo
> xServInfo( xEntrySink
->getListEntrySource(), UNO_QUERY
);
492 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_LISTSOURCE
) )
494 ScfPropertySet
aSinkProp( xServInfo
);
495 CellRangeAddress aApiRange
;
496 if( aSinkProp
.GetProperty( aApiRange
, SC_UNONAME_CELLRANGE
) )
499 ScUnoConversion::FillScRange( aSrcRange
, aApiRange
);
500 if( (aSrcRange
.aStart
.Tab() == aSrcRange
.aEnd
.Tab()) && GetTabInfo().IsExportTab( aSrcRange
.aStart
.Tab() ) )
501 mxSrcRange
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aSrcRange
);
502 mnEntryCount
= static_cast< sal_uInt16
>( aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1 );
508 void XclExpControlHelper::WriteFormula( XclExpStream
& rStrm
, const XclTokenArray
& rTokArr
)
510 sal_uInt16 nFmlaSize
= rTokArr
.GetSize();
511 rStrm
<< nFmlaSize
<< sal_uInt32( 0 );
512 rTokArr
.WriteArray( rStrm
);
513 if( nFmlaSize
& 1 ) // pad to 16-bit
514 rStrm
<< sal_uInt8( 0 );
517 void XclExpControlHelper::WriteFormulaSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
, const XclTokenArray
& rTokArr
)
519 rStrm
.StartRecord( nSubRecId
, (rTokArr
.GetSize() + 5) & ~1 );
520 WriteFormula( rStrm
, rTokArr
);
524 //delete for exporting OCX
525 //#if EXC_EXP_OCX_CTRL
527 XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> const & xShape
,
528 const tools::Rectangle
* pChildAnchor
, const OUString
& rClassName
, sal_uInt32 nStrmStart
, sal_uInt32 nStrmSize
) :
529 XclObj( rObjMgr
, EXC_OBJTYPE_PICTURE
, true ),
530 XclExpControlHelper( rObjMgr
.GetRoot() ),
531 maClassName( rClassName
),
532 mnStrmStart( nStrmStart
),
533 mnStrmSize( nStrmSize
)
535 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
539 SetPrintable( aCtrlProp
.GetBoolProperty( "Printable" ) );
540 SetAutoFill( false );
541 SetAutoLine( false );
543 // fill DFF property set
544 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
545 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
,
546 ShapeFlag::HaveShapeProperty
| ShapeFlag::HaveAnchor
| ShapeFlag::OLEShape
);
547 tools::Rectangle aDummyRect
;
548 EscherPropertyContainer
aPropOpt( mrEscherEx
.GetGraphicProvider(), mrEscherEx
.QueryPictureStream(), aDummyRect
);
549 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 ); // bool field
550 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x08000040 );
551 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
553 // #i51348# name of the control, may overwrite shape name
555 if( aCtrlProp
.GetProperty( aCtrlName
, "Name" ) && !aCtrlName
.isEmpty() )
556 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
560 Reference
< XPropertySet
> xShapePS( xShape
, UNO_QUERY
);
561 if( xShapePS
.is() && aPropOpt
.CreateGraphicProperties( xShapePS
, "MetaFile", false ) )
564 if( aPropOpt
.GetOpt( ESCHER_Prop_pib
, nBlipId
) )
565 aPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nBlipId
);
568 // write DFF property set to stream
569 aPropOpt
.Commit( mrEscherEx
.GetStream() );
572 ImplWriteAnchor( SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
574 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
575 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
576 mrEscherEx
.UpdateDffFragmentEnd();
579 ConvertSheetLinks( xShape
);
582 void XclExpOcxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
584 // OBJCF - clipboard format
585 rStrm
.StartRecord( EXC_ID_OBJCF
, 2 );
586 rStrm
<< sal_uInt16( 2 );
590 rStrm
.StartRecord( EXC_ID_OBJFLAGS
, 2 );
591 rStrm
<< sal_uInt16( 0x0031 );
595 XclExpString
aClass( maClassName
);
596 sal_uInt16 nClassNameSize
= static_cast< sal_uInt16
>( aClass
.GetSize() );
597 sal_uInt16 nClassNamePad
= nClassNameSize
& 1;
598 sal_uInt16 nFirstPartSize
= 12 + nClassNameSize
+ nClassNamePad
;
600 const XclTokenArray
* pCellLink
= GetCellLinkTokArr();
601 sal_uInt16 nCellLinkSize
= pCellLink
? ((pCellLink
->GetSize() + 7) & 0xFFFE) : 0;
603 const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr();
604 sal_uInt16 nSrcRangeSize
= pSrcRange
? ((pSrcRange
->GetSize() + 7) & 0xFFFE) : 0;
606 sal_uInt16 nPictFmlaSize
= nFirstPartSize
+ nCellLinkSize
+ nSrcRangeSize
+ 18;
607 rStrm
.StartRecord( EXC_ID_OBJPICTFMLA
, nPictFmlaSize
);
609 rStrm
<< nFirstPartSize
// size of first part
610 << sal_uInt16( 5 ) // formula size
611 << sal_uInt32( 0 ) // unknown ID
612 << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
613 << sal_uInt8( 3 ) // pad to word
614 << aClass
; // "Forms.***.1"
615 rStrm
.WriteZeroBytes( nClassNamePad
); // pad to word
616 rStrm
<< mnStrmStart
// start in 'Ctls' stream
617 << mnStrmSize
// size in 'Ctls' stream
618 << sal_uInt32( 0 ); // class ID size
620 rStrm
<< nCellLinkSize
;
622 WriteFormula( rStrm
, *pCellLink
);
624 rStrm
<< nSrcRangeSize
;
626 WriteFormula( rStrm
, *pSrcRange
);
633 XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager
& rRoot
, Reference
< XShape
> const & xShape
, const tools::Rectangle
* pChildAnchor
) :
634 XclObj( rRoot
, EXC_OBJTYPE_UNKNOWN
, true ),
635 XclMacroHelper( rRoot
),
636 meEventType( EXC_TBX_EVENT_ACTION
),
646 mbFlatButton( false ),
647 mbFlatBorder( false ),
651 namespace FormCompType
= css::form::FormComponentType
;
652 namespace AwtVisualEffect
= css::awt::VisualEffect
;
653 namespace AwtScrollOrient
= css::awt::ScrollBarOrientation
;
655 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
656 if( !xShape
.is() || !aCtrlProp
.Is() )
659 mnHeight
= xShape
->getSize().Height
;
664 sal_Int16 nClassId
= 0;
665 if( aCtrlProp
.GetProperty( nClassId
, "ClassId" ) )
669 case FormCompType::COMMANDBUTTON
: mnObjType
= EXC_OBJTYPE_BUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
670 case FormCompType::RADIOBUTTON
: mnObjType
= EXC_OBJTYPE_OPTIONBUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
671 case FormCompType::CHECKBOX
: mnObjType
= EXC_OBJTYPE_CHECKBOX
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
672 case FormCompType::LISTBOX
: mnObjType
= EXC_OBJTYPE_LISTBOX
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
673 case FormCompType::COMBOBOX
: mnObjType
= EXC_OBJTYPE_DROPDOWN
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
674 case FormCompType::GROUPBOX
: mnObjType
= EXC_OBJTYPE_GROUPBOX
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
675 case FormCompType::FIXEDTEXT
: mnObjType
= EXC_OBJTYPE_LABEL
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
676 case FormCompType::SCROLLBAR
: mnObjType
= EXC_OBJTYPE_SCROLLBAR
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
677 case FormCompType::SPINBUTTON
: mnObjType
= EXC_OBJTYPE_SPIN
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
680 if( mnObjType
== EXC_OBJTYPE_UNKNOWN
)
685 SetPrintable( aCtrlProp
.GetBoolProperty( "Printable" ) );
686 SetAutoFill( false );
687 SetAutoLine( false );
689 // fill DFF property set
690 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
691 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, ShapeFlag::HaveAnchor
| ShapeFlag::HaveShapeProperty
);
692 EscherPropertyContainer aPropOpt
;
693 bool bVisible
= aCtrlProp
.GetBoolProperty( "EnableVisible" );
694 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, bVisible
? 0x00080000 : 0x00080002 ); // visible flag
696 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01000100 ); // bool field
697 aPropOpt
.AddOpt( ESCHER_Prop_lTxid
, 0 ); // Text ID
698 aPropOpt
.AddOpt( ESCHER_Prop_WrapText
, 0x00000001 );
699 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x001A0008 ); // bool field
700 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00100000 ); // bool field
701 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
703 // #i51348# name of the control, may overwrite shape name
705 if( aCtrlProp
.GetProperty( aCtrlName
, "Name" ) && !aCtrlName
.isEmpty() )
706 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
708 //Export description as alt text
709 if( SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
) )
712 OUString aDescrText
= pSdrObj
->GetDescription();
713 if(!aDescrText
.isEmpty())
714 aAltTxt
= aDescrText
.copy( 0, std::min
<sal_Int32
>(MSPROP_DESCRIPTION_MAX_LEN
, aDescrText
.getLength()) );
715 aPropOpt
.AddOpt( ESCHER_Prop_wzDescription
, aAltTxt
);
718 // write DFF property set to stream
719 aPropOpt
.Commit( mrEscherEx
.GetStream() );
722 ImplWriteAnchor( SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
724 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
725 mrEscherEx
.UpdateDffFragmentEnd();
729 if( aCtrlProp
.GetProperty( aString
, "Label" ) )
731 /* Be sure to construct the MSODRAWING record containing the
732 ClientTextbox atom after the base OBJ's MSODRAWING record data is
734 pClientTextbox
.reset( new XclExpMsoDrawing( mrEscherEx
) );
735 mrEscherEx
.AddAtom( 0, ESCHER_ClientTextbox
); // TXO record
736 mrEscherEx
.UpdateDffFragmentEnd();
738 sal_uInt16 nXclFont
= EXC_FONT_APP
;
739 if( !aString
.isEmpty() )
741 XclFontData aFontData
;
742 GetFontPropSetHelper().ReadFontProperties( aFontData
, aCtrlProp
, EXC_FONTPROPSET_CONTROL
);
743 if( (!aFontData
.maName
.isEmpty() ) && (aFontData
.mnHeight
> 0) )
744 nXclFont
= GetFontBuffer().Insert( aFontData
, EXC_COLOR_CTRLTEXT
);
747 pTxo
.reset( new XclTxo( aString
, nXclFont
) );
748 pTxo
->SetHorAlign( (mnObjType
== EXC_OBJTYPE_BUTTON
) ? EXC_OBJ_HOR_CENTER
: EXC_OBJ_HOR_LEFT
);
749 pTxo
->SetVerAlign( EXC_OBJ_VER_CENTER
);
752 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
755 aCtrlProp
.GetProperty( mnLineCount
, "LineCount" );
758 sal_Int16 nApiButton
= AwtVisualEffect::LOOK3D
;
759 sal_Int16 nApiBorder
= AwtVisualEffect::LOOK3D
;
762 case FormCompType::LISTBOX
:
763 case FormCompType::COMBOBOX
:
764 aCtrlProp
.GetProperty( nApiBorder
, "Border" );
766 case FormCompType::CHECKBOX
:
767 case FormCompType::RADIOBUTTON
:
768 aCtrlProp
.GetProperty( nApiButton
, "VisualEffect" );
769 nApiBorder
= AwtVisualEffect::NONE
;
771 // Push button cannot be set to flat in Excel
772 case FormCompType::COMMANDBUTTON
:
773 nApiBorder
= AwtVisualEffect::LOOK3D
;
775 // Label does not support a border in Excel
776 case FormCompType::FIXEDTEXT
:
777 nApiBorder
= AwtVisualEffect::NONE
;
779 /* Scroll bar and spin button have a "Border" property, but it is
780 really used for a border, and not for own 3D/flat look (#i34712#). */
781 case FormCompType::SCROLLBAR
:
782 case FormCompType::SPINBUTTON
:
783 nApiButton
= AwtVisualEffect::LOOK3D
;
784 nApiBorder
= AwtVisualEffect::NONE
;
786 // Group box does not support flat style (#i34712#)
787 case FormCompType::GROUPBOX
:
788 nApiBorder
= AwtVisualEffect::LOOK3D
;
791 mbFlatButton
= nApiButton
!= AwtVisualEffect::LOOK3D
;
792 mbFlatBorder
= nApiBorder
!= AwtVisualEffect::LOOK3D
;
795 sal_Int16 nApiState
= 0;
796 if( aCtrlProp
.GetProperty( nApiState
, "State" ) )
800 case 0: mnState
= EXC_OBJ_CHECKBOX_UNCHECKED
; break;
801 case 1: mnState
= EXC_OBJ_CHECKBOX_CHECKED
; break;
802 case 2: mnState
= EXC_OBJ_CHECKBOX_TRISTATE
; break;
806 // special control contents
809 case FormCompType::LISTBOX
:
811 mbMultiSel
= aCtrlProp
.GetBoolProperty( "MultiSelection" );
812 Sequence
< sal_Int16
> aSelection
;
813 if( aCtrlProp
.GetProperty( aSelection
, "SelectedItems" ) )
815 if( aSelection
.hasElements() )
817 mnSelEntry
= aSelection
[ 0 ] + 1;
818 comphelper::sequenceToContainer(maMultiSel
, aSelection
);
822 // convert listbox with dropdown button to Excel dropdown
823 if( aCtrlProp
.GetBoolProperty( "Dropdown" ) )
824 mnObjType
= EXC_OBJTYPE_DROPDOWN
;
828 case FormCompType::COMBOBOX
:
830 Sequence
< OUString
> aStringList
;
832 if( aCtrlProp
.GetProperty( aStringList
, "StringItemList" ) &&
833 aCtrlProp
.GetProperty( aDefText
, "Text" ) &&
834 aStringList
.hasElements() && !aDefText
.isEmpty() )
836 auto nIndex
= comphelper::findValue(aStringList
, aDefText
);
838 mnSelEntry
= static_cast< sal_Int16
>( nIndex
+ 1 ); // 1-based
840 maMultiSel
.resize( 1, mnSelEntry
- 1 );
843 // convert combobox without dropdown button to Excel listbox
844 if( !aCtrlProp
.GetBoolProperty( "Dropdown" ) )
845 mnObjType
= EXC_OBJTYPE_LISTBOX
;
849 case FormCompType::SCROLLBAR
:
851 sal_Int32 nApiValue
= 0;
852 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMin" ) )
853 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
854 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMax" ) )
855 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MIN
);
856 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValue" ) )
857 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
858 if( aCtrlProp
.GetProperty( nApiValue
, "LineIncrement" ) )
859 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
860 if( aCtrlProp
.GetProperty( nApiValue
, "BlockIncrement" ) )
861 mnScrollPage
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
862 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
863 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
867 case FormCompType::SPINBUTTON
:
869 sal_Int32 nApiValue
= 0;
870 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMin" ) )
871 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
872 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMax" ) )
873 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MAX
);
874 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValue" ) )
875 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
876 if( aCtrlProp
.GetProperty( nApiValue
, "SpinIncrement" ) )
877 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
878 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
879 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
885 ConvertSheetLinks( xShape
);
888 bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor
& rEvent
)
890 return XclMacroHelper::SetMacroLink( rEvent
, meEventType
);
893 void XclExpTbxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
897 // *** Push buttons, labels ***
899 case EXC_OBJTYPE_BUTTON
:
900 case EXC_OBJTYPE_LABEL
:
901 // ftMacro - macro link
902 WriteMacroSubRec( rStrm
);
905 // *** Check boxes, option buttons ***
907 case EXC_OBJTYPE_CHECKBOX
:
908 case EXC_OBJTYPE_OPTIONBUTTON
:
910 // ftCbls - box properties
911 sal_uInt16 nStyle
= 0;
912 ::set_flag( nStyle
, EXC_OBJ_CHECKBOX_FLAT
, mbFlatButton
);
914 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 12 );
916 rStrm
.WriteZeroBytes( 8 );
920 // ftMacro - macro link
921 WriteMacroSubRec( rStrm
);
922 // ftCblsFmla subrecord - cell link
923 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJCBLSFMLA
);
925 // ftCblsData subrecord - box properties, again
926 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 8 );
928 rStrm
.WriteZeroBytes( 4 );
934 // *** List boxes, combo boxes ***
936 case EXC_OBJTYPE_LISTBOX
:
937 case EXC_OBJTYPE_DROPDOWN
:
939 sal_uInt16 nEntryCount
= GetSourceEntryCount();
941 // ftSbs subrecord - Scroll bars
942 sal_Int32 nLineHeight
= XclTools::GetHmmFromTwips( 200 ); // always 10pt
943 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
944 mnLineCount
= static_cast< sal_uInt16
>( mnHeight
/ nLineHeight
);
947 sal_uInt16 nInvisLines
= (nEntryCount
>= mnLineCount
) ? (nEntryCount
- mnLineCount
) : 0;
948 mnScrollMax
= limit_cast
< sal_uInt16
>( nInvisLines
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
950 mnScrollPage
= limit_cast
< sal_uInt16
>( mnLineCount
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
954 // ftMacro - macro link
955 WriteMacroSubRec( rStrm
);
956 // ftSbsFmla subrecord - cell link
957 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
959 // ftLbsData - source data range and box properties
960 sal_uInt16 nStyle
= 0;
961 ::insert_value( nStyle
, mbMultiSel
? EXC_OBJ_LISTBOX_MULTI
: EXC_OBJ_LISTBOX_SINGLE
, 4, 2 );
962 ::set_flag( nStyle
, EXC_OBJ_LISTBOX_FLAT
, mbFlatBorder
);
964 rStrm
.StartRecord( EXC_ID_OBJLBSDATA
, 0 );
966 if( const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr() )
968 rStrm
<< static_cast< sal_uInt16
>( (pSrcRange
->GetSize() + 7) & 0xFFFE );
969 WriteFormula( rStrm
, *pSrcRange
);
972 rStrm
<< sal_uInt16( 0 );
974 rStrm
<< nEntryCount
<< mnSelEntry
<< nStyle
<< sal_uInt16( 0 );
975 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
979 ScfUInt8Vec
aSelEx( nEntryCount
, 0 );
980 for( const auto& rItem
: maMultiSel
)
981 if( rItem
< nEntryCount
)
983 rStrm
.Write( aSelEx
.data(), aSelEx
.size() );
986 else if( mnObjType
== EXC_OBJTYPE_DROPDOWN
)
988 rStrm
<< sal_uInt16( 0 ) << mnLineCount
<< sal_uInt16( 0 ) << sal_uInt16( 0 );
995 // *** Spin buttons, scrollbars ***
997 case EXC_OBJTYPE_SPIN
:
998 case EXC_OBJTYPE_SCROLLBAR
:
1000 // ftSbs subrecord - scroll bars
1002 // ftMacro - macro link
1003 WriteMacroSubRec( rStrm
);
1004 // ftSbsFmla subrecord - cell link
1005 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
1009 // *** Group boxes ***
1011 case EXC_OBJTYPE_GROUPBOX
:
1013 // ftMacro - macro link
1014 WriteMacroSubRec( rStrm
);
1016 // ftGboData subrecord - group box properties
1017 sal_uInt16 nStyle
= 0;
1018 ::set_flag( nStyle
, EXC_OBJ_GROUPBOX_FLAT
, mbFlatBorder
);
1020 rStrm
.StartRecord( EXC_ID_OBJGBODATA
, 6 );
1021 rStrm
<< sal_uInt32( 0 )
1029 void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
)
1031 if( const XclTokenArray
* pCellLink
= GetCellLinkTokArr() )
1032 WriteFormulaSubRec( rStrm
, nSubRecId
, *pCellLink
);
1035 void XclExpTbxControlObj::WriteSbs( XclExpStream
& rStrm
)
1037 sal_uInt16 nOrient
= 0;
1038 ::set_flag( nOrient
, EXC_OBJ_SCROLLBAR_HOR
, mbScrollHor
);
1039 sal_uInt16 nStyle
= EXC_OBJ_SCROLLBAR_DEFFLAGS
;
1040 ::set_flag( nStyle
, EXC_OBJ_SCROLLBAR_FLAT
, mbFlatButton
);
1042 rStrm
.StartRecord( EXC_ID_OBJSBS
, 20 );
1043 rStrm
<< sal_uInt32( 0 ) // reserved
1044 << mnScrollValue
// thumb position
1045 << mnScrollMin
// thumb min pos
1046 << mnScrollMax
// thumb max pos
1047 << mnScrollStep
// line increment
1048 << mnScrollPage
// page increment
1049 << nOrient
// 0 = vertical, 1 = horizontal
1050 << sal_uInt16( 15 ) // thumb width
1051 << nStyle
; // flags/style
1057 XclExpChartObj::XclExpChartObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> const & xShape
, const tools::Rectangle
* pChildAnchor
, ScDocument
* pDoc
) :
1058 XclObj( rObjMgr
, EXC_OBJTYPE_CHART
),
1059 XclExpRoot( rObjMgr
.GetRoot() ), mxShape( xShape
),
1062 // create the MSODRAWING record contents for the chart object
1063 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
1064 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, ShapeFlag::HaveAnchor
| ShapeFlag::HaveShapeProperty
);
1065 EscherPropertyContainer aPropOpt
;
1066 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01040104 );
1067 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 );
1068 aPropOpt
.AddOpt( ESCHER_Prop_fillColor
, 0x0800004E );
1069 aPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0x0800004D );
1070 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00110010 );
1071 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x0800004D );
1072 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
1073 aPropOpt
.AddOpt( ESCHER_Prop_fshadowObscured
, 0x00020000 );
1074 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x00080000 );
1075 aPropOpt
.Commit( mrEscherEx
.GetStream() );
1078 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
);
1079 ImplWriteAnchor( pSdrObj
, pChildAnchor
);
1081 // client data (the following OBJ record)
1082 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
);
1083 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
1084 mrEscherEx
.UpdateDffFragmentEnd();
1086 // load the chart OLE object
1087 if( SdrOle2Obj
* pSdrOleObj
= dynamic_cast< SdrOle2Obj
* >( pSdrObj
) )
1088 svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj
->GetObjRef() );
1090 // create the chart substream object
1091 ScfPropertySet
aShapeProp( xShape
);
1092 Reference
< XModel
> xModel
;
1093 aShapeProp
.GetProperty( xModel
, "Model" );
1094 mxChartDoc
.set( xModel
,UNO_QUERY
);
1095 css::awt::Rectangle aBoundRect
;
1096 aShapeProp
.GetProperty( aBoundRect
, "BoundRect" );
1097 tools::Rectangle
aChartRect( Point( aBoundRect
.X
, aBoundRect
.Y
), Size( aBoundRect
.Width
, aBoundRect
.Height
) );
1098 mxChart
.reset( new XclExpChart( GetRoot(), xModel
, aChartRect
) );
1101 XclExpChartObj::~XclExpChartObj()
1105 void XclExpChartObj::Save( XclExpStream
& rStrm
)
1107 // content of OBJ record
1108 XclObj::Save( rStrm
);
1110 mxChart
->Save( rStrm
);
1113 void XclExpChartObj::SaveXml( XclExpXmlStream
& rStrm
)
1115 sax_fastparser::FSHelperPtr pDrawing
= rStrm
.GetCurrentStream();
1117 // FIXME: two cell? it seems the two cell anchor is incorrect.
1118 pDrawing
->startElement( FSNS( XML_xdr
, XML_twoCellAnchor
), // OOXTODO: oneCellAnchor, absoluteAnchor
1119 XML_editAs
, "oneCell" );
1120 Reference
< XPropertySet
> xPropSet( mxShape
, UNO_QUERY
);
1123 XclObjAny::WriteFromTo( rStrm
, mxShape
, GetTab() );
1124 ChartExport
aChartExport(XML_xdr
, pDrawing
, mxChartDoc
, &rStrm
, drawingml::DOCUMENT_XLSX
);
1125 std::shared_ptr
<oox::drawingml::URLTransformer
> pURLTransformer(new ScURLTransformer(*mpDoc
));
1126 aChartExport
.SetURLTranslator(pURLTransformer
);
1127 static sal_Int32 nChartCount
= 0;
1129 sal_Int32 nID
= rStrm
.GetUniqueId();
1130 aChartExport
.WriteChartObj( mxShape
, nID
, nChartCount
);
1131 // TODO: get the correcto chart number
1134 pDrawing
->singleElement( FSNS( XML_xdr
, XML_clientData
)
1135 // OOXTODO: XML_fLocksWithSheet
1136 // OOXTODO: XML_fPrintsWithSheet
1138 pDrawing
->endElement( FSNS( XML_xdr
, XML_twoCellAnchor
) );
1141 const css::uno::Reference
<css::chart::XChartDocument
>& XclExpChartObj::GetChartDoc() const
1146 XclExpNote::XclExpNote(const XclExpRoot
& rRoot
, const ScAddress
& rScPos
,
1147 const ScPostIt
* pScNote
, const OUString
& rAddText
)
1148 : XclExpRecord(EXC_ID_NOTE
)
1151 , mnObjId(EXC_OBJ_INVALID_ID
)
1152 , mbVisible(pScNote
&& pScNote
->IsCaptionShown())
1153 , meTHA(SDRTEXTHORZADJUST_LEFT
)
1154 , meTVA(SDRTEXTVERTADJUST_TOP
)
1155 , mbAutoScale(false)
1158 , mbColHidden(false)
1159 , mbRowHidden(false)
1161 // get the main note text
1165 aNoteText
= pScNote
->GetText();
1166 const EditTextObject
*pEditObj
= pScNote
->GetEditTextObject();
1168 mpNoteContents
= XclExpStringHelper::CreateString( rRoot
, *pEditObj
);
1170 // append additional text
1171 aNoteText
= ScGlobal::addToken( aNoteText
, rAddText
, '\n', 2 );
1173 // initialize record dependent on BIFF type
1174 switch( rRoot
.GetBiff() )
1177 maNoteText
= OUStringToOString(aNoteText
, rRoot
.GetTextEncoding());
1182 // TODO: additional text
1185 if( SdrCaptionObj
* pCaption
= pScNote
->GetOrCreateCaption( maScPos
) )
1187 lcl_GetFromTo( rRoot
, pCaption
->GetLogicRect(), maScPos
.Tab(), maCommentFrom
, maCommentTo
);
1188 if( const OutlinerParaObject
* pOPO
= pCaption
->GetOutlinerParaObject() )
1189 mnObjId
= rRoot
.GetObjectManager().AddObj( std::make_unique
<XclObjComment
>( rRoot
.GetObjectManager(), pCaption
->GetLogicRect(), pOPO
->GetTextObject(), pCaption
, mbVisible
, maScPos
, maCommentFrom
, maCommentTo
) );
1191 SfxItemSet aItemSet
= pCaption
->GetMergedItemSet();
1192 meTVA
= pCaption
->GetTextVerticalAdjust();
1193 meTHA
= pCaption
->GetTextHorizontalAdjust();
1194 mbAutoScale
= pCaption
->GetFitToSize() != drawing::TextFitToSizeType_NONE
;
1195 mbLocked
= pCaption
->IsMoveProtect() || pCaption
->IsResizeProtect();
1197 // AutoFill style would change if Postit.cxx object creation values are changed
1198 OUString
aCol(aItemSet
.Get(XATTR_FILLCOLOR
).GetValue());
1199 mbAutoFill
= aCol
.isEmpty() && (aItemSet
.Get(XATTR_FILLSTYLE
).GetValue() == drawing::FillStyle_SOLID
);
1200 mbRowHidden
= (rRoot
.GetDoc().RowHidden(maScPos
.Row(),maScPos
.Tab()));
1201 mbColHidden
= (rRoot
.GetDoc().ColHidden(maScPos
.Col(),maScPos
.Tab()));
1203 // stAuthor (variable): An XLUnicodeString that specifies the name of the comment
1204 // author. String length MUST be greater than or equal to 1 and less than or equal
1206 if( pScNote
->GetAuthor().isEmpty() )
1207 maAuthor
= XclExpString( " " );
1209 maAuthor
= XclExpString( pScNote
->GetAuthor(), XclStrFlags::NONE
, 54 );
1212 SetRecSize( 9 + maAuthor
.GetSize() );
1216 default: DBG_ERROR_BIFF();
1220 void XclExpNote::Save( XclExpStream
& rStrm
)
1222 switch( rStrm
.GetRoot().GetBiff() )
1226 // write the NOTE record directly, there may be the need to create more than one
1227 const sal_Char
* pcBuffer
= maNoteText
.getStr();
1228 sal_uInt16 nCharsLeft
= static_cast< sal_uInt16
>( maNoteText
.getLength() );
1232 sal_uInt16 nWriteChars
= ::std::min( nCharsLeft
, EXC_NOTE5_MAXLEN
);
1234 rStrm
.StartRecord( EXC_ID_NOTE
, 6 + nWriteChars
);
1235 if( pcBuffer
== maNoteText
.getStr() )
1237 // first record: row, col, length of complete text
1238 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1239 << static_cast< sal_uInt16
>( maScPos
.Col() )
1240 << nCharsLeft
; // still contains full length
1244 // next records: -1, 0, length of current text segment
1245 rStrm
<< sal_uInt16( 0xFFFF )
1249 rStrm
.Write( pcBuffer
, nWriteChars
);
1252 pcBuffer
+= nWriteChars
;
1253 nCharsLeft
= nCharsLeft
- nWriteChars
;
1259 if( mnObjId
!= EXC_OBJ_INVALID_ID
)
1260 XclExpRecord::Save( rStrm
);
1263 default: DBG_ERROR_BIFF();
1267 void XclExpNote::WriteBody( XclExpStream
& rStrm
)
1269 // BIFF5/BIFF7 is written separately
1270 OSL_ENSURE_BIFF( rStrm
.GetRoot().GetBiff() == EXC_BIFF8
);
1272 sal_uInt16 nFlags
= 0;
1273 ::set_flag( nFlags
, EXC_NOTE_VISIBLE
, mbVisible
);
1275 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1276 << static_cast< sal_uInt16
>( maScPos
.Col() )
1283 void XclExpNote::WriteXml( sal_Int32 nAuthorId
, XclExpXmlStream
& rStrm
)
1285 sax_fastparser::FSHelperPtr rComments
= rStrm
.GetCurrentStream();
1287 rComments
->startElement( XML_comment
,
1288 XML_ref
, XclXmlUtils::ToOString(&mrRoot
.GetDoc(), maScPos
),
1289 XML_authorId
, OString::number(nAuthorId
)
1290 // OOXTODO: XML_guid
1292 rComments
->startElement(XML_text
);
1293 // OOXTODO: phoneticPr, rPh, r
1294 if( mpNoteContents
)
1295 mpNoteContents
->WriteXml( rStrm
);
1296 rComments
->endElement( XML_text
);
1299 Export of commentPr is disabled, since the current (Oct 2010)
1300 version of MSO 2010 doesn't yet support commentPr
1302 #if 1//def XLSX_OOXML_FUTURE
1303 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1305 rComments
->startElement(FSNS(XML_mc
, XML_AlternateContent
));
1306 rComments
->startElement(FSNS(XML_mc
, XML_Choice
), XML_Requires
, "v2");
1307 rComments
->startElement( XML_commentPr
,
1308 XML_autoFill
, ToPsz( mbAutoFill
),
1309 XML_autoScale
, ToPsz( mbAutoScale
),
1310 XML_colHidden
, ToPsz( mbColHidden
),
1311 XML_locked
, ToPsz( mbLocked
),
1312 XML_rowHidden
, ToPsz( mbRowHidden
),
1313 XML_textHAlign
, ToHorizAlign( meTHA
),
1314 XML_textVAlign
, ToVertAlign( meTVA
) );
1315 rComments
->startElement(XML_anchor
, XML_moveWithCells
, "false", XML_sizeWithCells
, "false");
1316 rComments
->startElement(FSNS(XML_xdr
, XML_from
));
1317 lcl_WriteAnchorVertex( rComments
, maCommentFrom
);
1318 rComments
->endElement( FSNS( XML_xdr
, XML_from
) );
1319 rComments
->startElement(FSNS(XML_xdr
, XML_to
));
1320 lcl_WriteAnchorVertex( rComments
, maCommentTo
);
1321 rComments
->endElement( FSNS( XML_xdr
, XML_to
) );
1322 rComments
->endElement( XML_anchor
);
1323 rComments
->endElement( XML_commentPr
);
1325 rComments
->endElement( FSNS( XML_mc
, XML_Choice
) );
1326 rComments
->startElement(FSNS(XML_mc
, XML_Fallback
));
1327 // Any fallback code ?
1328 rComments
->endElement( FSNS( XML_mc
, XML_Fallback
) );
1329 rComments
->endElement( FSNS( XML_mc
, XML_AlternateContent
) );
1332 rComments
->endElement( XML_comment
);
1335 XclMacroHelper::XclMacroHelper( const XclExpRoot
& rRoot
) :
1336 XclExpControlHelper( rRoot
)
1340 XclMacroHelper::~XclMacroHelper()
1344 void XclMacroHelper::WriteMacroSubRec( XclExpStream
& rStrm
)
1347 WriteFormulaSubRec( rStrm
, EXC_ID_OBJMACRO
, *mxMacroLink
);
1351 XclMacroHelper::SetMacroLink( const ScriptEventDescriptor
& rEvent
, const XclTbxEventType
& nEventType
)
1353 OUString aMacroName
= XclControlHelper::ExtractFromMacroDescriptor( rEvent
, nEventType
);
1354 if( !aMacroName
.isEmpty() )
1356 return SetMacroLink( aMacroName
);
1362 XclMacroHelper::SetMacroLink( const OUString
& rMacroName
)
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
> const & 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 void XclExpComments::SaveXml( XclExpXmlStream
& rStrm
)
1405 if( mrNotes
.IsEmpty() )
1408 sax_fastparser::FSHelperPtr rComments
= rStrm
.CreateOutputStream(
1409 XclXmlUtils::GetStreamName( "xl/", "comments", mnTab
+ 1 ),
1410 XclXmlUtils::GetStreamName( "../", "comments", mnTab
+ 1 ),
1411 rStrm
.GetCurrentStream()->getOutputStream(),
1412 "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
1413 OUStringToOString(oox::getRelationship(Relationship::COMMENTS
), RTL_TEXTENCODING_UTF8
).getStr());
1414 rStrm
.PushStream( rComments
);
1416 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1417 rComments
->startElement( XML_comments
,
1418 XML_xmlns
, rStrm
.getNamespaceURL(OOX_NS(xls
)).toUtf8(),
1419 FSNS(XML_xmlns
, XML_mc
), rStrm
.getNamespaceURL(OOX_NS(mce
)).toUtf8(),
1420 FSNS(XML_xmlns
, XML_xdr
), rStrm
.getNamespaceURL(OOX_NS(dmlSpreadDr
)).toUtf8(),
1421 FSNS(XML_xmlns
, XML_v2
), rStrm
.getNamespaceURL(OOX_NS(mceTest
)).toUtf8(),
1422 FSNS( XML_mc
, XML_Ignorable
), "v2" );
1424 rComments
->startElement( XML_comments
,
1425 XML_xmlns
, rStrm
.getNamespaceURL(OOX_NS(xls
)).toUtf8(),
1426 FSNS(XML_xmlns
, XML_xdr
), rStrm
.getNamespaceURL(OOX_NS(dmlSpreadDr
)).toUtf8() );
1428 rComments
->startElement(XML_authors
);
1430 typedef std::set
<OUString
> Authors
;
1433 size_t nNotes
= mrNotes
.GetSize();
1434 for( size_t i
= 0; i
< nNotes
; ++i
)
1436 aAuthors
.insert( XclXmlUtils::ToOUString( mrNotes
.GetRecord( i
)->GetAuthor() ) );
1439 for( const auto& rAuthor
: aAuthors
)
1441 rComments
->startElement(XML_author
);
1442 rComments
->writeEscaped( rAuthor
);
1443 rComments
->endElement( XML_author
);
1446 rComments
->endElement( XML_authors
);
1447 rComments
->startElement(XML_commentList
);
1449 Authors::const_iterator aAuthorsBegin
= aAuthors
.begin();
1450 for( size_t i
= 0; i
< nNotes
; ++i
)
1452 XclExpRecordList
< XclExpNote
>::RecordRefType xNote
= mrNotes
.GetRecord( i
);
1453 Authors::const_iterator aAuthor
= aAuthors
.find(
1454 XclXmlUtils::ToOUString( xNote
->GetAuthor() ) );
1455 sal_Int32 nAuthorId
= distance( aAuthorsBegin
, aAuthor
);
1456 xNote
->WriteXml( nAuthorId
, rStrm
);
1459 rComments
->endElement( XML_commentList
);
1460 rComments
->endElement( XML_comments
);
1465 // object manager =============================================================
1467 XclExpObjectManager::XclExpObjectManager( const XclExpRoot
& rRoot
) :
1471 mxEscherEx
.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm
) );
1474 XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager
& rParent
) :
1475 XclExpRoot( rParent
.GetRoot() )
1477 InitStream( false );
1478 mxEscherEx
.reset( new XclEscherEx( GetRoot(), *this, *mxDffStrm
, rParent
.mxEscherEx
.get() ) );
1481 XclExpObjectManager::~XclExpObjectManager()
1485 XclExpDffAnchorBase
* XclExpObjectManager::CreateDffAnchor() const
1487 return new XclExpDffSheetAnchor( GetRoot() );
1490 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::CreateDrawingGroup()
1492 return std::shared_ptr
< XclExpRecordBase
>( new XclExpMsoDrawingGroup( *mxEscherEx
) );
1495 void XclExpObjectManager::StartSheet()
1497 mxObjList
.reset( new XclExpObjList( GetRoot(), *mxEscherEx
) );
1500 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( const SdrPage
* pSdrPage
)
1503 mxEscherEx
->AddSdrPage( *pSdrPage
);
1504 // the first dummy object may still be open
1505 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1506 while( mxEscherEx
->GetGroupLevel() )
1507 mxEscherEx
->LeaveGroup();
1508 mxObjList
->EndSheet();
1512 std::shared_ptr
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( const Reference
< XShapes
>& rxShapes
)
1515 mxEscherEx
->AddUnoShapes( rxShapes
);
1516 // the first dummy object may still be open
1517 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1518 while( mxEscherEx
->GetGroupLevel() )
1519 mxEscherEx
->LeaveGroup();
1520 mxObjList
->EndSheet();
1524 void XclExpObjectManager::EndDocument()
1526 mxEscherEx
->EndDocument();
1529 XclExpMsoDrawing
* XclExpObjectManager::GetMsodrawingPerSheet()
1531 return mxObjList
->GetMsodrawingPerSheet();
1534 bool XclExpObjectManager::HasObj() const
1536 return !mxObjList
->empty();
1539 sal_uInt16
XclExpObjectManager::AddObj( std::unique_ptr
<XclObj
> pObjRec
)
1541 return mxObjList
->Add( std::move(pObjRec
) );
1544 std::unique_ptr
<XclObj
> XclExpObjectManager::RemoveLastObj()
1546 return mxObjList
->pop_back();
1549 void XclExpObjectManager::InitStream( bool bTempFile
)
1553 mxTempFile
.reset( new ::utl::TempFile
);
1554 if( mxTempFile
->IsValid() )
1556 mxTempFile
->EnableKillingFile();
1557 mxDffStrm
= ::utl::UcbStreamHelper::CreateStream( mxTempFile
->GetURL(), StreamMode::STD_READWRITE
);
1561 if( !mxDffStrm
.get() )
1562 mxDffStrm
.reset( new SvMemoryStream
);
1564 mxDffStrm
->SetEndian( SvStreamEndian::LITTLE
);
1567 XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager(
1568 const XclExpObjectManager
& rParent
, const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
1569 XclExpObjectManager( rParent
),
1570 maPageSize( rPageSize
),
1571 mnScaleX( nScaleX
),
1576 XclExpDffAnchorBase
* XclExpEmbeddedObjectManager::CreateDffAnchor() const
1578 return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize
, mnScaleX
, mnScaleY
);
1581 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */