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/awt/XControlModel.hpp>
28 #include <com/sun/star/drawing/XShape.hpp>
29 #include <com/sun/star/form/binding/XBindableValue.hpp>
30 #include <com/sun/star/form/binding/XListEntrySink.hpp>
31 #include <com/sun/star/awt/Size.hpp>
32 #include <com/sun/star/chart/XChartDocument.hpp>
35 #include <vcl/BitmapReadAccess.hxx>
36 #include <svx/svdoole2.hxx>
37 #include <svx/svdocapt.hxx>
38 #include <editeng/outlobj.hxx>
39 #include <unotools/tempfile.hxx>
40 #include <unotools/ucbstreamhelper.hxx>
41 #include <svtools/embedhlp.hxx>
43 #include <unonames.hxx>
44 #include <convuno.hxx>
47 #include <fapihelper.hxx>
48 #include <xcl97esc.hxx>
49 #include <xechart.hxx>
50 #include <xeformula.hxx>
51 #include <xehelper.hxx>
54 #include <xestyle.hxx>
56 #include <xltools.hxx>
57 #include <userdat.hxx>
58 #include <drwlayer.hxx>
59 #include <svl/itemset.hxx>
60 #include <svx/unoapi.hxx>
61 #include <svx/sdtaitm.hxx>
62 #include <document.hxx>
63 #include <svx/xfillit0.hxx>
64 #include <svx/xflclit.hxx>
66 #include <comphelper/sequence.hxx>
67 #include <oox/token/tokens.hxx>
68 #include <oox/token/relationship.hxx>
69 #include <oox/export/drawingml.hxx>
70 #include <oox/export/chartexport.hxx>
71 #include <oox/export/utils.hxx>
72 #include <oox/token/namespaces.hxx>
73 #include <oox/export/vmlexport.hxx>
76 using namespace com::sun::star
;
77 using ::com::sun::star::uno::UNO_QUERY
;
78 using ::com::sun::star::uno::Reference
;
79 using ::com::sun::star::uno::Sequence
;
80 using ::com::sun::star::lang::XServiceInfo
;
81 using ::com::sun::star::beans::XPropertySet
;
82 using ::com::sun::star::drawing::XShape
;
83 using ::com::sun::star::drawing::XShapes
;
84 using ::com::sun::star::frame::XModel
;
85 using ::com::sun::star::awt::XControlModel
;
86 using ::com::sun::star::form::binding::XBindableValue
;
87 using ::com::sun::star::form::binding::XListEntrySink
;
88 using ::com::sun::star::script::ScriptEventDescriptor
;
89 using ::com::sun::star::table::CellAddress
;
90 using ::com::sun::star::table::CellRangeAddress
;
91 using ::oox::drawingml::DrawingML
;
92 using ::oox::drawingml::ChartExport
;
98 const char *ToHorizAlign( SdrTextHorzAdjust eAdjust
)
102 case SDRTEXTHORZADJUST_CENTER
:
104 case SDRTEXTHORZADJUST_RIGHT
:
106 case SDRTEXTHORZADJUST_BLOCK
:
108 case SDRTEXTHORZADJUST_LEFT
:
114 const char *ToVertAlign( SdrTextVertAdjust eAdjust
)
118 case SDRTEXTVERTADJUST_CENTER
:
120 case SDRTEXTVERTADJUST_BOTTOM
:
122 case SDRTEXTVERTADJUST_BLOCK
:
124 case SDRTEXTVERTADJUST_TOP
:
130 void lcl_WriteAnchorVertex( sax_fastparser::FSHelperPtr
const & rComments
, const tools::Rectangle
&aRect
)
132 rComments
->startElement(FSNS(XML_xdr
, XML_col
));
133 rComments
->writeEscaped( OUString::number( aRect
.Left() ) );
134 rComments
->endElement( FSNS( XML_xdr
, XML_col
) );
135 rComments
->startElement(FSNS(XML_xdr
, XML_colOff
));
136 rComments
->writeEscaped( OUString::number( aRect
.Top() ) );
137 rComments
->endElement( FSNS( XML_xdr
, XML_colOff
) );
138 rComments
->startElement(FSNS(XML_xdr
, XML_row
));
139 rComments
->writeEscaped( OUString::number( aRect
.Right() ) );
140 rComments
->endElement( FSNS( XML_xdr
, XML_row
) );
141 rComments
->startElement(FSNS(XML_xdr
, XML_rowOff
));
142 rComments
->writeEscaped( OUString::number( aRect
.Bottom() ) );
143 rComments
->endElement( FSNS( XML_xdr
, XML_rowOff
) );
146 tools::Long
lcl_hmm2output(tools::Long value
, bool bInEMU
)
148 return o3tl::convert(value
, o3tl::Length::mm100
, bInEMU
? o3tl::Length::emu
: o3tl::Length::px
);
151 void lcl_GetFromTo( const XclExpRoot
& rRoot
, const tools::Rectangle
&aRect
, sal_Int32 nTab
, tools::Rectangle
&aFrom
, tools::Rectangle
&aTo
, bool bInEMU
= false )
153 sal_Int32 nCol
= 0, nRow
= 0;
154 sal_Int32 nColOff
= 0, nRowOff
= 0;
156 const bool bRTL
= rRoot
.GetDoc().IsNegativePage( nTab
);
161 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
162 if( r
.Left() <= aRect
.Left() )
165 nColOff
= aRect
.Left() - r
.Left();
167 if( r
.Top() <= aRect
.Top() )
170 nRowOff
= aRect
.Top() - r
.Top();
172 if( r
.Left() > aRect
.Left() && r
.Top() > aRect
.Top() )
174 aFrom
= tools::Rectangle( nCol
-1, lcl_hmm2output( nColOff
, bInEMU
),
175 nRow
-1, lcl_hmm2output( nRowOff
, bInEMU
) );
184 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
185 if( r
.Left() >= aRect
.Left() )
188 nColOff
= r
.Left() - aRect
.Left();
190 if( r
.Top() <= aRect
.Top() )
193 nRowOff
= aRect
.Top() - r
.Top();
195 if( r
.Left() < aRect
.Left() && r
.Top() > aRect
.Top() )
197 aFrom
= tools::Rectangle( nCol
-1, lcl_hmm2output( nColOff
, bInEMU
),
198 nRow
-1, lcl_hmm2output( nRowOff
, bInEMU
) );
207 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
208 if( r
.Right() < aRect
.Right() )
210 if( r
.Bottom() < aRect
.Bottom() )
212 if( r
.Right() >= aRect
.Right() && r
.Bottom() >= aRect
.Bottom() )
214 aTo
= tools::Rectangle( nCol
, lcl_hmm2output( aRect
.Right() - r
.Left(), bInEMU
),
215 nRow
, lcl_hmm2output( aRect
.Bottom() - r
.Top(), bInEMU
));
224 tools::Rectangle r
= rRoot
.GetDoc().GetMMRect( nCol
,nRow
,nCol
,nRow
,nTab
);
225 if( r
.Right() >= aRect
.Right() )
227 if( r
.Bottom() < aRect
.Bottom() )
229 if( r
.Right() < aRect
.Right() && r
.Bottom() >= aRect
.Bottom() )
231 aTo
= tools::Rectangle( nCol
, lcl_hmm2output( r
.Left() - aRect
.Right(), bInEMU
),
232 nRow
, lcl_hmm2output( aRect
.Bottom() - r
.Top(), bInEMU
));
241 // Escher client anchor =======================================================
243 XclExpDffAnchorBase::XclExpDffAnchorBase( const XclExpRoot
& rRoot
, sal_uInt16 nFlags
) :
249 void XclExpDffAnchorBase::SetFlags( const SdrObject
& rSdrObj
)
251 ImplSetFlags( rSdrObj
);
254 void XclExpDffAnchorBase::SetSdrObject( const SdrObject
& rSdrObj
)
256 ImplSetFlags( rSdrObj
);
257 ImplCalcAnchorRect( rSdrObj
.GetCurrentBoundRect(), MapUnit::Map100thMM
);
260 void XclExpDffAnchorBase::WriteDffData( EscherEx
& rEscherEx
) const
262 rEscherEx
.AddAtom( 18, ESCHER_ClientAnchor
);
263 rEscherEx
.GetStream().WriteUInt16( mnFlags
);
264 WriteXclObjAnchor( rEscherEx
.GetStream(), maAnchor
);
267 void XclExpDffAnchorBase::WriteData( EscherEx
& rEscherEx
, const tools::Rectangle
& rRect
)
269 // the passed rectangle is in twips
270 ImplCalcAnchorRect( rRect
, MapUnit::MapTwip
);
271 WriteDffData( rEscherEx
);
274 void XclExpDffAnchorBase::ImplSetFlags( const SdrObject
& )
276 OSL_FAIL( "XclExpDffAnchorBase::ImplSetFlags - not implemented" );
279 void XclExpDffAnchorBase::ImplCalcAnchorRect( const tools::Rectangle
&, MapUnit
)
281 OSL_FAIL( "XclExpDffAnchorBase::ImplCalcAnchorRect - not implemented" );
284 XclExpDffSheetAnchor::XclExpDffSheetAnchor( const XclExpRoot
& rRoot
) :
285 XclExpDffAnchorBase( rRoot
),
286 mnScTab( rRoot
.GetCurrScTab() )
290 void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject
& rSdrObj
)
292 // set flags for cell/page anchoring
293 if ( ScDrawLayer::GetAnchorType( rSdrObj
) == SCA_CELL
)
296 mnFlags
= EXC_ESC_ANCHOR_LOCKED
;
299 void XclExpDffSheetAnchor::ImplCalcAnchorRect( const tools::Rectangle
& rRect
, MapUnit eMapUnit
)
301 maAnchor
.SetRect( GetRoot(), mnScTab
, rRect
, eMapUnit
);
304 XclExpDffEmbeddedAnchor::XclExpDffEmbeddedAnchor( const XclExpRoot
& rRoot
,
305 const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
306 XclExpDffAnchorBase( rRoot
),
307 maPageSize( rPageSize
),
313 void XclExpDffEmbeddedAnchor::ImplSetFlags( const SdrObject
& /*rSdrObj*/ )
315 // TODO (unsupported feature): fixed size
318 void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const tools::Rectangle
& rRect
, MapUnit eMapUnit
)
320 maAnchor
.SetRect( maPageSize
, mnScaleX
, mnScaleY
, rRect
, eMapUnit
);
323 XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot
& rRoot
, const tools::Rectangle
& rRect
) :
324 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_SIZELOCKED
)
326 maAnchor
.SetRect( rRoot
, rRoot
.GetCurrScTab(), rRect
, MapUnit::Map100thMM
);
329 XclExpDffDropDownAnchor::XclExpDffDropDownAnchor( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
) :
330 XclExpDffAnchorBase( rRoot
, EXC_ESC_ANCHOR_POSLOCKED
)
332 GetAddressConverter().ConvertAddress( maAnchor
.maFirst
, rScPos
, true );
333 maAnchor
.maLast
.mnCol
= maAnchor
.maFirst
.mnCol
+ 1;
334 maAnchor
.maLast
.mnRow
= maAnchor
.maFirst
.mnRow
+ 1;
335 maAnchor
.mnLX
= maAnchor
.mnTY
= maAnchor
.mnRX
= maAnchor
.mnBY
= 0;
338 // MSODRAWING* records ========================================================
340 XclExpMsoDrawingBase::XclExpMsoDrawingBase( XclEscherEx
& rEscherEx
, sal_uInt16 nRecId
) :
341 XclExpRecord( nRecId
),
342 mrEscherEx( rEscherEx
),
343 mnFragmentKey( rEscherEx
.InitNextDffFragment() )
347 void XclExpMsoDrawingBase::WriteBody( XclExpStream
& rStrm
)
349 OSL_ENSURE( mrEscherEx
.GetStreamPos() == mrEscherEx
.GetDffFragmentPos( mnFragmentKey
),
350 "XclExpMsoDrawingBase::WriteBody - DFF stream position mismatch" );
351 rStrm
.CopyFromStream( mrEscherEx
.GetStream(), mrEscherEx
.GetDffFragmentSize( mnFragmentKey
) );
354 XclExpMsoDrawingGroup::XclExpMsoDrawingGroup( XclEscherEx
& rEscherEx
) :
355 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWINGGROUP
)
357 SvStream
& rDffStrm
= mrEscherEx
.GetStream();
359 // write the DGGCONTAINER with some default settings
360 mrEscherEx
.OpenContainer( ESCHER_DggContainer
);
362 // TODO: stuff the OPT atom with our own document defaults?
363 static const sal_uInt8 spnDffOpt
[] = {
364 0xBF, 0x00, 0x08, 0x00, 0x08, 0x00, 0x81, 0x01,
365 0x09, 0x00, 0x00, 0x08, 0xC0, 0x01, 0x40, 0x00,
368 mrEscherEx
.AddAtom( sizeof( spnDffOpt
), ESCHER_OPT
, 3, 3 );
369 rDffStrm
.WriteBytes(spnDffOpt
, sizeof(spnDffOpt
));
371 // SPLITMENUCOLORS contains colors in toolbar
372 static const sal_uInt8 spnDffSplitMenuColors
[] = {
373 0x0D, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x00, 0x08,
374 0x17, 0x00, 0x00, 0x08, 0xF7, 0x00, 0x00, 0x10
376 mrEscherEx
.AddAtom( sizeof( spnDffSplitMenuColors
), ESCHER_SplitMenuColors
, 0, 4 );
377 rDffStrm
.WriteBytes(spnDffSplitMenuColors
, sizeof(spnDffSplitMenuColors
));
379 // close the DGGCONTAINER
380 mrEscherEx
.CloseContainer();
381 mrEscherEx
.UpdateDffFragmentEnd();
384 XclExpMsoDrawing::XclExpMsoDrawing( XclEscherEx
& rEscherEx
) :
385 XclExpMsoDrawingBase( rEscherEx
, EXC_ID_MSODRAWING
)
389 XclExpImgData::XclExpImgData( const Graphic
& rGraphic
, sal_uInt16 nRecId
) :
390 maGraphic( rGraphic
),
395 void XclExpImgData::Save( XclExpStream
& rStrm
)
397 Bitmap aBmp
= maGraphic
.GetBitmapEx().GetBitmap();
398 if (aBmp
.getPixelFormat() != vcl::PixelFormat::N24_BPP
)
399 aBmp
.Convert( BmpConversion::N24Bit
);
401 Bitmap::ScopedReadAccess
pAccess(aBmp
);
405 sal_Int32 nWidth
= ::std::min
< sal_Int32
>( pAccess
->Width(), 0xFFFF );
406 sal_Int32 nHeight
= ::std::min
< sal_Int32
>( pAccess
->Height(), 0xFFFF );
407 if( (nWidth
<= 0) || (nHeight
<= 0) )
410 sal_uInt8 nPadding
= static_cast< sal_uInt8
>( nWidth
& 0x03 );
411 sal_uInt32 nTmpSize
= static_cast< sal_uInt32
>( (nWidth
* 3 + nPadding
) * nHeight
+ 12 );
413 rStrm
.StartRecord( mnRecId
, nTmpSize
+ 4 );
415 rStrm
<< EXC_IMGDATA_BMP
// BMP format
416 << EXC_IMGDATA_WIN
// Windows
417 << nTmpSize
// size after _this_ field
418 << sal_uInt32( 12 ) // BITMAPCOREHEADER size
419 << static_cast< sal_uInt16
>( nWidth
) // width
420 << static_cast< sal_uInt16
>( nHeight
) // height
421 << sal_uInt16( 1 ) // planes
422 << sal_uInt16( 24 ); // bits per pixel
424 for( sal_Int32 nY
= nHeight
- 1; nY
>= 0; --nY
)
426 Scanline pScanline
= pAccess
->GetScanline( nY
);
427 for( sal_Int32 nX
= 0; nX
< nWidth
; ++nX
)
429 const BitmapColor
& rBmpColor
= pAccess
->GetPixelFromData( pScanline
, nX
);
430 rStrm
<< rBmpColor
.GetBlue() << rBmpColor
.GetGreen() << rBmpColor
.GetRed();
432 rStrm
.WriteZeroBytes( nPadding
);
438 void XclExpImgData::SaveXml( XclExpXmlStream
& rStrm
)
440 sax_fastparser::FSHelperPtr pWorksheet
= rStrm
.GetCurrentStream();
442 DrawingML
aDML(pWorksheet
, &rStrm
, drawingml::DOCUMENT_XLSX
);
443 OUString rId
= aDML
.WriteImage( maGraphic
);
444 pWorksheet
->singleElement(XML_picture
, FSNS(XML_r
, XML_id
), rId
);
447 XclExpControlHelper::XclExpControlHelper( const XclExpRoot
& rRoot
) :
453 XclExpControlHelper::~XclExpControlHelper()
457 void XclExpControlHelper::ConvertSheetLinks( Reference
< XShape
> const & xShape
)
460 mxCellLinkAddress
.SetInvalid();
465 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( xShape
);
466 if( !xCtrlModel
.is() )
469 // *** cell link *** ------------------------------------------------------
471 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY
);
474 Reference
< XServiceInfo
> xServInfo( xBindable
->getValueBinding(), UNO_QUERY
);
475 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_VALBIND
) )
477 ScfPropertySet
aBindProp( xServInfo
);
478 CellAddress aApiAddress
;
479 if( aBindProp
.GetProperty( aApiAddress
, SC_UNONAME_BOUNDCELL
) )
481 ScUnoConversion::FillScAddress( mxCellLinkAddress
, aApiAddress
);
482 if( GetTabInfo().IsExportTab( mxCellLinkAddress
.Tab() ) )
483 mxCellLink
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, mxCellLinkAddress
);
488 // *** source range *** ---------------------------------------------------
490 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY
);
491 if( !xEntrySink
.is() )
494 Reference
< XServiceInfo
> xServInfo( xEntrySink
->getListEntrySource(), UNO_QUERY
);
495 if( !(xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_LISTSOURCE
)) )
498 ScfPropertySet
aSinkProp( xServInfo
);
499 CellRangeAddress aApiRange
;
500 if( aSinkProp
.GetProperty( aApiRange
, SC_UNONAME_CELLRANGE
) )
503 ScUnoConversion::FillScRange( aSrcRange
, aApiRange
);
504 if( (aSrcRange
.aStart
.Tab() == aSrcRange
.aEnd
.Tab()) && GetTabInfo().IsExportTab( aSrcRange
.aStart
.Tab() ) )
505 mxSrcRange
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aSrcRange
);
506 mnEntryCount
= static_cast< sal_uInt16
>( aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1 );
510 void XclExpControlHelper::WriteFormula( XclExpStream
& rStrm
, const XclTokenArray
& rTokArr
)
512 sal_uInt16 nFmlaSize
= rTokArr
.GetSize();
513 rStrm
<< nFmlaSize
<< sal_uInt32( 0 );
514 rTokArr
.WriteArray( rStrm
);
515 if( nFmlaSize
& 1 ) // pad to 16-bit
516 rStrm
<< sal_uInt8( 0 );
519 void XclExpControlHelper::WriteFormulaSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
, const XclTokenArray
& rTokArr
)
521 rStrm
.StartRecord( nSubRecId
, (rTokArr
.GetSize() + 5) & ~1 );
522 WriteFormula( rStrm
, rTokArr
);
526 //delete for exporting OCX
527 //#if EXC_EXP_OCX_CTRL
529 XclExpOcxControlObj::XclExpOcxControlObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> const & xShape
,
530 const tools::Rectangle
* pChildAnchor
, const OUString
& rClassName
, sal_uInt32 nStrmStart
, sal_uInt32 nStrmSize
) :
531 XclObj( rObjMgr
, EXC_OBJTYPE_PICTURE
, true ),
532 XclExpControlHelper( rObjMgr
.GetRoot() ),
533 maClassName( rClassName
),
534 mnStrmStart( nStrmStart
),
535 mnStrmSize( nStrmSize
)
537 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
541 SetPrintable( aCtrlProp
.GetBoolProperty( "Printable" ) );
542 SetAutoFill( false );
543 SetAutoLine( false );
545 // fill DFF property set
546 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
547 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
,
548 ShapeFlag::HaveShapeProperty
| ShapeFlag::HaveAnchor
| ShapeFlag::OLEShape
);
549 tools::Rectangle aDummyRect
;
550 EscherPropertyContainer
aPropOpt( mrEscherEx
.GetGraphicProvider(), mrEscherEx
.QueryPictureStream(), aDummyRect
);
551 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 ); // bool field
552 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x08000040 );
553 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
555 // #i51348# name of the control, may overwrite shape name
557 if( aCtrlProp
.GetProperty( aCtrlName
, "Name" ) && !aCtrlName
.isEmpty() )
558 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
562 Reference
< XPropertySet
> xShapePS( xShape
, UNO_QUERY
);
563 if( xShapePS
.is() && aPropOpt
.CreateGraphicProperties( xShapePS
, "MetaFile", false ) )
566 if( aPropOpt
.GetOpt( ESCHER_Prop_pib
, nBlipId
) )
567 aPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nBlipId
);
570 // write DFF property set to stream
571 aPropOpt
.Commit( mrEscherEx
.GetStream() );
574 ImplWriteAnchor( SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
576 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
577 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
578 mrEscherEx
.UpdateDffFragmentEnd();
581 ConvertSheetLinks( xShape
);
584 void XclExpOcxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
586 // OBJCF - clipboard format
587 rStrm
.StartRecord( EXC_ID_OBJCF
, 2 );
588 rStrm
<< sal_uInt16( 2 );
592 rStrm
.StartRecord( EXC_ID_OBJFLAGS
, 2 );
593 rStrm
<< sal_uInt16( 0x0031 );
597 XclExpString
aClass( maClassName
);
598 sal_uInt16 nClassNameSize
= static_cast< sal_uInt16
>( aClass
.GetSize() );
599 sal_uInt16 nClassNamePad
= nClassNameSize
& 1;
600 sal_uInt16 nFirstPartSize
= 12 + nClassNameSize
+ nClassNamePad
;
602 const XclTokenArray
* pCellLink
= GetCellLinkTokArr();
603 sal_uInt16 nCellLinkSize
= pCellLink
? ((pCellLink
->GetSize() + 7) & 0xFFFE) : 0;
605 const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr();
606 sal_uInt16 nSrcRangeSize
= pSrcRange
? ((pSrcRange
->GetSize() + 7) & 0xFFFE) : 0;
608 sal_uInt16 nPictFmlaSize
= nFirstPartSize
+ nCellLinkSize
+ nSrcRangeSize
+ 18;
609 rStrm
.StartRecord( EXC_ID_OBJPICTFMLA
, nPictFmlaSize
);
611 rStrm
<< nFirstPartSize
// size of first part
612 << sal_uInt16( 5 ) // formula size
613 << sal_uInt32( 0 ) // unknown ID
614 << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
615 << sal_uInt8( 3 ) // pad to word
616 << aClass
; // "Forms.***.1"
617 rStrm
.WriteZeroBytes( nClassNamePad
); // pad to word
618 rStrm
<< mnStrmStart
// start in 'Ctls' stream
619 << mnStrmSize
// size in 'Ctls' stream
620 << sal_uInt32( 0 ); // class ID size
622 rStrm
<< nCellLinkSize
;
624 WriteFormula( rStrm
, *pCellLink
);
626 rStrm
<< nSrcRangeSize
;
628 WriteFormula( rStrm
, *pSrcRange
);
635 XclExpTbxControlObj::XclExpTbxControlObj( XclExpObjectManager
& rRoot
, Reference
< XShape
> const & xShape
, const tools::Rectangle
* pChildAnchor
) :
636 XclObj( rRoot
, EXC_OBJTYPE_UNKNOWN
, true ),
637 XclMacroHelper( rRoot
),
639 meEventType( EXC_TBX_EVENT_ACTION
),
649 mbFlatButton( false ),
650 mbFlatBorder( false ),
652 mbScrollHor( false ),
658 namespace FormCompType
= css::form::FormComponentType
;
659 namespace AwtVisualEffect
= css::awt::VisualEffect
;
660 namespace AwtScrollOrient
= css::awt::ScrollBarOrientation
;
662 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
663 if( !xShape
.is() || !aCtrlProp
.Is() )
666 mnHeight
= xShape
->getSize().Height
;
671 sal_Int16 nClassId
= 0;
672 if( aCtrlProp
.GetProperty( nClassId
, "ClassId" ) )
676 case FormCompType::COMMANDBUTTON
: mnObjType
= EXC_OBJTYPE_BUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
677 case FormCompType::RADIOBUTTON
: mnObjType
= EXC_OBJTYPE_OPTIONBUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
678 case FormCompType::CHECKBOX
: mnObjType
= EXC_OBJTYPE_CHECKBOX
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
679 case FormCompType::LISTBOX
: mnObjType
= EXC_OBJTYPE_LISTBOX
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
680 case FormCompType::COMBOBOX
: mnObjType
= EXC_OBJTYPE_DROPDOWN
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
681 case FormCompType::GROUPBOX
: mnObjType
= EXC_OBJTYPE_GROUPBOX
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
682 case FormCompType::FIXEDTEXT
: mnObjType
= EXC_OBJTYPE_LABEL
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
683 case FormCompType::SCROLLBAR
: mnObjType
= EXC_OBJTYPE_SCROLLBAR
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
684 case FormCompType::SPINBUTTON
: mnObjType
= EXC_OBJTYPE_SPIN
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
687 if( mnObjType
== EXC_OBJTYPE_UNKNOWN
)
692 mbPrint
= aCtrlProp
.GetBoolProperty( "Printable" );
693 SetPrintable( mbPrint
);
694 SetAutoFill( false );
695 SetAutoLine( false );
697 // fill DFF property set
698 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
699 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, ShapeFlag::HaveAnchor
| ShapeFlag::HaveShapeProperty
);
700 EscherPropertyContainer aPropOpt
;
701 mbVisible
= aCtrlProp
.GetBoolProperty( "EnableVisible" );
702 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, mbVisible
? 0x00080000 : 0x00080002 ); // visible flag
704 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01000100 ); // bool field
705 aPropOpt
.AddOpt( ESCHER_Prop_lTxid
, 0 ); // Text ID
706 aPropOpt
.AddOpt( ESCHER_Prop_WrapText
, 0x00000001 );
707 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x001A0008 ); // bool field
708 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00100000 ); // bool field
709 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
711 // #i51348# name of the control, may overwrite shape name
712 if( aCtrlProp
.GetProperty( msCtrlName
, "Name" ) && !msCtrlName
.isEmpty() )
713 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, msCtrlName
);
715 //Export description as alt text
716 if( SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
) )
719 OUString aDescrText
= pSdrObj
->GetDescription();
720 if(!aDescrText
.isEmpty())
721 aAltTxt
= aDescrText
.copy( 0, std::min
<sal_Int32
>(MSPROP_DESCRIPTION_MAX_LEN
, aDescrText
.getLength()) );
722 aPropOpt
.AddOpt( ESCHER_Prop_wzDescription
, aAltTxt
);
725 // write DFF property set to stream
726 aPropOpt
.Commit( mrEscherEx
.GetStream() );
729 ImplWriteAnchor( SdrObject::getSdrObjectFromXShape( xShape
), pChildAnchor
);
731 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
732 mrEscherEx
.UpdateDffFragmentEnd();
735 if( aCtrlProp
.GetProperty( msLabel
, "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
.reset( new XclExpMsoDrawing( mrEscherEx
) );
741 mrEscherEx
.AddAtom( 0, ESCHER_ClientTextbox
); // TXO record
742 mrEscherEx
.UpdateDffFragmentEnd();
744 sal_uInt16 nXclFont
= EXC_FONT_APP
;
745 if( !msLabel
.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
.reset( new XclTxo( msLabel
, 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 if( aSelection
.hasElements() )
823 mnSelEntry
= aSelection
[ 0 ] + 1;
824 comphelper::sequenceToContainer(maMultiSel
, aSelection
);
828 // convert listbox with dropdown button to Excel dropdown
829 if( aCtrlProp
.GetBoolProperty( "Dropdown" ) )
830 mnObjType
= EXC_OBJTYPE_DROPDOWN
;
834 case FormCompType::COMBOBOX
:
836 Sequence
< OUString
> aStringList
;
838 if( aCtrlProp
.GetProperty( aStringList
, "StringItemList" ) &&
839 aCtrlProp
.GetProperty( aDefText
, "Text" ) &&
840 aStringList
.hasElements() && !aDefText
.isEmpty() )
842 auto nIndex
= comphelper::findValue(aStringList
, aDefText
);
844 mnSelEntry
= static_cast< sal_Int16
>( nIndex
+ 1 ); // 1-based
846 maMultiSel
.resize( 1, mnSelEntry
- 1 );
849 // convert combobox without dropdown button to Excel listbox
850 if( !aCtrlProp
.GetBoolProperty( "Dropdown" ) )
851 mnObjType
= EXC_OBJTYPE_LISTBOX
;
855 case FormCompType::SCROLLBAR
:
857 sal_Int32 nApiValue
= 0;
858 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMin" ) )
859 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
860 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValueMax" ) )
861 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MAX
);
862 if( aCtrlProp
.GetProperty( nApiValue
, "ScrollValue" ) )
863 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
864 if( aCtrlProp
.GetProperty( nApiValue
, "LineIncrement" ) )
865 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
866 if( aCtrlProp
.GetProperty( nApiValue
, "BlockIncrement" ) )
867 mnScrollPage
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
868 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
869 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
873 case FormCompType::SPINBUTTON
:
875 sal_Int32 nApiValue
= 0;
876 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMin" ) )
877 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
878 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValueMax" ) )
879 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MAX
);
880 if( aCtrlProp
.GetProperty( nApiValue
, "SpinValue" ) )
881 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
882 if( aCtrlProp
.GetProperty( nApiValue
, "SpinIncrement" ) )
883 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
884 if( aCtrlProp
.GetProperty( nApiValue
, "Orientation" ) )
885 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
891 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( xShape
);
892 if( xCtrlModel
.is() )
894 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY
);
897 Reference
< XServiceInfo
> xServInfo( xBindable
->getValueBinding(), UNO_QUERY
);
898 if( xServInfo
.is() && xServInfo
->supportsService( SC_SERVICENAME_VALBIND
) )
900 ScfPropertySet
aBindProp( xServInfo
);
901 CellAddress aApiAddress
;
902 if( aBindProp
.GetProperty( aApiAddress
, SC_UNONAME_BOUNDCELL
) )
904 ScUnoConversion::FillScAddress( mxCellLinkAddress
, aApiAddress
);
905 if( SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
) )
906 lcl_GetFromTo( rRoot
, pSdrObj
->GetLogicRect(), mxCellLinkAddress
.Tab(), maAreaFrom
, maAreaTo
, true );
914 ConvertSheetLinks( xShape
);
917 bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor
& rEvent
)
919 return XclMacroHelper::SetMacroLink( rEvent
, meEventType
);
922 void XclExpTbxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
926 // *** Push buttons, labels ***
928 case EXC_OBJTYPE_BUTTON
:
929 case EXC_OBJTYPE_LABEL
:
930 // ftMacro - macro link
931 WriteMacroSubRec( rStrm
);
934 // *** Check boxes, option buttons ***
936 case EXC_OBJTYPE_CHECKBOX
:
937 case EXC_OBJTYPE_OPTIONBUTTON
:
939 // ftCbls - box properties
940 sal_uInt16 nStyle
= 0;
941 ::set_flag( nStyle
, EXC_OBJ_CHECKBOX_FLAT
, mbFlatButton
);
943 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 12 );
945 rStrm
.WriteZeroBytes( 8 );
949 // ftMacro - macro link
950 WriteMacroSubRec( rStrm
);
951 // ftCblsFmla subrecord - cell link
952 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJCBLSFMLA
);
954 // ftCblsData subrecord - box properties, again
955 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 8 );
957 rStrm
.WriteZeroBytes( 4 );
963 // *** List boxes, combo boxes ***
965 case EXC_OBJTYPE_LISTBOX
:
966 case EXC_OBJTYPE_DROPDOWN
:
968 sal_uInt16 nEntryCount
= GetSourceEntryCount();
970 // ftSbs subrecord - Scroll bars
971 sal_Int32 nLineHeight
= XclTools::GetHmmFromTwips( 200 ); // always 10pt
972 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
973 mnLineCount
= static_cast< sal_uInt16
>( mnHeight
/ nLineHeight
);
976 sal_uInt16 nInvisLines
= (nEntryCount
>= mnLineCount
) ? (nEntryCount
- mnLineCount
) : 0;
977 mnScrollMax
= limit_cast
< sal_uInt16
>( nInvisLines
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
979 mnScrollPage
= limit_cast
< sal_uInt16
>( mnLineCount
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
983 // ftMacro - macro link
984 WriteMacroSubRec( rStrm
);
985 // ftSbsFmla subrecord - cell link
986 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
988 // ftLbsData - source data range and box properties
989 sal_uInt16 nStyle
= 0;
990 ::insert_value( nStyle
, mbMultiSel
? EXC_OBJ_LISTBOX_MULTI
: EXC_OBJ_LISTBOX_SINGLE
, 4, 2 );
991 ::set_flag( nStyle
, EXC_OBJ_LISTBOX_FLAT
, mbFlatBorder
);
993 rStrm
.StartRecord( EXC_ID_OBJLBSDATA
, 0 );
995 if( const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr() )
997 rStrm
<< static_cast< sal_uInt16
>( (pSrcRange
->GetSize() + 7) & 0xFFFE );
998 WriteFormula( rStrm
, *pSrcRange
);
1001 rStrm
<< sal_uInt16( 0 );
1003 rStrm
<< nEntryCount
<< mnSelEntry
<< nStyle
<< sal_uInt16( 0 );
1004 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
1008 ScfUInt8Vec
aSelEx( nEntryCount
, 0 );
1009 for( const auto& rItem
: maMultiSel
)
1010 if( rItem
< nEntryCount
)
1011 aSelEx
[ rItem
] = 1;
1012 rStrm
.Write( aSelEx
.data(), aSelEx
.size() );
1015 else if( mnObjType
== EXC_OBJTYPE_DROPDOWN
)
1017 rStrm
<< sal_uInt16( 0 ) << mnLineCount
<< sal_uInt16( 0 ) << sal_uInt16( 0 );
1024 // *** Spin buttons, scrollbars ***
1026 case EXC_OBJTYPE_SPIN
:
1027 case EXC_OBJTYPE_SCROLLBAR
:
1029 // ftSbs subrecord - scroll bars
1031 // ftMacro - macro link
1032 WriteMacroSubRec( rStrm
);
1033 // ftSbsFmla subrecord - cell link
1034 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
1038 // *** Group boxes ***
1040 case EXC_OBJTYPE_GROUPBOX
:
1042 // ftMacro - macro link
1043 WriteMacroSubRec( rStrm
);
1045 // ftGboData subrecord - group box properties
1046 sal_uInt16 nStyle
= 0;
1047 ::set_flag( nStyle
, EXC_OBJ_GROUPBOX_FLAT
, mbFlatBorder
);
1049 rStrm
.StartRecord( EXC_ID_OBJGBODATA
, 6 );
1050 rStrm
<< sal_uInt32( 0 )
1058 void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
)
1060 if( const XclTokenArray
* pCellLink
= GetCellLinkTokArr() )
1061 WriteFormulaSubRec( rStrm
, nSubRecId
, *pCellLink
);
1064 void XclExpTbxControlObj::WriteSbs( XclExpStream
& rStrm
)
1066 sal_uInt16 nOrient
= 0;
1067 ::set_flag( nOrient
, EXC_OBJ_SCROLLBAR_HOR
, mbScrollHor
);
1068 sal_uInt16 nStyle
= EXC_OBJ_SCROLLBAR_DEFFLAGS
;
1069 ::set_flag( nStyle
, EXC_OBJ_SCROLLBAR_FLAT
, mbFlatButton
);
1071 rStrm
.StartRecord( EXC_ID_OBJSBS
, 20 );
1072 rStrm
<< sal_uInt32( 0 ) // reserved
1073 << mnScrollValue
// thumb position
1074 << mnScrollMin
// thumb min pos
1075 << mnScrollMax
// thumb max pos
1076 << mnScrollStep
// line increment
1077 << mnScrollPage
// page increment
1078 << nOrient
// 0 = vertical, 1 = horizontal
1079 << sal_uInt16( 15 ) // thumb width
1080 << nStyle
; // flags/style
1084 void XclExpTbxControlObj::setShapeId(sal_Int32 aShapeId
)
1086 mnShapeId
= aShapeId
;
1091 /// Handles the VML export of form controls (e.g. checkboxes).
1092 class VmlFormControlExporter
: public oox::vml::VMLExport
1094 sal_uInt16 m_nObjType
;
1095 tools::Rectangle m_aAreaFrom
;
1096 tools::Rectangle m_aAreaTo
;
1098 OUString m_aMacroName
;
1101 VmlFormControlExporter(const sax_fastparser::FSHelperPtr
& p
, sal_uInt16 nObjType
,
1102 const tools::Rectangle
& rAreaFrom
, const tools::Rectangle
& rAreaTo
,
1103 const OUString
& rLabel
, const OUString
& rMacroName
);
1106 using VMLExport::StartShape
;
1107 sal_Int32
StartShape() override
;
1108 using VMLExport::EndShape
;
1109 void EndShape(sal_Int32 nShapeElement
) override
;
1112 VmlFormControlExporter::VmlFormControlExporter(const sax_fastparser::FSHelperPtr
& p
,
1113 sal_uInt16 nObjType
,
1114 const tools::Rectangle
& rAreaFrom
,
1115 const tools::Rectangle
& rAreaTo
,
1116 const OUString
& rLabel
, const OUString
& rMacroName
)
1118 , m_nObjType(nObjType
)
1119 , m_aAreaFrom(rAreaFrom
)
1120 , m_aAreaTo(rAreaTo
)
1122 , m_aMacroName(rMacroName
)
1126 sal_Int32
VmlFormControlExporter::StartShape()
1129 AddShapeAttribute(XML_type
, "#_x0000_t201");
1130 return VMLExport::StartShape();
1133 void VmlFormControlExporter::EndShape(sal_Int32 nShapeElement
)
1135 sax_fastparser::FSHelperPtr pVmlDrawing
= GetFS();
1137 pVmlDrawing
->startElement(FSNS(XML_v
, XML_textbox
));
1138 pVmlDrawing
->startElement(XML_div
);
1139 pVmlDrawing
->write(m_aLabel
);
1140 pVmlDrawing
->endElement(XML_div
);
1141 pVmlDrawing
->endElement(FSNS(XML_v
, XML_textbox
));
1143 OString aObjectType
;
1146 case EXC_OBJTYPE_CHECKBOX
:
1147 aObjectType
= "Checkbox";
1149 case EXC_OBJTYPE_BUTTON
:
1150 aObjectType
= "Button";
1153 pVmlDrawing
->startElement(FSNS(XML_x
, XML_ClientData
), XML_ObjectType
, aObjectType
);
1155 = OString::number(m_aAreaFrom
.Left()) + ", " + OString::number(m_aAreaFrom
.Top()) + ", "
1156 + OString::number(m_aAreaFrom
.Right()) + ", " + OString::number(m_aAreaFrom
.Bottom()) + ", "
1157 + OString::number(m_aAreaTo
.Left()) + ", " + OString::number(m_aAreaTo
.Top()) + ", "
1158 + OString::number(m_aAreaTo
.Right()) + ", " + OString::number(m_aAreaTo
.Bottom());
1159 XclXmlUtils::WriteElement(pVmlDrawing
, FSNS(XML_x
, XML_Anchor
), aAnchor
);
1161 if (!m_aMacroName
.isEmpty())
1163 XclXmlUtils::WriteElement(pVmlDrawing
, FSNS(XML_x
, XML_FmlaMacro
), m_aMacroName
);
1166 // XclExpOcxControlObj::WriteSubRecs() has the same fixed values.
1167 if (m_nObjType
== EXC_OBJTYPE_BUTTON
)
1169 XclXmlUtils::WriteElement(pVmlDrawing
, FSNS(XML_x
, XML_TextHAlign
), "Center");
1171 XclXmlUtils::WriteElement(pVmlDrawing
, FSNS(XML_x
, XML_TextVAlign
), "Center");
1173 pVmlDrawing
->endElement(FSNS(XML_x
, XML_ClientData
));
1174 VMLExport::EndShape(nShapeElement
);
1179 /// Save into xl/drawings/vmlDrawing1.vml.
1180 void XclExpTbxControlObj::SaveVml(XclExpXmlStream
& rStrm
)
1182 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1183 tools::Rectangle aAreaFrom
;
1184 tools::Rectangle aAreaTo
;
1185 // Unlike XclExpTbxControlObj::SaveXml(), this is not calculated in EMUs.
1186 lcl_GetFromTo(mrRoot
, pObj
->GetLogicRect(), GetTab(), aAreaFrom
, aAreaTo
);
1187 VmlFormControlExporter
aFormControlExporter(rStrm
.GetCurrentStream(), GetObjType(), aAreaFrom
,
1188 aAreaTo
, msLabel
, GetMacroName());
1189 aFormControlExporter
.AddSdrObject(*pObj
, /*bIsFollowingTextFlow=*/false, /*eHOri=*/-1,
1190 /*eVOri=*/-1, /*eHRel=*/-1, /*eVRel=*/-1,
1191 /*pWrapAttrList=*/nullptr, /*bOOxmlExport=*/true);
1194 // save into xl\drawings\drawing1.xml
1195 void XclExpTbxControlObj::SaveXml( XclExpXmlStream
& rStrm
)
1197 sax_fastparser::FSHelperPtr
& pDrawing
= rStrm
.GetCurrentStream();
1199 pDrawing
->startElement(FSNS(XML_mc
, XML_AlternateContent
),
1200 FSNS(XML_xmlns
, XML_mc
), rStrm
.getNamespaceURL(OOX_NS(mce
)));
1201 pDrawing
->startElement(FSNS(XML_mc
, XML_Choice
),
1202 FSNS(XML_xmlns
, XML_a14
), rStrm
.getNamespaceURL(OOX_NS(a14
)),
1203 XML_Requires
, "a14");
1205 pDrawing
->startElement(FSNS(XML_xdr
, XML_twoCellAnchor
), XML_editAs
, "oneCell");
1207 pDrawing
->startElement(FSNS(XML_xdr
, XML_from
));
1208 lcl_WriteAnchorVertex(pDrawing
, maAreaFrom
);
1209 pDrawing
->endElement(FSNS(XML_xdr
, XML_from
));
1210 pDrawing
->startElement(FSNS(XML_xdr
, XML_to
));
1211 lcl_WriteAnchorVertex(pDrawing
, maAreaTo
);
1212 pDrawing
->endElement(FSNS(XML_xdr
, XML_to
));
1214 pDrawing
->startElement(FSNS(XML_xdr
, XML_sp
));
1217 pDrawing
->startElement(FSNS(XML_xdr
, XML_nvSpPr
));
1219 pDrawing
->singleElement(FSNS(XML_xdr
, XML_cNvPr
),
1220 XML_id
, OString::number(mnShapeId
).getStr(),
1221 XML_name
, msCtrlName
, // control name
1222 XML_descr
, msLabel
, // description as alt text
1223 XML_hidden
, mbVisible
? "0" : "1");
1224 pDrawing
->singleElement(FSNS(XML_xdr
, XML_cNvSpPr
));
1226 pDrawing
->endElement(FSNS(XML_xdr
, XML_nvSpPr
));
1229 pDrawing
->startElement(FSNS(XML_xdr
, XML_spPr
));
1232 pDrawing
->startElement(FSNS(XML_a
, XML_xfrm
));
1234 pDrawing
->singleElement(FSNS(XML_a
, XML_off
),
1237 pDrawing
->singleElement(FSNS(XML_a
, XML_ext
),
1241 pDrawing
->endElement(FSNS(XML_a
, XML_xfrm
));
1244 pDrawing
->startElement(FSNS(XML_a
, XML_prstGeom
), XML_prst
, "rect");
1246 pDrawing
->singleElement(FSNS(XML_a
, XML_avLst
));
1248 pDrawing
->endElement(FSNS(XML_a
, XML_prstGeom
));
1250 pDrawing
->endElement(FSNS(XML_xdr
, XML_spPr
));
1254 pDrawing
->startElement(FSNS(XML_xdr
, XML_txBody
));
1256 #define DEFLRINS 254
1257 #define DEFTBINS 127
1258 sal_Int32 nLeft
, nRight
, nTop
, nBottom
;
1259 nLeft
= nRight
= DEFLRINS
;
1260 nTop
= nBottom
= DEFTBINS
;
1262 // top inset looks a bit different compared to ppt export
1263 // check if something related doesn't work as expected
1264 Reference
< XPropertySet
> rXPropSet(mxShape
, UNO_QUERY
);
1270 mAny
= rXPropSet
->getPropertyValue("TextLeftDistance");
1271 if (mAny
.hasValue())
1274 mAny
= rXPropSet
->getPropertyValue("TextRightDistance");
1275 if (mAny
.hasValue())
1278 mAny
= rXPropSet
->getPropertyValue("TextUpperDistance");
1279 if (mAny
.hasValue())
1282 mAny
= rXPropSet
->getPropertyValue("TextLowerDistance");
1283 if (mAny
.hasValue())
1290 // Specifies the inset of the bounding rectangle.
1291 // Insets are used just as internal margins for text boxes within shapes.
1292 // If this attribute is omitted, then a value of 45720 or 0.05 inches is implied.
1293 pDrawing
->startElementNS(XML_a
, XML_bodyPr
,
1294 XML_lIns
, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nLeft
)), nLeft
!= DEFLRINS
),
1295 XML_rIns
, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nRight
)), nRight
!= DEFLRINS
),
1296 XML_tIns
, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nTop
)), nTop
!= DEFTBINS
),
1297 XML_bIns
, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nBottom
)), nBottom
!= DEFTBINS
),
1301 bool bTextAutoGrowHeight
= false;
1307 mAny
= rXPropSet
->getPropertyValue("TextAutoGrowHeight");
1308 if (mAny
.hasValue())
1309 mAny
>>= bTextAutoGrowHeight
;
1315 pDrawing
->singleElementNS(XML_a
, (bTextAutoGrowHeight
? XML_spAutoFit
: XML_noAutofit
));
1318 pDrawing
->endElementNS(XML_a
, XML_bodyPr
);
1321 pDrawing
->startElementNS(XML_a
, XML_p
);
1322 pDrawing
->startElementNS(XML_a
, XML_r
);
1323 pDrawing
->startElementNS(XML_a
, XML_t
);
1324 pDrawing
->write(msLabel
);
1325 pDrawing
->endElementNS(XML_a
, XML_t
);
1326 pDrawing
->endElementNS(XML_a
, XML_r
);
1327 pDrawing
->endElementNS(XML_a
, XML_p
);
1330 pDrawing
->endElement(FSNS(XML_xdr
, XML_txBody
));
1333 pDrawing
->endElement(FSNS(XML_xdr
, XML_sp
));
1334 pDrawing
->singleElement(FSNS(XML_xdr
, XML_clientData
));
1336 pDrawing
->endElement(FSNS(XML_xdr
, XML_twoCellAnchor
));
1337 pDrawing
->endElement( FSNS( XML_mc
, XML_Choice
) );
1338 pDrawing
->endElement( FSNS( XML_mc
, XML_AlternateContent
) );
1341 // output into ctrlProp1.xml
1342 OUString
XclExpTbxControlObj::SaveControlPropertiesXml(XclExpXmlStream
& rStrm
) const
1344 OUString sIdFormControlPr
;
1348 case EXC_OBJTYPE_CHECKBOX
:
1350 const sal_Int32 nDrawing
= DrawingML::getNewDrawingUniqueId();
1351 sax_fastparser::FSHelperPtr pFormControl
= rStrm
.CreateOutputStream(
1352 XclXmlUtils::GetStreamName( "xl/", "ctrlProps/ctrlProps", nDrawing
),
1353 XclXmlUtils::GetStreamName( "../", "ctrlProps/ctrlProps", nDrawing
),
1354 rStrm
.GetCurrentStream()->getOutputStream(),
1355 "application/vnd.ms-excel.controlproperties+xml",
1356 oox::getRelationship(Relationship::CTRLPROP
),
1357 &sIdFormControlPr
);
1359 rStrm
.PushStream( pFormControl
);
1362 // xmlns="http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"
1363 // objectType="CheckBox" checked="Checked" lockText="1" noThreeD="1"/>
1365 pFormControl
->write("<formControlPr xmlns=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\" objectType=\"CheckBox\"");
1366 if (mnState
== EXC_OBJ_CHECKBOX_CHECKED
)
1367 pFormControl
->write(" checked=\"Checked\"");
1369 pFormControl
->write(" autoLine=\"false\"");
1372 pFormControl
->write(" print=\"true\"");
1374 pFormControl
->write(" print=\"false\"");
1376 if (mxCellLinkAddress
.IsValid())
1378 OUString aCellLink
= mxCellLinkAddress
.Format(ScRefFlags::ADDR_ABS
,
1380 ScAddress::Details(::formula::FormulaGrammar::CONV_XL_A1
));
1383 pFormControl
->write(" fmlaLink=\"");
1384 if (aCellLink
.indexOf('!') < 0)
1386 pFormControl
->write(GetTabInfo().GetScTabName(mxCellLinkAddress
.Tab()));
1387 pFormControl
->write("!");
1389 pFormControl
->write(aCellLink
);
1390 pFormControl
->write("\"");
1393 pFormControl
->write(" lockText=\"1\" noThreeD=\"1\"/>");
1398 case EXC_OBJTYPE_BUTTON
:
1400 sal_Int32 nDrawing
= DrawingML::getNewDrawingUniqueId();
1401 sax_fastparser::FSHelperPtr pFormControl
= rStrm
.CreateOutputStream(
1402 XclXmlUtils::GetStreamName("xl/", "ctrlProps/ctrlProps", nDrawing
),
1403 XclXmlUtils::GetStreamName("../", "ctrlProps/ctrlProps", nDrawing
),
1404 rStrm
.GetCurrentStream()->getOutputStream(),
1405 "application/vnd.ms-excel.controlproperties+xml",
1406 oox::getRelationship(Relationship::CTRLPROP
), &sIdFormControlPr
);
1408 pFormControl
->singleElement(XML_formControlPr
, XML_xmlns
,
1409 rStrm
.getNamespaceURL(OOX_NS(xls14Lst
)), XML_objectType
,
1410 "Button", XML_lockText
, "1");
1415 return sIdFormControlPr
;
1418 // output into sheet1.xml
1419 void XclExpTbxControlObj::SaveSheetXml(XclExpXmlStream
& rStrm
, const OUString
& aIdFormControlPr
) const
1423 case EXC_OBJTYPE_CHECKBOX
:
1425 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
1427 rWorksheet
->startElement(FSNS(XML_mc
, XML_AlternateContent
),
1428 FSNS(XML_xmlns
, XML_mc
), rStrm
.getNamespaceURL(OOX_NS(mce
)));
1429 rWorksheet
->startElement(FSNS(XML_mc
, XML_Choice
), XML_Requires
, "x14");
1431 rWorksheet
->startElement(
1433 XML_shapeId
, OString::number(mnShapeId
).getStr(),
1434 FSNS(XML_r
, XML_id
), aIdFormControlPr
,
1435 XML_name
, msLabel
); // text to display with checkbox button
1437 rWorksheet
->write("<controlPr defaultSize=\"0\" locked=\"1\" autoFill=\"0\" autoLine=\"0\" autoPict=\"0\"");
1440 rWorksheet
->write(" print=\"true\"");
1442 rWorksheet
->write(" print=\"false\"");
1444 if (!msCtrlName
.isEmpty())
1446 rWorksheet
->write(" altText=\"");
1447 rWorksheet
->write(msCtrlName
); // alt text
1448 rWorksheet
->write("\"");
1451 rWorksheet
->write(">");
1453 rWorksheet
->startElement(XML_anchor
, XML_moveWithCells
, "true", XML_sizeWithCells
, "false");
1454 rWorksheet
->startElement(XML_from
);
1455 lcl_WriteAnchorVertex(rWorksheet
, maAreaFrom
);
1456 rWorksheet
->endElement(XML_from
);
1457 rWorksheet
->startElement(XML_to
);
1458 lcl_WriteAnchorVertex(rWorksheet
, maAreaTo
);
1459 rWorksheet
->endElement(XML_to
);
1460 rWorksheet
->endElement( XML_anchor
);
1462 rWorksheet
->write("</controlPr>");
1464 rWorksheet
->endElement(XML_control
);
1465 rWorksheet
->endElement( FSNS( XML_mc
, XML_Choice
) );
1466 rWorksheet
->endElement( FSNS( XML_mc
, XML_AlternateContent
) );
1470 case EXC_OBJTYPE_BUTTON
:
1472 sax_fastparser::FSHelperPtr
& rWorksheet
= rStrm
.GetCurrentStream();
1474 rWorksheet
->startElement(FSNS(XML_mc
, XML_AlternateContent
), FSNS(XML_xmlns
, XML_mc
),
1475 rStrm
.getNamespaceURL(OOX_NS(mce
)));
1476 rWorksheet
->startElement(FSNS(XML_mc
, XML_Choice
), XML_Requires
, "x14");
1478 rWorksheet
->startElement(XML_control
, XML_shapeId
, OString::number(mnShapeId
).getStr(),
1479 FSNS(XML_r
, XML_id
), aIdFormControlPr
, XML_name
, msCtrlName
);
1481 OString aMacroName
= GetMacroName().toUtf8();
1482 // Omit the macro attribute if it would be empty.
1483 const char* pMacroName
= aMacroName
.isEmpty() ? nullptr : aMacroName
.getStr();
1484 rWorksheet
->startElement(XML_controlPr
, XML_defaultSize
, "0", XML_print
,
1485 mbPrint
? "true" : "false", XML_autoFill
, "0", XML_autoPict
,
1486 "0", XML_macro
, pMacroName
);
1488 rWorksheet
->startElement(XML_anchor
, XML_moveWithCells
, "true", XML_sizeWithCells
,
1491 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1492 tools::Rectangle aAreaFrom
;
1493 tools::Rectangle aAreaTo
;
1494 lcl_GetFromTo(mrRoot
, pObj
->GetLogicRect(), GetTab(), aAreaFrom
, aAreaTo
,
1497 rWorksheet
->startElement(XML_from
);
1498 lcl_WriteAnchorVertex(rWorksheet
, aAreaFrom
);
1499 rWorksheet
->endElement(XML_from
);
1500 rWorksheet
->startElement(XML_to
);
1501 lcl_WriteAnchorVertex(rWorksheet
, aAreaTo
);
1502 rWorksheet
->endElement(XML_to
);
1503 rWorksheet
->endElement(XML_anchor
);
1505 rWorksheet
->endElement(XML_controlPr
);
1507 rWorksheet
->endElement(XML_control
);
1508 rWorksheet
->endElement(FSNS(XML_mc
, XML_Choice
));
1509 rWorksheet
->endElement(FSNS(XML_mc
, XML_AlternateContent
));
1517 XclExpChartObj::XclExpChartObj( XclExpObjectManager
& rObjMgr
, Reference
< XShape
> const & xShape
, const tools::Rectangle
* pChildAnchor
, ScDocument
* pDoc
) :
1518 XclObj( rObjMgr
, EXC_OBJTYPE_CHART
),
1519 XclExpRoot( rObjMgr
.GetRoot() ), mxShape( xShape
),
1522 // create the MSODRAWING record contents for the chart object
1523 mrEscherEx
.OpenContainer( ESCHER_SpContainer
);
1524 mrEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, ShapeFlag::HaveAnchor
| ShapeFlag::HaveShapeProperty
);
1525 EscherPropertyContainer aPropOpt
;
1526 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01040104 );
1527 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 );
1528 aPropOpt
.AddOpt( ESCHER_Prop_fillColor
, 0x0800004E );
1529 aPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0x0800004D );
1530 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00110010 );
1531 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x0800004D );
1532 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
1533 aPropOpt
.AddOpt( ESCHER_Prop_fshadowObscured
, 0x00020000 );
1534 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x00080000 );
1535 aPropOpt
.Commit( mrEscherEx
.GetStream() );
1538 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
);
1539 ImplWriteAnchor( pSdrObj
, pChildAnchor
);
1541 // client data (the following OBJ record)
1542 mrEscherEx
.AddAtom( 0, ESCHER_ClientData
);
1543 mrEscherEx
.CloseContainer(); // ESCHER_SpContainer
1544 mrEscherEx
.UpdateDffFragmentEnd();
1546 // load the chart OLE object
1547 if( SdrOle2Obj
* pSdrOleObj
= dynamic_cast< SdrOle2Obj
* >( pSdrObj
) )
1548 svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj
->GetObjRef() );
1550 // create the chart substream object
1551 ScfPropertySet
aShapeProp( xShape
);
1552 css::awt::Rectangle aBoundRect
;
1553 aShapeProp
.GetProperty( aBoundRect
, "BoundRect" );
1554 tools::Rectangle
aChartRect( Point( aBoundRect
.X
, aBoundRect
.Y
), Size( aBoundRect
.Width
, aBoundRect
.Height
) );
1555 mxChart
= std::make_shared
<XclExpChart
>(GetRoot(), GetChartDoc(), aChartRect
);
1558 XclExpChartObj::~XclExpChartObj()
1562 void XclExpChartObj::Save( XclExpStream
& rStrm
)
1564 // content of OBJ record
1565 XclObj::Save( rStrm
);
1567 mxChart
->Save( rStrm
);
1570 void XclExpChartObj::SaveXml( XclExpXmlStream
& rStrm
)
1572 sax_fastparser::FSHelperPtr pDrawing
= rStrm
.GetCurrentStream();
1574 // FIXME: two cell? it seems the two cell anchor is incorrect.
1575 pDrawing
->startElement( FSNS( XML_xdr
, XML_twoCellAnchor
), // OOXTODO: oneCellAnchor, absoluteAnchor
1576 XML_editAs
, "oneCell" );
1577 Reference
< XPropertySet
> xPropSet( mxShape
, UNO_QUERY
);
1580 XclObjAny::WriteFromTo( rStrm
, mxShape
, GetTab() );
1581 ChartExport
aChartExport(XML_xdr
, pDrawing
, GetChartDoc(), &rStrm
, drawingml::DOCUMENT_XLSX
);
1582 auto pURLTransformer
= std::make_shared
<ScURLTransformer
>(*mpDoc
);
1583 aChartExport
.SetURLTranslator(pURLTransformer
);
1584 static sal_Int32 nChartCount
= 0;
1586 sal_Int32 nID
= rStrm
.GetUniqueId();
1587 aChartExport
.WriteChartObj( mxShape
, nID
, nChartCount
);
1588 // TODO: get the correcto chart number
1591 pDrawing
->singleElement( FSNS( XML_xdr
, XML_clientData
)
1592 // OOXTODO: XML_fLocksWithSheet
1593 // OOXTODO: XML_fPrintsWithSheet
1595 pDrawing
->endElement( FSNS( XML_xdr
, XML_twoCellAnchor
) );
1598 css::uno::Reference
<css::chart::XChartDocument
> XclExpChartObj::GetChartDoc() const
1600 SdrObject
* pObj
= SdrObject::getSdrObjectFromXShape(mxShape
);
1601 if (!pObj
|| pObj
->GetObjIdentifier() != OBJ_OLE2
)
1603 // May load here - makes sure that we are working with actually loaded OLE object
1604 return css::uno::Reference
<css::chart::XChartDocument
>(
1605 static_cast<SdrOle2Obj
*>(pObj
)->getXModel(), css::uno::UNO_QUERY
);
1608 XclExpNote::XclExpNote(const XclExpRoot
& rRoot
, const ScAddress
& rScPos
,
1609 const ScPostIt
* pScNote
, std::u16string_view rAddText
)
1610 : XclExpRecord(EXC_ID_NOTE
)
1613 , mnObjId(EXC_OBJ_INVALID_ID
)
1614 , mbVisible(pScNote
&& pScNote
->IsCaptionShown())
1615 , meTHA(SDRTEXTHORZADJUST_LEFT
)
1616 , meTVA(SDRTEXTVERTADJUST_TOP
)
1617 , mbAutoScale(false)
1620 , mbColHidden(false)
1621 , mbRowHidden(false)
1623 // get the main note text
1627 aNoteText
= pScNote
->GetText();
1628 const EditTextObject
*pEditObj
= pScNote
->GetEditTextObject();
1630 mpNoteContents
= XclExpStringHelper::CreateString( rRoot
, *pEditObj
);
1632 // append additional text
1633 aNoteText
= ScGlobal::addToken( aNoteText
, rAddText
, '\n', 2 );
1635 // initialize record dependent on BIFF type
1636 switch( rRoot
.GetBiff() )
1639 maNoteText
= OUStringToOString(aNoteText
, rRoot
.GetTextEncoding());
1644 // TODO: additional text
1647 if( SdrCaptionObj
* pCaption
= pScNote
->GetOrCreateCaption( maScPos
) )
1649 lcl_GetFromTo( rRoot
, pCaption
->GetLogicRect(), maScPos
.Tab(), maCommentFrom
, maCommentTo
);
1650 if( const OutlinerParaObject
* pOPO
= pCaption
->GetOutlinerParaObject() )
1651 mnObjId
= rRoot
.GetObjectManager().AddObj( std::make_unique
<XclObjComment
>( rRoot
.GetObjectManager(), pCaption
->GetLogicRect(), pOPO
->GetTextObject(), pCaption
, mbVisible
, maScPos
, maCommentFrom
, maCommentTo
) );
1653 SfxItemSet aItemSet
= pCaption
->GetMergedItemSet();
1654 meTVA
= pCaption
->GetTextVerticalAdjust();
1655 meTHA
= pCaption
->GetTextHorizontalAdjust();
1656 mbAutoScale
= pCaption
->GetFitToSize() != drawing::TextFitToSizeType_NONE
;
1657 mbLocked
= pCaption
->IsMoveProtect() || pCaption
->IsResizeProtect();
1659 // AutoFill style would change if Postit.cxx object creation values are changed
1660 OUString
aCol(aItemSet
.Get(XATTR_FILLCOLOR
).GetValue());
1661 mbAutoFill
= aCol
.isEmpty() && (aItemSet
.Get(XATTR_FILLSTYLE
).GetValue() == drawing::FillStyle_SOLID
);
1662 mbRowHidden
= (rRoot
.GetDoc().RowHidden(maScPos
.Row(),maScPos
.Tab()));
1663 mbColHidden
= (rRoot
.GetDoc().ColHidden(maScPos
.Col(),maScPos
.Tab()));
1665 // stAuthor (variable): An XLUnicodeString that specifies the name of the comment
1666 // author. String length MUST be greater than or equal to 1 and less than or equal
1668 if( pScNote
->GetAuthor().isEmpty() )
1669 maAuthor
= XclExpString( " " );
1671 maAuthor
= XclExpString( pScNote
->GetAuthor(), XclStrFlags::NONE
, 54 );
1674 SetRecSize( 9 + maAuthor
.GetSize() );
1678 default: DBG_ERROR_BIFF();
1682 void XclExpNote::Save( XclExpStream
& rStrm
)
1684 switch( rStrm
.GetRoot().GetBiff() )
1688 // write the NOTE record directly, there may be the need to create more than one
1689 const char* pcBuffer
= maNoteText
.getStr();
1690 sal_uInt16 nCharsLeft
= static_cast< sal_uInt16
>( maNoteText
.getLength() );
1694 sal_uInt16 nWriteChars
= ::std::min( nCharsLeft
, EXC_NOTE5_MAXLEN
);
1696 rStrm
.StartRecord( EXC_ID_NOTE
, 6 + nWriteChars
);
1697 if( pcBuffer
== maNoteText
.getStr() )
1699 // first record: row, col, length of complete text
1700 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1701 << static_cast< sal_uInt16
>( maScPos
.Col() )
1702 << nCharsLeft
; // still contains full length
1706 // next records: -1, 0, length of current text segment
1707 rStrm
<< sal_uInt16( 0xFFFF )
1711 rStrm
.Write( pcBuffer
, nWriteChars
);
1714 pcBuffer
+= nWriteChars
;
1715 nCharsLeft
= nCharsLeft
- nWriteChars
;
1721 if( mnObjId
!= EXC_OBJ_INVALID_ID
)
1722 XclExpRecord::Save( rStrm
);
1725 default: DBG_ERROR_BIFF();
1729 void XclExpNote::WriteBody( XclExpStream
& rStrm
)
1731 // BIFF5/BIFF7 is written separately
1732 OSL_ENSURE_BIFF( rStrm
.GetRoot().GetBiff() == EXC_BIFF8
);
1734 sal_uInt16 nFlags
= 0;
1735 ::set_flag( nFlags
, EXC_NOTE_VISIBLE
, mbVisible
);
1737 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
1738 << static_cast< sal_uInt16
>( maScPos
.Col() )
1745 void XclExpNote::WriteXml( sal_Int32 nAuthorId
, XclExpXmlStream
& rStrm
)
1747 sax_fastparser::FSHelperPtr rComments
= rStrm
.GetCurrentStream();
1749 rComments
->startElement( XML_comment
,
1750 XML_ref
, XclXmlUtils::ToOString(mrRoot
.GetDoc(), maScPos
),
1751 XML_authorId
, OString::number(nAuthorId
)
1752 // OOXTODO: XML_guid
1754 rComments
->startElement(XML_text
);
1755 // OOXTODO: phoneticPr, rPh, r
1756 if( mpNoteContents
)
1757 mpNoteContents
->WriteXml( rStrm
);
1758 rComments
->endElement( XML_text
);
1761 Export of commentPr is disabled, since the current (Oct 2010)
1762 version of MSO 2010 doesn't yet support commentPr
1764 #if 1//def XLSX_OOXML_FUTURE
1765 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1767 rComments
->startElement(FSNS(XML_mc
, XML_AlternateContent
));
1768 rComments
->startElement(FSNS(XML_mc
, XML_Choice
), XML_Requires
, "v2");
1769 rComments
->startElement( XML_commentPr
,
1770 XML_autoFill
, ToPsz( mbAutoFill
),
1771 XML_autoScale
, ToPsz( mbAutoScale
),
1772 XML_colHidden
, ToPsz( mbColHidden
),
1773 XML_locked
, ToPsz( mbLocked
),
1774 XML_rowHidden
, ToPsz( mbRowHidden
),
1775 XML_textHAlign
, ToHorizAlign( meTHA
),
1776 XML_textVAlign
, ToVertAlign( meTVA
) );
1777 rComments
->startElement(XML_anchor
, XML_moveWithCells
, "false", XML_sizeWithCells
, "false");
1778 rComments
->startElement(FSNS(XML_xdr
, XML_from
));
1779 lcl_WriteAnchorVertex( rComments
, maCommentFrom
);
1780 rComments
->endElement( FSNS( XML_xdr
, XML_from
) );
1781 rComments
->startElement(FSNS(XML_xdr
, XML_to
));
1782 lcl_WriteAnchorVertex( rComments
, maCommentTo
);
1783 rComments
->endElement( FSNS( XML_xdr
, XML_to
) );
1784 rComments
->endElement( XML_anchor
);
1785 rComments
->endElement( XML_commentPr
);
1787 rComments
->endElement( FSNS( XML_mc
, XML_Choice
) );
1788 rComments
->startElement(FSNS(XML_mc
, XML_Fallback
));
1789 // Any fallback code ?
1790 rComments
->endElement( FSNS( XML_mc
, XML_Fallback
) );
1791 rComments
->endElement( FSNS( XML_mc
, XML_AlternateContent
) );
1794 rComments
->endElement( XML_comment
);
1797 XclMacroHelper::XclMacroHelper( const XclExpRoot
& rRoot
) :
1798 XclExpControlHelper( rRoot
)
1802 XclMacroHelper::~XclMacroHelper()
1806 void XclMacroHelper::WriteMacroSubRec( XclExpStream
& rStrm
)
1809 WriteFormulaSubRec( rStrm
, EXC_ID_OBJMACRO
, *mxMacroLink
);
1812 const OUString
& XclMacroHelper::GetMacroName() const { return maMacroName
; }
1815 XclMacroHelper::SetMacroLink( const ScriptEventDescriptor
& rEvent
, const XclTbxEventType
& nEventType
)
1817 maMacroName
= XclControlHelper::ExtractFromMacroDescriptor(rEvent
, nEventType
);
1818 if (!maMacroName
.isEmpty())
1820 return SetMacroLink(maMacroName
);
1826 XclMacroHelper::SetMacroLink( const OUString
& rMacroName
)
1828 // OOXML documents do not store any defined name for VBA macros (while BIFF documents do).
1829 bool bOOXML
= GetOutput() == EXC_OUTPUT_XML_2007
;
1830 if (!rMacroName
.isEmpty() && !bOOXML
)
1832 sal_uInt16 nExtSheet
= GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC
);
1834 = GetNameManager().InsertMacroCall(rMacroName
, /*bVBasic=*/true, /*bFunc=*/false);
1835 mxMacroLink
= GetFormulaCompiler().CreateNameXFormula( nExtSheet
, nNameIdx
);
1841 XclExpShapeObj::XclExpShapeObj( XclExpObjectManager
& rRoot
, css::uno::Reference
< css::drawing::XShape
> const & xShape
, ScDocument
* pDoc
) :
1842 XclObjAny( rRoot
, xShape
, pDoc
),
1843 XclMacroHelper( rRoot
)
1845 if (SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape(xShape
))
1847 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pSdrObj
);
1848 if ( pInfo
&& !pInfo
->GetMacro().isEmpty() )
1849 // 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
1850 // SetMacroLink( XclControlHelper::GetXclMacroName( pInfo->GetMacro(), rRoot.GetDocShell() ) );
1851 SetMacroLink( XclTools::GetXclMacroName( pInfo
->GetMacro() ) );
1855 XclExpShapeObj::~XclExpShapeObj()
1859 void XclExpShapeObj::WriteSubRecs( XclExpStream
& rStrm
)
1861 XclObjAny::WriteSubRecs( rStrm
);
1862 WriteMacroSubRec( rStrm
);
1865 XclExpComments::XclExpComments( SCTAB nTab
, XclExpRecordList
< XclExpNote
>& rNotes
)
1866 : mnTab( nTab
), mrNotes( rNotes
)
1870 void XclExpComments::SaveXml( XclExpXmlStream
& rStrm
)
1872 if( mrNotes
.IsEmpty() )
1875 sax_fastparser::FSHelperPtr rComments
= rStrm
.CreateOutputStream(
1876 XclXmlUtils::GetStreamName( "xl/", "comments", mnTab
+ 1 ),
1877 XclXmlUtils::GetStreamName( "../", "comments", mnTab
+ 1 ),
1878 rStrm
.GetCurrentStream()->getOutputStream(),
1879 "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
1880 oox::getRelationship(Relationship::COMMENTS
));
1881 rStrm
.PushStream( rComments
);
1883 if( rStrm
.getVersion() == oox::core::ISOIEC_29500_2008
)
1884 rComments
->startElement( XML_comments
,
1885 XML_xmlns
, rStrm
.getNamespaceURL(OOX_NS(xls
)),
1886 FSNS(XML_xmlns
, XML_mc
), rStrm
.getNamespaceURL(OOX_NS(mce
)),
1887 FSNS(XML_xmlns
, XML_xdr
), rStrm
.getNamespaceURL(OOX_NS(dmlSpreadDr
)),
1888 FSNS(XML_xmlns
, XML_v2
), rStrm
.getNamespaceURL(OOX_NS(mceTest
)),
1889 FSNS( XML_mc
, XML_Ignorable
), "v2" );
1891 rComments
->startElement( XML_comments
,
1892 XML_xmlns
, rStrm
.getNamespaceURL(OOX_NS(xls
)),
1893 FSNS(XML_xmlns
, XML_xdr
), rStrm
.getNamespaceURL(OOX_NS(dmlSpreadDr
)) );
1895 rComments
->startElement(XML_authors
);
1897 typedef std::set
<OUString
> Authors
;
1900 size_t nNotes
= mrNotes
.GetSize();
1901 for( size_t i
= 0; i
< nNotes
; ++i
)
1903 aAuthors
.insert( XclXmlUtils::ToOUString( mrNotes
.GetRecord( i
)->GetAuthor() ) );
1906 for( const auto& rAuthor
: aAuthors
)
1908 rComments
->startElement(XML_author
);
1909 rComments
->writeEscaped( rAuthor
);
1910 rComments
->endElement( XML_author
);
1913 rComments
->endElement( XML_authors
);
1914 rComments
->startElement(XML_commentList
);
1916 Authors::const_iterator aAuthorsBegin
= aAuthors
.begin();
1917 for( size_t i
= 0; i
< nNotes
; ++i
)
1919 XclExpRecordList
< XclExpNote
>::RecordRefType xNote
= mrNotes
.GetRecord( i
);
1920 Authors::const_iterator aAuthor
= aAuthors
.find(
1921 XclXmlUtils::ToOUString( xNote
->GetAuthor() ) );
1922 sal_Int32 nAuthorId
= distance( aAuthorsBegin
, aAuthor
);
1923 xNote
->WriteXml( nAuthorId
, rStrm
);
1926 rComments
->endElement( XML_commentList
);
1927 rComments
->endElement( XML_comments
);
1932 // object manager =============================================================
1934 XclExpObjectManager::XclExpObjectManager( const XclExpRoot
& rRoot
) :
1938 mxEscherEx
= std::make_shared
<XclEscherEx
>( GetRoot(), *this, *mxDffStrm
);
1941 XclExpObjectManager::XclExpObjectManager( const XclExpObjectManager
& rParent
) :
1942 XclExpRoot( rParent
.GetRoot() )
1944 InitStream( false );
1945 mxEscherEx
= std::make_shared
<XclEscherEx
>( GetRoot(), *this, *mxDffStrm
, rParent
.mxEscherEx
.get() );
1948 XclExpObjectManager::~XclExpObjectManager()
1952 XclExpDffAnchorBase
* XclExpObjectManager::CreateDffAnchor() const
1954 return new XclExpDffSheetAnchor( GetRoot() );
1957 rtl::Reference
< XclExpRecordBase
> XclExpObjectManager::CreateDrawingGroup()
1959 return new XclExpMsoDrawingGroup( *mxEscherEx
);
1962 void XclExpObjectManager::StartSheet()
1964 mxObjList
= new XclExpObjList( GetRoot(), *mxEscherEx
);
1967 rtl::Reference
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( const SdrPage
* pSdrPage
)
1970 mxEscherEx
->AddSdrPage( *pSdrPage
, GetOutput() != EXC_OUTPUT_BINARY
);
1971 // the first dummy object may still be open
1972 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1973 while( mxEscherEx
->GetGroupLevel() )
1974 mxEscherEx
->LeaveGroup();
1975 mxObjList
->EndSheet();
1979 rtl::Reference
< XclExpRecordBase
> XclExpObjectManager::ProcessDrawing( const Reference
< XShapes
>& rxShapes
)
1982 mxEscherEx
->AddUnoShapes( rxShapes
, GetOutput() != EXC_OUTPUT_BINARY
);
1983 // the first dummy object may still be open
1984 OSL_ENSURE( mxEscherEx
->GetGroupLevel() <= 1, "XclExpObjectManager::ProcessDrawing - still groups open?" );
1985 while( mxEscherEx
->GetGroupLevel() )
1986 mxEscherEx
->LeaveGroup();
1987 mxObjList
->EndSheet();
1991 void XclExpObjectManager::EndDocument()
1993 mxEscherEx
->EndDocument();
1996 XclExpMsoDrawing
* XclExpObjectManager::GetMsodrawingPerSheet()
1998 return mxObjList
->GetMsodrawingPerSheet();
2001 bool XclExpObjectManager::HasObj() const
2003 return !mxObjList
->empty();
2006 sal_uInt16
XclExpObjectManager::AddObj( std::unique_ptr
<XclObj
> pObjRec
)
2008 return mxObjList
->Add( std::move(pObjRec
) );
2011 std::unique_ptr
<XclObj
> XclExpObjectManager::RemoveLastObj()
2013 return mxObjList
->pop_back();
2016 void XclExpObjectManager::InitStream( bool bTempFile
)
2020 mxTempFile
= std::make_shared
<::utl::TempFile
>();
2021 if( mxTempFile
->IsValid() )
2023 mxTempFile
->EnableKillingFile();
2024 mxDffStrm
= ::utl::UcbStreamHelper::CreateStream( mxTempFile
->GetURL(), StreamMode::STD_READWRITE
);
2029 mxDffStrm
= std::make_unique
<SvMemoryStream
>();
2031 mxDffStrm
->SetEndian( SvStreamEndian::LITTLE
);
2034 XclExpEmbeddedObjectManager::XclExpEmbeddedObjectManager(
2035 const XclExpObjectManager
& rParent
, const Size
& rPageSize
, sal_Int32 nScaleX
, sal_Int32 nScaleY
) :
2036 XclExpObjectManager( rParent
),
2037 maPageSize( rPageSize
),
2038 mnScaleX( nScaleX
),
2043 XclExpDffAnchorBase
* XclExpEmbeddedObjectManager::CreateDffAnchor() const
2045 return new XclExpDffEmbeddedAnchor( GetRoot(), maPageSize
, mnScaleX
, mnScaleY
);
2048 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */