1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xeescher.cxx,v $
10 * $Revision: 1.24.128.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
37 #include "xeescher.hxx"
39 #include <com/sun/star/lang/XServiceInfo.hpp>
40 #include <com/sun/star/frame/XModel.hpp>
41 #include <com/sun/star/form/FormComponentType.hpp>
42 #include <com/sun/star/awt/VisualEffect.hpp>
43 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
44 #include <com/sun/star/drawing/XShape.hpp>
45 #include <com/sun/star/form/binding/XBindableValue.hpp>
46 #include <com/sun/star/form/binding/XValueBinding.hpp>
47 #include <com/sun/star/form/binding/XListEntrySink.hpp>
48 #include <com/sun/star/form/binding/XListEntrySource.hpp>
49 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
51 #include <rtl/ustrbuf.h>
52 #include <vcl/bmpacc.hxx>
53 #include <svx/svdoole2.hxx>
54 #include <svx/svdocapt.hxx>
55 #include <svx/outlobj.hxx>
56 #include <svx/editobj.hxx>
58 #include "editutil.hxx"
59 #include "unonames.hxx"
60 #include "convuno.hxx"
63 #include "fapihelper.hxx"
64 #include "xechart.hxx"
65 #include "xeformula.hxx"
68 #include "xestyle.hxx"
69 #include "userdat.hxx"
70 #include "drwlayer.hxx"
71 #include "svx/unoapi.hxx"
73 #include <oox/core/tokens.hxx>
76 using ::rtl::OUString
;
77 using ::rtl::OUStringBuffer
;
78 using ::com::sun::star::uno::UNO_QUERY
;
79 using ::com::sun::star::uno::Reference
;
80 using ::com::sun::star::uno::Sequence
;
81 using ::com::sun::star::lang::XServiceInfo
;
82 using ::com::sun::star::beans::XPropertySet
;
83 using ::com::sun::star::drawing::XShape
;
84 using ::com::sun::star::frame::XModel
;
85 using ::com::sun::star::embed::XEmbeddedObject
;
86 using ::com::sun::star::awt::XControlModel
;
87 using ::com::sun::star::form::binding::XBindableValue
;
88 using ::com::sun::star::form::binding::XValueBinding
;
89 using ::com::sun::star::form::binding::XListEntrySink
;
90 using ::com::sun::star::form::binding::XListEntrySource
;
91 using ::com::sun::star::script::ScriptEventDescriptor
;
92 using ::com::sun::star::table::CellAddress
;
93 using ::com::sun::star::table::CellRangeAddress
;
95 // ============================================================================
97 XclExpImgData::XclExpImgData( const Graphic
& rGraphic
, sal_uInt16 nRecId
) :
98 maGraphic( rGraphic
),
103 void XclExpImgData::Save( XclExpStream
& rStrm
)
105 Bitmap aBmp
= maGraphic
.GetBitmap();
106 if( aBmp
.GetBitCount() != 24 )
107 aBmp
.Convert( BMP_CONVERSION_24BIT
);
109 if( BitmapReadAccess
* pAccess
= aBmp
.AcquireReadAccess() )
111 sal_Int32 nWidth
= ::std::min
< sal_Int32
>( pAccess
->Width(), 0xFFFF );
112 sal_Int32 nHeight
= ::std::min
< sal_Int32
>( pAccess
->Height(), 0xFFFF );
113 if( (nWidth
> 0) && (nHeight
> 0) )
115 sal_uInt8 nPadding
= static_cast< sal_uInt8
>( nWidth
& 0x03 );
116 sal_uInt32 nTmpSize
= static_cast< sal_uInt32
>( (nWidth
* 3 + nPadding
) * nHeight
+ 12 );
118 rStrm
.StartRecord( mnRecId
, nTmpSize
+ 4 );
120 rStrm
<< EXC_IMGDATA_BMP
// BMP format
121 << EXC_IMGDATA_WIN
// Windows
122 << nTmpSize
// size after _this_ field
123 << sal_uInt32( 12 ) // BITMAPCOREHEADER size
124 << static_cast< sal_uInt16
>( nWidth
) // width
125 << static_cast< sal_uInt16
>( nHeight
) // height
126 << sal_uInt16( 1 ) // planes
127 << sal_uInt16( 24 ); // bits per pixel
129 for( sal_Int32 nY
= nHeight
- 1; nY
>= 0; --nY
)
131 for( sal_Int32 nX
= 0; nX
< nWidth
; ++nX
)
133 const BitmapColor
& rBmpColor
= pAccess
->GetPixel( nY
, nX
);
134 rStrm
<< rBmpColor
.GetBlue() << rBmpColor
.GetGreen() << rBmpColor
.GetRed();
136 rStrm
.WriteZeroBytes( nPadding
);
141 aBmp
.ReleaseAccess( pAccess
);
145 // ============================================================================
147 XclExpControlHelper::XclExpControlHelper( const XclExpRoot
& rRoot
) :
153 XclExpControlHelper::~XclExpControlHelper()
157 void XclExpControlHelper::ConvertSheetLinks( Reference
< XShape
> xShape
)
164 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( xShape
);
165 if( !xCtrlModel
.is() )
168 // *** cell link *** ------------------------------------------------------
170 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY
);
173 Reference
< XServiceInfo
> xServInfo( xBindable
->getValueBinding(), UNO_QUERY
);
174 if( xServInfo
.is() && xServInfo
->supportsService( CREATE_OUSTRING( SC_SERVICENAME_VALBIND
) ) )
176 ScfPropertySet
aBindProp( xServInfo
);
177 CellAddress aApiAddress
;
178 if( aBindProp
.GetProperty( aApiAddress
, CREATE_OUSTRING( SC_UNONAME_BOUNDCELL
) ) )
181 ScUnoConversion::FillScAddress( aCellLink
, aApiAddress
);
182 if( GetTabInfo().IsExportTab( aCellLink
.Tab() ) )
183 mxCellLink
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aCellLink
);
188 // *** source range *** ---------------------------------------------------
190 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY
);
191 if( xEntrySink
.is() )
193 Reference
< XServiceInfo
> xServInfo( xEntrySink
->getListEntrySource(), UNO_QUERY
);
194 if( xServInfo
.is() && xServInfo
->supportsService( CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE
) ) )
196 ScfPropertySet
aSinkProp( xServInfo
);
197 CellRangeAddress aApiRange
;
198 if( aSinkProp
.GetProperty( aApiRange
, CREATE_OUSTRING( SC_UNONAME_CELLRANGE
) ) )
201 ScUnoConversion::FillScRange( aSrcRange
, aApiRange
);
202 if( (aSrcRange
.aStart
.Tab() == aSrcRange
.aEnd
.Tab()) && GetTabInfo().IsExportTab( aSrcRange
.aStart
.Tab() ) )
203 mxSrcRange
= GetFormulaCompiler().CreateFormula( EXC_FMLATYPE_CONTROL
, aSrcRange
);
204 mnEntryCount
= static_cast< sal_uInt16
>( aSrcRange
.aEnd
.Col() - aSrcRange
.aStart
.Col() + 1 );
210 void XclExpControlHelper::WriteFormula( XclExpStream
& rStrm
, const XclTokenArray
& rTokArr
) const
212 sal_uInt16 nFmlaSize
= rTokArr
.GetSize();
213 rStrm
<< nFmlaSize
<< sal_uInt32( 0 );
214 rTokArr
.WriteArray( rStrm
);
215 if( nFmlaSize
& 1 ) // pad to 16-bit
216 rStrm
<< sal_uInt8( 0 );
219 void XclExpControlHelper::WriteFormulaSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
, const XclTokenArray
& rTokArr
) const
221 rStrm
.StartRecord( nSubRecId
, (rTokArr
.GetSize() + 5) & ~1 );
222 WriteFormula( rStrm
, rTokArr
);
226 // ----------------------------------------------------------------------------
230 XclExpOcxControlObj::XclExpOcxControlObj( const XclExpRoot
& rRoot
, Reference
< XShape
> xShape
,
231 const String
& rClassName
, sal_uInt32 nStrmStart
, sal_uInt32 nStrmSize
) :
232 XclObj( rRoot
, EXC_OBJTYPE_PICTURE
, true ),
233 XclExpControlHelper( rRoot
),
234 maClassName( rClassName
),
235 mnStrmStart( nStrmStart
),
236 mnStrmSize( nStrmSize
)
238 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
242 SetPrintable( aCtrlProp
.GetBoolProperty( CREATE_OUSTRING( "Printable" ) ) );
243 SetAutoFill( FALSE
);
244 SetAutoLine( FALSE
);
246 // fill DFF property set
247 XclEscherEx
& rEscherEx
= *pMsodrawing
->GetEscherEx();
248 rEscherEx
.OpenContainer( ESCHER_SpContainer
);
249 rEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVESPT
| SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_OLESHAPE
);
250 Rectangle aDummyRect
;
251 EscherPropertyContainer
aPropOpt( rEscherEx
, rEscherEx
.QueryPicStream(), aDummyRect
);
252 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 ); // bool field
253 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x08000040 );
254 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
256 // #i51348# name of the control, may overwrite shape name
258 if( aCtrlProp
.GetProperty( aCtrlName
, CREATE_OUSTRING( "Name" ) ) && (aCtrlName
.getLength() > 0) )
259 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
262 //! TODO - needs check
263 Reference
< XPropertySet
> xShapePS( xShape
, UNO_QUERY
);
264 if( xShapePS
.is() && aPropOpt
.CreateGraphicProperties( xShapePS
, CREATE_STRING( "MetaFile" ), sal_False
) )
267 if( aPropOpt
.GetOpt( ESCHER_Prop_pib
, nBlipId
) )
268 aPropOpt
.AddOpt( ESCHER_Prop_pictureId
, nBlipId
);
271 // write DFF property set to stream
272 aPropOpt
.Commit( rEscherEx
.GetStream() );
275 if( SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
) )
276 XclExpDffAnchor( rRoot
, *pSdrObj
).WriteData( rEscherEx
);
277 rEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
278 rEscherEx
.CloseContainer(); // ESCHER_SpContainer
280 pMsodrawing
->UpdateStopPos();
283 ConvertSheetLinks( xShape
);
286 void XclExpOcxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
288 // OBJCF - clipboard format
289 rStrm
.StartRecord( EXC_ID_OBJCF
, 2 );
290 rStrm
<< sal_uInt16( 2 );
294 rStrm
.StartRecord( EXC_ID_OBJFLAGS
, 2 );
295 rStrm
<< sal_uInt16( 0x0031 );
299 XclExpString
aClass( maClassName
);
300 sal_uInt16 nClassNameSize
= static_cast< sal_uInt16
>( aClass
.GetSize() );
301 sal_uInt16 nClassNamePad
= nClassNameSize
& 1;
302 sal_uInt16 nFirstPartSize
= 12 + nClassNameSize
+ nClassNamePad
;
304 const XclTokenArray
* pCellLink
= GetCellLinkTokArr();
305 sal_uInt16 nCellLinkSize
= pCellLink
? ((pCellLink
->GetSize() + 7) & 0xFFFE) : 0;
307 const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr();
308 sal_uInt16 nSrcRangeSize
= pSrcRange
? ((pSrcRange
->GetSize() + 7) & 0xFFFE) : 0;
310 sal_uInt16 nPictFmlaSize
= nFirstPartSize
+ nCellLinkSize
+ nSrcRangeSize
+ 18;
311 rStrm
.StartRecord( EXC_ID_OBJPICTFMLA
, nPictFmlaSize
);
313 rStrm
<< sal_uInt16( nFirstPartSize
) // size of first part
314 << sal_uInt16( 5 ) // formula size
315 << sal_uInt32( 0 ) // unknown ID
316 << sal_uInt8( 0x02 ) << sal_uInt32( 0 ) // tTbl token with unknown ID
317 << sal_uInt8( 3 ) // pad to word
318 << aClass
; // "Forms.***.1"
319 rStrm
.WriteZeroBytes( nClassNamePad
); // pad to word
320 rStrm
<< mnStrmStart
// start in 'Ctls' stream
321 << mnStrmSize
// size in 'Ctls' stream
322 << sal_uInt32( 0 ); // class ID size
324 rStrm
<< nCellLinkSize
;
326 WriteFormula( rStrm
, *pCellLink
);
328 rStrm
<< nSrcRangeSize
;
330 WriteFormula( rStrm
, *pSrcRange
);
337 XclExpTbxControlObj::XclExpTbxControlObj( const XclExpRoot
& rRoot
, Reference
< XShape
> xShape
) :
338 XclObj( rRoot
, EXC_OBJTYPE_UNKNOWN
, true ),
339 XclMacroHelper( rRoot
),
349 mbFlatButton( false ),
350 mbFlatBorder( false ),
354 namespace FormCompType
= ::com::sun::star::form::FormComponentType
;
355 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
356 namespace AwtScrollOrient
= ::com::sun::star::awt::ScrollBarOrientation
;
358 ScfPropertySet
aCtrlProp( XclControlHelper::GetControlModel( xShape
) );
359 if( !xShape
.is() || !aCtrlProp
.Is() )
362 mnHeight
= xShape
->getSize().Height
;
367 sal_Int16 nClassId
= 0;
368 if( aCtrlProp
.GetProperty( nClassId
, CREATE_OUSTRING( "ClassId" ) ) )
372 case FormCompType::COMMANDBUTTON
: mnObjType
= EXC_OBJTYPE_BUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
373 case FormCompType::RADIOBUTTON
: mnObjType
= EXC_OBJTYPE_OPTIONBUTTON
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
374 case FormCompType::CHECKBOX
: mnObjType
= EXC_OBJTYPE_CHECKBOX
; meEventType
= EXC_TBX_EVENT_ACTION
; break;
375 case FormCompType::LISTBOX
: mnObjType
= EXC_OBJTYPE_LISTBOX
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
376 case FormCompType::COMBOBOX
: mnObjType
= EXC_OBJTYPE_DROPDOWN
; meEventType
= EXC_TBX_EVENT_CHANGE
; break;
377 case FormCompType::GROUPBOX
: mnObjType
= EXC_OBJTYPE_GROUPBOX
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
378 case FormCompType::FIXEDTEXT
: mnObjType
= EXC_OBJTYPE_LABEL
; meEventType
= EXC_TBX_EVENT_MOUSE
; break;
379 case FormCompType::SCROLLBAR
: mnObjType
= EXC_OBJTYPE_SCROLLBAR
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
380 case FormCompType::SPINBUTTON
: mnObjType
= EXC_OBJTYPE_SPIN
; meEventType
= EXC_TBX_EVENT_VALUE
; break;
383 if( mnObjType
== EXC_OBJTYPE_UNKNOWN
)
388 SetPrintable( aCtrlProp
.GetBoolProperty( CREATE_OUSTRING( "Printable" ) ) );
389 SetAutoFill( FALSE
);
390 SetAutoLine( FALSE
);
392 // fill DFF property set
393 XclEscherEx
& rEscherEx
= *pMsodrawing
->GetEscherEx();
394 rEscherEx
.OpenContainer( ESCHER_SpContainer
);
395 rEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_HAVESPT
);
396 EscherPropertyContainer aPropOpt
;
397 bool bVisible
= aCtrlProp
.GetBoolProperty( CREATE_OUSTRING( "EnableVisible" ) );
398 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, bVisible
? 0x00080000 : 0x00080002 ); // visible flag
400 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01000100 ); // bool field
401 aPropOpt
.AddOpt( ESCHER_Prop_lTxid
, 0 ); // Text ID
402 aPropOpt
.AddOpt( ESCHER_Prop_WrapText
, 0x00000001 );
403 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x001A0008 ); // bool field
404 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00100000 ); // bool field
405 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080000 ); // bool field
407 // #i51348# name of the control, may overwrite shape name
409 if( aCtrlProp
.GetProperty( aCtrlName
, CREATE_OUSTRING( "Name" ) ) && (aCtrlName
.getLength() > 0) )
410 aPropOpt
.AddOpt( ESCHER_Prop_wzName
, aCtrlName
);
412 // write DFF property set to stream
413 aPropOpt
.Commit( rEscherEx
.GetStream() );
416 if( SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
) )
417 XclExpDffAnchor( rRoot
, *pSdrObj
).WriteData( rEscherEx
);
418 rEscherEx
.AddAtom( 0, ESCHER_ClientData
); // OBJ record
419 pMsodrawing
->UpdateStopPos();
423 if( aCtrlProp
.GetProperty( aString
, CREATE_OUSTRING( "Label" ) ) )
425 /* Be sure to construct the MSODRAWING record containing the
426 ClientTextbox atom after the base OBJ's MSODRAWING record data is
428 pClientTextbox
= new XclMsodrawing( GetRoot() );
429 pClientTextbox
->GetEscherEx()->AddAtom( 0, ESCHER_ClientTextbox
); // TXO record
430 pClientTextbox
->UpdateStopPos();
432 sal_uInt16 nXclFont
= EXC_FONT_APP
;
433 if( aString
.getLength() > 0 )
435 XclFontData aFontData
;
436 GetFontPropSetHelper().ReadFontProperties( aFontData
, aCtrlProp
, EXC_FONTPROPSET_CONTROL
);
437 if( (aFontData
.maName
.Len() > 0) && (aFontData
.mnHeight
> 0) )
438 nXclFont
= GetFontBuffer().Insert( aFontData
, EXC_COLOR_CTRLTEXT
);
441 pTxo
= new XclTxo( aString
, nXclFont
);
442 pTxo
->SetHorAlign( (mnObjType
== EXC_OBJTYPE_BUTTON
) ? EXC_OBJ_HOR_CENTER
: EXC_OBJ_HOR_LEFT
);
443 pTxo
->SetVerAlign( EXC_OBJ_VER_CENTER
);
446 rEscherEx
.CloseContainer(); // ESCHER_SpContainer
449 aCtrlProp
.GetProperty( mnLineCount
, CREATE_OUSTRING( "LineCount" ) );
452 sal_Int16 nApiButton
= AwtVisualEffect::LOOK3D
;
453 sal_Int16 nApiBorder
= AwtVisualEffect::LOOK3D
;
456 case FormCompType::LISTBOX
:
457 case FormCompType::COMBOBOX
:
458 aCtrlProp
.GetProperty( nApiBorder
, CREATE_OUSTRING( "Border" ) );
460 case FormCompType::CHECKBOX
:
461 case FormCompType::RADIOBUTTON
:
462 aCtrlProp
.GetProperty( nApiButton
, CREATE_OUSTRING( "VisualEffect" ) );
463 nApiBorder
= AwtVisualEffect::NONE
;
465 // Push button cannot be set to flat in Excel
466 case FormCompType::COMMANDBUTTON
:
467 nApiBorder
= AwtVisualEffect::LOOK3D
;
469 // Label does not support a border in Excel
470 case FormCompType::FIXEDTEXT
:
471 nApiBorder
= AwtVisualEffect::NONE
;
473 /* Scroll bar and spin button have a "Border" property, but it is
474 really used for a border, and not for own 3D/flat look (#i34712#). */
475 case FormCompType::SCROLLBAR
:
476 case FormCompType::SPINBUTTON
:
477 nApiButton
= AwtVisualEffect::LOOK3D
;
478 nApiBorder
= AwtVisualEffect::NONE
;
480 // Group box does not support flat style (#i34712#)
481 case FormCompType::GROUPBOX
:
482 nApiBorder
= AwtVisualEffect::LOOK3D
;
485 mbFlatButton
= nApiButton
!= AwtVisualEffect::LOOK3D
;
486 mbFlatBorder
= nApiBorder
!= AwtVisualEffect::LOOK3D
;
489 sal_Int16 nApiState
= 0;
490 if( aCtrlProp
.GetProperty( nApiState
, CREATE_OUSTRING( "State" ) ) )
494 case 0: mnState
= EXC_OBJ_CHECKBOX_UNCHECKED
; break;
495 case 1: mnState
= EXC_OBJ_CHECKBOX_CHECKED
; break;
496 case 2: mnState
= EXC_OBJ_CHECKBOX_TRISTATE
; break;
500 // special control contents
503 case FormCompType::LISTBOX
:
505 mbMultiSel
= aCtrlProp
.GetBoolProperty( CREATE_OUSTRING( "MultiSelection" ) );
506 Sequence
< sal_Int16
> aSelection
;
507 if( aCtrlProp
.GetProperty( aSelection
, CREATE_OUSTRING( "SelectedItems" ) ) )
509 sal_Int32 nLen
= aSelection
.getLength();
512 mnSelEntry
= aSelection
[ 0 ] + 1;
513 maMultiSel
.resize( nLen
);
514 const sal_Int16
* pnBegin
= aSelection
.getConstArray();
515 ::std::copy( pnBegin
, pnBegin
+ nLen
, maMultiSel
.begin() );
519 // convert listbox with dropdown button to Excel dropdown
520 if( aCtrlProp
.GetBoolProperty( CREATE_OUSTRING( "Dropdown" ) ) )
521 mnObjType
= EXC_OBJTYPE_DROPDOWN
;
525 case FormCompType::COMBOBOX
:
527 Sequence
< OUString
> aStringList
;
529 if( aCtrlProp
.GetProperty( aStringList
, CREATE_OUSTRING( "StringItemList" ) ) &&
530 aCtrlProp
.GetProperty( aDefText
, CREATE_OUSTRING( "Text" ) ) &&
531 aStringList
.getLength() && aDefText
.getLength() )
533 const OUString
* pBegin
= aStringList
.getConstArray();
534 const OUString
* pEnd
= pBegin
+ aStringList
.getLength();
535 const OUString
* pString
= ::std::find( pBegin
, pEnd
, aDefText
);
536 if( pString
!= pEnd
)
537 mnSelEntry
= static_cast< sal_Int16
>( pString
- pBegin
+ 1 ); // 1-based
539 maMultiSel
.resize( 1, mnSelEntry
- 1 );
542 // convert combobox without dropdown button to Excel listbox
543 if( !aCtrlProp
.GetBoolProperty( CREATE_OUSTRING( "Dropdown" ) ) )
544 mnObjType
= EXC_OBJTYPE_LISTBOX
;
548 case FormCompType::SCROLLBAR
:
550 sal_Int32 nApiValue
= 0;
551 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "ScrollValueMin" ) ) )
552 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
553 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "ScrollValueMax" ) ) )
554 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MIN
);
555 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "ScrollValue" ) ) )
556 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
557 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "LineIncrement" ) ) )
558 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
559 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "BlockIncrement" ) ) )
560 mnScrollPage
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
561 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "Orientation" ) ) )
562 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
566 case FormCompType::SPINBUTTON
:
568 sal_Int32 nApiValue
= 0;
569 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "SpinValueMin" ) ) )
570 mnScrollMin
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
571 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "SpinValueMax" ) ) )
572 mnScrollMax
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, EXC_OBJ_SCROLLBAR_MAX
);
573 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "SpinValue" ) ) )
574 mnScrollValue
= limit_cast
< sal_uInt16
>( nApiValue
, mnScrollMin
, mnScrollMax
);
575 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "SpinIncrement" ) ) )
576 mnScrollStep
= limit_cast
< sal_uInt16
>( nApiValue
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
577 if( aCtrlProp
.GetProperty( nApiValue
, CREATE_OUSTRING( "Orientation" ) ) )
578 mbScrollHor
= nApiValue
== AwtScrollOrient::HORIZONTAL
;
584 ConvertSheetLinks( xShape
);
587 bool XclExpTbxControlObj::SetMacroLink( const ScriptEventDescriptor
& rEvent
)
589 return XclMacroHelper::SetMacroLink( rEvent
, meEventType
);
591 String aMacroName = XclControlHelper::ExtractFromMacroDescriptor( rEvent, meEventType );
592 if( aMacroName.Len() )
594 sal_uInt16 nExtSheet = GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC );
595 sal_uInt16 nNameIdx = GetNameManager().InsertMacroCall( aMacroName, true, false );
596 mxMacroLink = GetFormulaCompiler().CreateNameXFormula( nExtSheet, nNameIdx );
603 void XclExpTbxControlObj::WriteSubRecs( XclExpStream
& rStrm
)
607 // *** Push buttons, labels ***
609 case EXC_OBJTYPE_BUTTON
:
610 case EXC_OBJTYPE_LABEL
:
611 // ftMacro - macro link
612 WriteMacroSubRec( rStrm
);
615 // *** Check boxes, option buttons ***
617 case EXC_OBJTYPE_CHECKBOX
:
618 case EXC_OBJTYPE_OPTIONBUTTON
:
620 // ftCbls - box properties
621 sal_uInt16 nStyle
= 0;
622 ::set_flag( nStyle
, EXC_OBJ_CHECKBOX_FLAT
, mbFlatButton
);
624 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 12 );
626 rStrm
.WriteZeroBytes( 8 );
630 // ftMacro - macro link
631 WriteMacroSubRec( rStrm
);
632 // ftCblsFmla subrecord - cell link
633 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJCBLSFMLA
);
635 // ftCblsData subrecord - box properties, again
636 rStrm
.StartRecord( EXC_ID_OBJCBLS
, 8 );
638 rStrm
.WriteZeroBytes( 4 );
644 // *** List boxes, combo boxes ***
646 case EXC_OBJTYPE_LISTBOX
:
647 case EXC_OBJTYPE_DROPDOWN
:
649 sal_uInt16 nEntryCount
= GetSourceEntryCount();
651 // ftSbs subrecord - Scroll bars
652 sal_Int32 nLineHeight
= XclTools::GetHmmFromTwips( 200 ); // always 10pt
653 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
654 mnLineCount
= static_cast< sal_uInt16
>( mnHeight
/ nLineHeight
);
657 sal_uInt16 nInvisLines
= (nEntryCount
>= mnLineCount
) ? (nEntryCount
- mnLineCount
) : 0;
658 mnScrollMax
= limit_cast
< sal_uInt16
>( nInvisLines
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
660 mnScrollPage
= limit_cast
< sal_uInt16
>( mnLineCount
, EXC_OBJ_SCROLLBAR_MIN
, EXC_OBJ_SCROLLBAR_MAX
);
664 // ftMacro - macro link
665 WriteMacroSubRec( rStrm
);
666 // ftSbsFmla subrecord - cell link
667 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
669 // ftLbsData - source data range and box properties
670 sal_uInt16 nStyle
= 0;
671 ::insert_value( nStyle
, mbMultiSel
? EXC_OBJ_LISTBOX_MULTI
: EXC_OBJ_LISTBOX_SINGLE
, 4, 2 );
672 ::set_flag( nStyle
, EXC_OBJ_LISTBOX_FLAT
, mbFlatBorder
);
674 rStrm
.StartRecord( EXC_ID_OBJLBSDATA
, 0 );
676 if( const XclTokenArray
* pSrcRange
= GetSourceRangeTokArr() )
678 rStrm
<< static_cast< sal_uInt16
>( (pSrcRange
->GetSize() + 7) & 0xFFFE );
679 WriteFormula( rStrm
, *pSrcRange
);
682 rStrm
<< sal_uInt16( 0 );
684 rStrm
<< nEntryCount
<< mnSelEntry
<< nStyle
<< sal_uInt16( 0 );
685 if( mnObjType
== EXC_OBJTYPE_LISTBOX
)
689 ScfUInt8Vec
aSelEx( nEntryCount
, 0 );
690 for( ScfInt16Vec::const_iterator aIt
= maMultiSel
.begin(), aEnd
= maMultiSel
.end(); aIt
!= aEnd
; ++aIt
)
691 if( *aIt
< nEntryCount
)
693 rStrm
.Write( &aSelEx
[ 0 ], aSelEx
.size() );
696 else if( mnObjType
== EXC_OBJTYPE_DROPDOWN
)
698 rStrm
<< sal_uInt16( 0 ) << mnLineCount
;
705 // *** Spin buttons, scrollbars ***
707 case EXC_OBJTYPE_SPIN
:
708 case EXC_OBJTYPE_SCROLLBAR
:
710 // ftSbs subrecord - scroll bars
712 // ftMacro - macro link
713 WriteMacroSubRec( rStrm
);
714 // ftSbsFmla subrecord - cell link
715 WriteCellLinkSubRec( rStrm
, EXC_ID_OBJSBSFMLA
);
719 // *** Group boxes ***
721 case EXC_OBJTYPE_GROUPBOX
:
723 // ftMacro - macro link
724 WriteMacroSubRec( rStrm
);
726 // ftGboData subrecord - group box properties
727 sal_uInt16 nStyle
= 0;
728 ::set_flag( nStyle
, EXC_OBJ_GROUPBOX_FLAT
, mbFlatBorder
);
730 rStrm
.StartRecord( EXC_ID_OBJGBODATA
, 6 );
731 rStrm
<< sal_uInt32( 0 )
739 void XclExpTbxControlObj::WriteCellLinkSubRec( XclExpStream
& rStrm
, sal_uInt16 nSubRecId
)
741 if( const XclTokenArray
* pCellLink
= GetCellLinkTokArr() )
742 WriteFormulaSubRec( rStrm
, nSubRecId
, *pCellLink
);
745 void XclExpTbxControlObj::WriteSbs( XclExpStream
& rStrm
)
747 sal_uInt16 nOrient
= 0;
748 ::set_flag( nOrient
, EXC_OBJ_SCROLLBAR_HOR
, mbScrollHor
);
749 sal_uInt16 nStyle
= EXC_OBJ_SCROLLBAR_DEFFLAGS
;
750 ::set_flag( nStyle
, EXC_OBJ_SCROLLBAR_FLAT
, mbFlatButton
);
752 rStrm
.StartRecord( EXC_ID_OBJSBS
, 20 );
753 rStrm
<< sal_uInt32( 0 ) // reserved
754 << mnScrollValue
// thumb position
755 << mnScrollMin
// thumb min pos
756 << mnScrollMax
// thumb max pos
757 << mnScrollStep
// line increment
758 << mnScrollPage
// page increment
759 << nOrient
// 0 = vertical, 1 = horizontal
760 << sal_uInt16( 15 ) // thumb width
761 << nStyle
; // flags/style
768 // ----------------------------------------------------------------------------
770 XclExpChartObj::XclExpChartObj( const XclExpRoot
& rRoot
, Reference
< XShape
> xShape
) :
771 XclObj( rRoot
, EXC_OBJTYPE_CHART
),
774 // create the MSODRAWING record contents for the chart object
775 XclEscherEx
& rEscherEx
= *pMsodrawing
->GetEscherEx();
776 rEscherEx
.OpenContainer( ESCHER_SpContainer
);
777 rEscherEx
.AddShape( ESCHER_ShpInst_HostControl
, SHAPEFLAG_HAVEANCHOR
| SHAPEFLAG_HAVESPT
);
778 EscherPropertyContainer aPropOpt
;
779 aPropOpt
.AddOpt( ESCHER_Prop_LockAgainstGrouping
, 0x01040104 );
780 aPropOpt
.AddOpt( ESCHER_Prop_FitTextToShape
, 0x00080008 );
781 aPropOpt
.AddOpt( ESCHER_Prop_fillColor
, 0x0800004E );
782 aPropOpt
.AddOpt( ESCHER_Prop_fillBackColor
, 0x0800004D );
783 aPropOpt
.AddOpt( ESCHER_Prop_fNoFillHitTest
, 0x00110010 );
784 aPropOpt
.AddOpt( ESCHER_Prop_lineColor
, 0x0800004D );
785 aPropOpt
.AddOpt( ESCHER_Prop_fNoLineDrawDash
, 0x00080008 );
786 aPropOpt
.AddOpt( ESCHER_Prop_fshadowObscured
, 0x00020000 );
787 aPropOpt
.AddOpt( ESCHER_Prop_fPrint
, 0x00080000 );
788 aPropOpt
.Commit( rEscherEx
.GetStream() );
791 SdrObject
* pSdrObj
= SdrObject::getSdrObjectFromXShape( xShape
);
793 XclExpDffAnchor( rRoot
, *pSdrObj
).WriteData( rEscherEx
);
795 // client data (the following OBJ record)
796 rEscherEx
.AddAtom( 0, ESCHER_ClientData
);
797 rEscherEx
.CloseContainer(); // ESCHER_SpContainer
798 pMsodrawing
->UpdateStopPos();
800 // load the chart OLE object
801 if( SdrOle2Obj
* pSdrOleObj
= dynamic_cast< SdrOle2Obj
* >( pSdrObj
) )
802 svt::EmbeddedObjectRef::TryRunningState( pSdrOleObj
->GetObjRef() );
804 // create the chart substream object
805 ScfPropertySet
aShapeProp( xShape
);
806 Reference
< XModel
> xModel
;
807 aShapeProp
.GetProperty( xModel
, CREATE_OUSTRING( "Model" ) );
808 ::com::sun::star::awt::Rectangle aBoundRect
;
809 aShapeProp
.GetProperty( aBoundRect
, CREATE_OUSTRING( "BoundRect" ) );
810 Size
aSize( aBoundRect
.Width
, aBoundRect
.Height
);
811 mxChart
.reset( new XclExpChart( rRoot
, xModel
, aSize
) );
814 XclExpChartObj::~XclExpChartObj()
818 void XclExpChartObj::Save( XclExpStream
& rStrm
)
820 // content of OBJ record
821 XclObj::Save( rStrm
);
823 mxChart
->Save( rStrm
);
826 // ============================================================================
828 XclExpNote::XclExpNote( const XclExpRoot
& rRoot
, const ScAddress
& rScPos
,
829 const ScPostIt
* pScNote
, const String
& rAddText
) :
830 XclExpRecord( EXC_ID_NOTE
),
832 mnObjId( EXC_OBJ_INVALID_ID
),
833 mbVisible( pScNote
&& pScNote
->IsCaptionShown() )
835 // get the main note text
838 aNoteText
= pScNote
->GetText();
839 // append additional text
840 ScGlobal::AddToken( aNoteText
, rAddText
, '\n', 2 );
841 maOrigNoteText
= aNoteText
;
843 // initialize record dependent on BIFF type
844 switch( rRoot
.GetBiff() )
847 maNoteText
= ByteString( aNoteText
, rRoot
.GetTextEncoding() );
852 // TODO: additional text
854 if( SdrCaptionObj
* pCaption
= pScNote
->GetCaption() )
855 if( const OutlinerParaObject
* pOPO
= pCaption
->GetOutlinerParaObject() )
856 mnObjId
= rRoot
.GetOldRoot().pObjRecs
->Add( new XclObjComment( rRoot
, pCaption
->GetLogicRect(), pOPO
->GetTextObject(), pCaption
, mbVisible
) );
858 SetRecSize( 9 + maAuthor
.GetSize() );
862 default: DBG_ERROR_BIFF();
866 void XclExpNote::Save( XclExpStream
& rStrm
)
868 switch( rStrm
.GetRoot().GetBiff() )
872 // write the NOTE record directly, there may be the need to create more than one
873 const sal_Char
* pcBuffer
= maNoteText
.GetBuffer();
874 sal_uInt16 nCharsLeft
= static_cast< sal_uInt16
>( maNoteText
.Len() );
878 sal_uInt16 nWriteChars
= ::std::min( nCharsLeft
, EXC_NOTE5_MAXLEN
);
880 rStrm
.StartRecord( EXC_ID_NOTE
, 6 + nWriteChars
);
881 if( pcBuffer
== maNoteText
.GetBuffer() )
883 // first record: row, col, length of complete text
884 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
885 << static_cast< sal_uInt16
>( maScPos
.Col() )
886 << nCharsLeft
; // still contains full length
890 // next records: -1, 0, length of current text segment
891 rStrm
<< sal_uInt16( 0xFFFF )
895 rStrm
.Write( pcBuffer
, nWriteChars
);
898 pcBuffer
+= nWriteChars
;
899 nCharsLeft
= nCharsLeft
- nWriteChars
;
905 if( mnObjId
!= EXC_OBJ_INVALID_ID
)
906 XclExpRecord::Save( rStrm
);
909 default: DBG_ERROR_BIFF();
914 void XclExpNote::WriteBody( XclExpStream
& rStrm
)
916 // BIFF5/BIFF7 is written separately
917 DBG_ASSERT_BIFF( rStrm
.GetRoot().GetBiff() == EXC_BIFF8
);
919 sal_uInt16 nFlags
= 0;
920 ::set_flag( nFlags
, EXC_NOTE_VISIBLE
, mbVisible
);
922 rStrm
<< static_cast< sal_uInt16
>( maScPos
.Row() )
923 << static_cast< sal_uInt16
>( maScPos
.Col() )
930 void XclExpNote::WriteXml( sal_Int32 nAuthorId
, XclExpXmlStream
& rStrm
)
932 sax_fastparser::FSHelperPtr rComments
= rStrm
.GetCurrentStream();
934 rComments
->startElement( XML_comment
,
935 XML_ref
, XclXmlUtils::ToOString( maScPos
).getStr(),
936 XML_authorId
, OString::valueOf( nAuthorId
).getStr(),
937 // OOXTODO: XML_guid,
939 rComments
->startElement( XML_text
, FSEND
);
940 // OOXTODO: phoneticPr, rPh, r
941 rComments
->startElement( XML_t
, FSEND
);
942 rComments
->writeEscaped( XclXmlUtils::ToOUString( maOrigNoteText
) );
943 rComments
->endElement ( XML_t
);
944 rComments
->endElement( XML_text
);
945 rComments
->endElement( XML_comment
);
948 // ============================================================================
950 XclMacroHelper::XclMacroHelper( const XclExpRoot
& rRoot
) :
951 XclExpControlHelper( rRoot
)
955 XclMacroHelper::~XclMacroHelper()
959 void XclMacroHelper::WriteMacroSubRec( XclExpStream
& rStrm
)
961 if( mxMacroLink
.is() )
962 WriteFormulaSubRec( rStrm
, EXC_ID_OBJMACRO
, *mxMacroLink
);
966 XclMacroHelper::SetMacroLink( const ScriptEventDescriptor
& rEvent
, const XclTbxEventType
& nEventType
)
968 String aMacroName
= XclControlHelper::ExtractFromMacroDescriptor( rEvent
, nEventType
);
969 if( aMacroName
.Len() )
971 return SetMacroLink( aMacroName
);
977 XclMacroHelper::SetMacroLink( const String
& rMacroName
)
979 OSL_TRACE("SetMacroLink( macroname:=%s )", rtl::OUStringToOString( rMacroName
, RTL_TEXTENCODING_UTF8
).getStr() );
980 if( rMacroName
.Len() )
982 sal_uInt16 nExtSheet
= GetLocalLinkManager().FindExtSheet( EXC_EXTSH_OWNDOC
);
983 sal_uInt16 nNameIdx
= GetNameManager().InsertMacroCall( rMacroName
, true, false );
984 mxMacroLink
= GetFormulaCompiler().CreateNameXFormula( nExtSheet
, nNameIdx
);
990 XclExpShapeObj::XclExpShapeObj( const XclExpRoot
& rRoot
, ::com::sun::star::uno::Reference
< ::com::sun::star::drawing::XShape
> xShape
) :
992 XclMacroHelper( rRoot
)
994 if( SdrObject
* pSdrObj
= ::GetSdrObjectFromXShape( xShape
) )
996 ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( pSdrObj
);
997 if ( pInfo
&& pInfo
->GetMacro().getLength() )
998 SetMacroLink( XclControlHelper::GetXclMacroName( pInfo
->GetMacro() ) );
1002 XclExpShapeObj::~XclExpShapeObj()
1006 void XclExpShapeObj::WriteSubRecs( XclExpStream
& rStrm
)
1008 XclObjAny::WriteSubRecs( rStrm
);
1009 WriteMacroSubRec( rStrm
);
1012 // ============================================================================
1014 XclExpComments::XclExpComments( SCTAB nTab
, XclExpRecordList
< XclExpNote
>& rNotes
)
1015 : mnTab( nTab
), mrNotes( rNotes
)
1019 struct OUStringLess
: public std::binary_function
<OUString
, OUString
, bool>
1021 bool operator()(const OUString
& x
, const OUString
& y
) const
1023 return x
.compareTo( y
) <= 0;
1027 void XclExpComments::SaveXml( XclExpXmlStream
& rStrm
)
1029 if( mrNotes
.IsEmpty() )
1032 sax_fastparser::FSHelperPtr rComments
= rStrm
.CreateOutputStream(
1033 XclXmlUtils::GetStreamName( "xl/", "comments", mnTab
+ 1 ),
1034 XclXmlUtils::GetStreamName( "../", "comments", mnTab
+ 1 ),
1035 rStrm
.GetCurrentStream()->getOutputStream(),
1036 "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
1037 "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments" );
1038 rStrm
.PushStream( rComments
);
1040 rComments
->startElement( XML_comments
,
1041 XML_xmlns
, "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
1043 rComments
->startElement( XML_authors
, FSEND
);
1045 typedef std::set
< OUString
, OUStringLess
> Authors
;
1048 size_t nNotes
= mrNotes
.GetSize();
1049 for( size_t i
= 0; i
< nNotes
; ++i
)
1051 aAuthors
.insert( XclXmlUtils::ToOUString( mrNotes
.GetRecord( i
)->GetAuthor() ) );
1054 for( Authors::const_iterator b
= aAuthors
.begin(), e
= aAuthors
.end(); b
!= e
; ++b
)
1056 rComments
->startElement( XML_author
, FSEND
);
1057 rComments
->writeEscaped( *b
);
1058 rComments
->endElement( XML_author
);
1061 rComments
->endElement( XML_authors
);
1062 rComments
->startElement( XML_commentList
, FSEND
);
1064 for( size_t i
= 0; i
< nNotes
; ++i
)
1066 XclExpNoteList::RecordRefType xNote
= mrNotes
.GetRecord( i
);
1067 Authors::const_iterator aAuthor
= aAuthors
.find(
1068 XclXmlUtils::ToOUString( xNote
->GetAuthor() ) );
1069 sal_Int32 nAuthorId
= distance( aAuthors
.begin(), aAuthor
);
1070 xNote
->WriteXml( nAuthorId
, rStrm
);
1073 rComments
->endElement( XML_commentList
);
1074 rComments
->endElement( XML_comments
);
1079 // ============================================================================