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: xiescher.cxx,v $
10 * $Revision: 1.57.52.8 $
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"
34 #include "xiescher.hxx"
36 #include <com/sun/star/beans/NamedValue.hpp>
37 #include <com/sun/star/container/XIndexContainer.hpp>
38 #include <com/sun/star/container/XNameContainer.hpp>
39 #include <com/sun/star/embed/Aspects.hpp>
40 #include <com/sun/star/embed/XEmbeddedObject.hpp>
41 #include <com/sun/star/embed/XEmbedPersist.hpp>
42 #include <com/sun/star/awt/PushButtonType.hpp>
43 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
44 #include <com/sun/star/awt/VisualEffect.hpp>
45 #include <com/sun/star/style/HorizontalAlignment.hpp>
46 #include <com/sun/star/style/VerticalAlignment.hpp>
47 #include <com/sun/star/drawing/XControlShape.hpp>
48 #include <com/sun/star/form/XForm.hpp>
49 #include <com/sun/star/form/XFormsSupplier.hpp>
50 #include <com/sun/star/form/binding/XBindableValue.hpp>
51 #include <com/sun/star/form/binding/XValueBinding.hpp>
52 #include <com/sun/star/form/binding/XListEntrySink.hpp>
53 #include <com/sun/star/form/binding/XListEntrySource.hpp>
54 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
55 #include <com/sun/star/script/XEventAttacherManager.hpp>
57 #include <rtl/logfile.hxx>
58 #include <sfx2/objsh.hxx>
59 #include <svtools/moduleoptions.hxx>
60 #include <svtools/fltrcfg.hxx>
61 #include <svtools/wmf.hxx>
62 #include <comphelper/types.hxx>
63 #include <comphelper/classids.hxx>
64 #include <toolkit/helper/vclunohelper.hxx>
65 #include <basegfx/point/b2dpoint.hxx>
66 #include <basegfx/polygon/b2dpolygon.hxx>
68 #include <basic/sbstar.hxx>
69 #include <basic/sbmod.hxx>
70 #include <basic/sbmeth.hxx>
72 #include <svx/svdopath.hxx>
73 #include <svx/svdocirc.hxx>
74 #include <svx/svdoedge.hxx>
75 #include <svx/svdogrp.hxx>
76 #include <svx/svdoashp.hxx>
77 #include <svx/svdograf.hxx>
78 #include <svx/svdoole2.hxx>
79 #include <svx/svdocapt.hxx>
80 #include <svx/svdouno.hxx>
81 #include <svx/svdpage.hxx>
82 #include <svx/editobj.hxx>
83 #include <svx/outliner.hxx>
84 #include <svx/outlobj.hxx>
85 #include <svx/unoapi.hxx>
86 #include <svx/svditer.hxx>
87 #include <svx/writingmodeitem.hxx>
89 #include "scitems.hxx"
90 #include <svx/eeitem.hxx>
91 #include <svx/colritem.hxx>
92 #include <svx/xflclit.hxx>
93 #include <svx/adjitem.hxx>
94 #include <svx/xlineit.hxx>
95 #include <svx/xlinjoit.hxx>
96 #include <svx/xlntrit.hxx>
97 #include <svx/xbtmpit.hxx>
99 #include "document.hxx"
100 #include "drwlayer.hxx"
101 #include "userdat.hxx"
102 #include "chartarr.hxx"
103 #include "detfunc.hxx"
104 #include "unonames.hxx"
105 #include "convuno.hxx"
106 #include "postit.hxx"
107 #include "globstr.hrc"
109 #include "fprogressbar.hxx"
110 #include "xltracer.hxx"
111 #include "xistream.hxx"
112 #include "xihelper.hxx"
113 #include "xiformula.hxx"
114 #include "xilink.hxx"
115 #include "xistyle.hxx"
116 #include "xipage.hxx"
117 #include "xichart.hxx"
118 #include "xicontent.hxx"
119 #include "scextopt.hxx"
121 #include "namebuff.hxx"
123 using ::rtl::OUString
;
124 using ::rtl::OUStringBuffer
;
125 using ::com::sun::star::uno::Reference
;
126 using ::com::sun::star::uno::Sequence
;
127 using ::com::sun::star::uno::Any
;
128 using ::com::sun::star::uno::XInterface
;
129 using ::com::sun::star::uno::Exception
;
130 using ::com::sun::star::uno::UNO_QUERY
;
131 using ::com::sun::star::uno::UNO_QUERY_THROW
;
132 using ::com::sun::star::beans::NamedValue
;
133 using ::com::sun::star::lang::XMultiServiceFactory
;
134 using ::com::sun::star::container::XIndexContainer
;
135 using ::com::sun::star::container::XNameContainer
;
136 using ::com::sun::star::frame::XModel
;
137 using ::com::sun::star::awt::XControlModel
;
138 using ::com::sun::star::embed::XEmbeddedObject
;
139 using ::com::sun::star::embed::XEmbedPersist
;
140 using ::com::sun::star::drawing::XControlShape
;
141 using ::com::sun::star::drawing::XShape
;
142 using ::com::sun::star::form::XForm
;
143 using ::com::sun::star::form::XFormComponent
;
144 using ::com::sun::star::form::XFormsSupplier
;
145 using ::com::sun::star::form::binding::XBindableValue
;
146 using ::com::sun::star::form::binding::XValueBinding
;
147 using ::com::sun::star::form::binding::XListEntrySink
;
148 using ::com::sun::star::form::binding::XListEntrySource
;
149 using ::com::sun::star::script::ScriptEventDescriptor
;
150 using ::com::sun::star::script::XEventAttacherManager
;
151 using ::com::sun::star::table::CellAddress
;
152 using ::com::sun::star::table::CellRangeAddress
;
154 // ============================================================================
158 /** Helper class which mimics the auto_ptr< SdrObject > semantics, but calls
159 SdrObject::Free instead of deleting the SdrObject directly. */
160 template< typename SdrObjType
>
164 inline explicit TSdrObjectPtr( SdrObjType
* pObj
= 0 ) : mpObj( pObj
) {}
165 inline ~TSdrObjectPtr() { free(); }
167 inline const SdrObjType
* operator->() const { return mpObj
; }
168 inline SdrObjType
* operator->() { return mpObj
; }
170 inline const SdrObjType
* get() const { return mpObj
; }
171 inline SdrObjType
* get() { return mpObj
; }
173 inline const SdrObjType
& operator*() const { return *mpObj
; }
174 inline SdrObjType
& operator*() { return *mpObj
; }
176 inline bool is() const { return mpObj
!= 0; }
177 inline bool operator!() const { return mpObj
== 0; }
179 inline void reset( SdrObjType
* pObj
= 0 ) { free(); mpObj
= pObj
; }
180 inline SdrObjType
* release() { SdrObjType
* pObj
= mpObj
; mpObj
= 0; return pObj
; }
183 TSdrObjectPtr( const TSdrObjectPtr
& ); // not implemented
184 TSdrObjectPtr
& operator=( TSdrObjectPtr
& rxObj
); // not implemented
186 inline void free() { SdrObject
* pObj
= mpObj
; mpObj
= 0; SdrObject::Free( pObj
); }
192 typedef TSdrObjectPtr
< SdrObject
> SdrObjectPtr
;
196 // Drawing objects ============================================================
198 XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot
& rRoot
) :
200 maObjId( rRoot
.GetCurrScTab(), EXC_OBJ_INVALID_ID
),
201 mnObjType( EXC_OBJTYPE_UNKNOWN
),
208 mbAutoMargin( true ),
209 mbSimpleMacro( true ),
210 mbProcessSdr( true ),
216 XclImpDrawObjBase::~XclImpDrawObjBase()
220 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj3( XclImpStream
& rStrm
)
222 const XclImpRoot
& rRoot
= rStrm
.GetRoot();
223 XclImpDrawObjRef xDrawObj
;
225 if( rStrm
.GetRecLeft() >= 30 )
232 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
233 case EXC_OBJTYPE_LINE
: xDrawObj
.reset( new XclImpLineObj( rRoot
) ); break;
234 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
.reset( new XclImpRectObj( rRoot
) ); break;
235 case EXC_OBJTYPE_OVAL
: xDrawObj
.reset( new XclImpOvalObj( rRoot
) ); break;
236 case EXC_OBJTYPE_ARC
: xDrawObj
.reset( new XclImpArcObj( rRoot
) ); break;
237 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
238 case EXC_OBJTYPE_TEXT
: xDrawObj
.reset( new XclImpTextObj( rRoot
) ); break;
239 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
240 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
242 DBG_ERROR1( "XclImpDrawObjBase::ReadObj3 - unknown object type 0x%04hX", nObjType
);
243 rRoot
.GetTracer().TraceUnsupportedObjects();
244 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
248 xDrawObj
->ImplReadObj3( rStrm
);
252 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj4( XclImpStream
& rStrm
)
254 const XclImpRoot
& rRoot
= rStrm
.GetRoot();
255 XclImpDrawObjRef xDrawObj
;
257 if( rStrm
.GetRecLeft() >= 30 )
264 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
265 case EXC_OBJTYPE_LINE
: xDrawObj
.reset( new XclImpLineObj( rRoot
) ); break;
266 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
.reset( new XclImpRectObj( rRoot
) ); break;
267 case EXC_OBJTYPE_OVAL
: xDrawObj
.reset( new XclImpOvalObj( rRoot
) ); break;
268 case EXC_OBJTYPE_ARC
: xDrawObj
.reset( new XclImpArcObj( rRoot
) ); break;
269 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
270 case EXC_OBJTYPE_TEXT
: xDrawObj
.reset( new XclImpTextObj( rRoot
) ); break;
271 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
272 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
273 case EXC_OBJTYPE_POLYGON
: xDrawObj
.reset( new XclImpPolygonObj( rRoot
) ); break;
275 DBG_ERROR1( "XclImpDrawObjBase::ReadObj4 - unknown object type 0x%04hX", nObjType
);
276 rRoot
.GetTracer().TraceUnsupportedObjects();
277 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
281 xDrawObj
->ImplReadObj4( rStrm
);
285 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj5( XclImpStream
& rStrm
)
287 const XclImpRoot
& rRoot
= rStrm
.GetRoot();
288 XclImpDrawObjRef xDrawObj
;
290 if( rStrm
.GetRecLeft() >= 34 )
297 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
298 case EXC_OBJTYPE_LINE
: xDrawObj
.reset( new XclImpLineObj( rRoot
) ); break;
299 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
.reset( new XclImpRectObj( rRoot
) ); break;
300 case EXC_OBJTYPE_OVAL
: xDrawObj
.reset( new XclImpOvalObj( rRoot
) ); break;
301 case EXC_OBJTYPE_ARC
: xDrawObj
.reset( new XclImpArcObj( rRoot
) ); break;
302 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
303 case EXC_OBJTYPE_TEXT
: xDrawObj
.reset( new XclImpTextObj( rRoot
) ); break;
304 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
305 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
306 case EXC_OBJTYPE_POLYGON
: xDrawObj
.reset( new XclImpPolygonObj( rRoot
) ); break;
307 case EXC_OBJTYPE_CHECKBOX
: xDrawObj
.reset( new XclImpCheckBoxObj( rRoot
) ); break;
308 case EXC_OBJTYPE_OPTIONBUTTON
: xDrawObj
.reset( new XclImpOptionButtonObj( rRoot
) ); break;
309 case EXC_OBJTYPE_EDIT
: xDrawObj
.reset( new XclImpEditObj( rRoot
) ); break;
310 case EXC_OBJTYPE_LABEL
: xDrawObj
.reset( new XclImpLabelObj( rRoot
) ); break;
311 case EXC_OBJTYPE_DIALOG
: xDrawObj
.reset( new XclImpDialogObj( rRoot
) ); break;
312 case EXC_OBJTYPE_SPIN
: xDrawObj
.reset( new XclImpSpinButtonObj( rRoot
) ); break;
313 case EXC_OBJTYPE_SCROLLBAR
: xDrawObj
.reset( new XclImpScrollBarObj( rRoot
) ); break;
314 case EXC_OBJTYPE_LISTBOX
: xDrawObj
.reset( new XclImpListBoxObj( rRoot
) ); break;
315 case EXC_OBJTYPE_GROUPBOX
: xDrawObj
.reset( new XclImpGroupBoxObj( rRoot
) ); break;
316 case EXC_OBJTYPE_DROPDOWN
: xDrawObj
.reset( new XclImpDropDownObj( rRoot
) ); break;
318 DBG_ERROR1( "XclImpDrawObjBase::ReadObj5 - unknown object type 0x%04hX", nObjType
);
319 rRoot
.GetTracer().TraceUnsupportedObjects();
320 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
324 xDrawObj
->ImplReadObj5( rStrm
);
328 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj8( XclImpStream
& rStrm
)
330 const XclImpRoot
& rRoot
= rStrm
.GetRoot();
331 XclImpDrawObjRef xDrawObj
;
333 if( rStrm
.GetRecLeft() >= 10 )
335 sal_uInt16 nSubRecId
, nSubRecSize
, nObjType
;
336 rStrm
>> nSubRecId
>> nSubRecSize
>> nObjType
;
337 DBG_ASSERT( nSubRecId
== EXC_ID_OBJCMO
, "XclImpDrawObjBase::ReadObj8 - OBJCMO subrecord expected" );
338 if( (nSubRecId
== EXC_ID_OBJCMO
) && (nSubRecSize
>= 6) )
342 // in BIFF8, all simple objects support text
343 case EXC_OBJTYPE_LINE
:
344 case EXC_OBJTYPE_ARC
:
345 xDrawObj
.reset( new XclImpTextObj( rRoot
) );
346 // lines and arcs may be 2-dimensional
347 xDrawObj
->SetAreaObj( false );
350 // in BIFF8, all simple objects support text
351 case EXC_OBJTYPE_RECTANGLE
:
352 case EXC_OBJTYPE_OVAL
:
353 case EXC_OBJTYPE_POLYGON
:
354 case EXC_OBJTYPE_DRAWING
:
355 case EXC_OBJTYPE_TEXT
:
356 xDrawObj
.reset( new XclImpTextObj( rRoot
) );
359 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
360 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
361 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
362 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
363 case EXC_OBJTYPE_CHECKBOX
: xDrawObj
.reset( new XclImpCheckBoxObj( rRoot
) ); break;
364 case EXC_OBJTYPE_OPTIONBUTTON
: xDrawObj
.reset( new XclImpOptionButtonObj( rRoot
) ); break;
365 case EXC_OBJTYPE_EDIT
: xDrawObj
.reset( new XclImpEditObj( rRoot
) ); break;
366 case EXC_OBJTYPE_LABEL
: xDrawObj
.reset( new XclImpLabelObj( rRoot
) ); break;
367 case EXC_OBJTYPE_DIALOG
: xDrawObj
.reset( new XclImpDialogObj( rRoot
) ); break;
368 case EXC_OBJTYPE_SPIN
: xDrawObj
.reset( new XclImpSpinButtonObj( rRoot
) ); break;
369 case EXC_OBJTYPE_SCROLLBAR
: xDrawObj
.reset( new XclImpScrollBarObj( rRoot
) ); break;
370 case EXC_OBJTYPE_LISTBOX
: xDrawObj
.reset( new XclImpListBoxObj( rRoot
) ); break;
371 case EXC_OBJTYPE_GROUPBOX
: xDrawObj
.reset( new XclImpGroupBoxObj( rRoot
) ); break;
372 case EXC_OBJTYPE_DROPDOWN
: xDrawObj
.reset( new XclImpDropDownObj( rRoot
) ); break;
373 case EXC_OBJTYPE_NOTE
: xDrawObj
.reset( new XclImpNoteObj( rRoot
) ); break;
376 DBG_ERROR1( "XclImpDrawObjBase::ReadObj8 - unknown object type 0x%04hX", nObjType
);
377 rRoot
.GetTracer().TraceUnsupportedObjects();
378 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
383 xDrawObj
->ImplReadObj8( rStrm
);
387 void XclImpDrawObjBase::SetDffData( const DffObjData
& rDffObjData
, const String
& rObjName
, const String
& rHyperlink
, bool bVisible
, bool bAutoMargin
)
389 mnDffShapeId
= rDffObjData
.nShapeId
;
390 mnDffFlags
= rDffObjData
.nSpFlags
;
391 maObjName
= rObjName
;
392 maHyperlink
= rHyperlink
;
393 mbVisible
= bVisible
;
394 mbAutoMargin
= bAutoMargin
;
397 void XclImpDrawObjBase::SetAnchor( const XclObjAnchor
& rAnchor
)
399 mxAnchor
.reset( new XclObjAnchor( rAnchor
) );
402 String
XclImpDrawObjBase::GetObjName() const
404 String
sName( GetObjectManager().GetOleNameOverride( GetObjId() ) );
407 /* #118053# #i51348# Always return a non-empty name. Create English
408 default names depending on the object type. This is not implemented as
409 virtual functions in derived classes, as class type and object type may
411 if ( sName
.Len() == 0 )
412 sName
= ( (maObjName
.Len() > 0) ? maObjName
: GetObjectManager().GetDefaultObjName( *this ) );
416 bool XclImpDrawObjBase::IsValidSize( const Rectangle
& rAnchorRect
) const
418 // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0
420 ((rAnchorRect
.GetWidth() > 3) && (rAnchorRect
.GetHeight() > 1)) :
421 ((rAnchorRect
.GetWidth() > 3) || (rAnchorRect
.GetHeight() > 1));
424 ScRange
XclImpDrawObjBase::GetUsedArea() const
426 ScRange
aScUsedArea( ScAddress::INITIALIZE_INVALID
);
429 // #i44077# object inserted -> update used area for OLE object import
430 if( GetAddressConverter().ConvertRange( aScUsedArea
, *mxAnchor
, GetScTab(), GetScTab(), false ) )
432 // reduce range, if object ends directly on borders between two columns or rows
433 if( (mxAnchor
->mnRX
== 0) && (aScUsedArea
.aStart
.Col() < aScUsedArea
.aEnd
.Col()) )
434 aScUsedArea
.aEnd
.IncCol( -1 );
435 if( (mxAnchor
->mnBY
== 0) && (aScUsedArea
.aStart
.Row() < aScUsedArea
.aEnd
.Row()) )
436 aScUsedArea
.aEnd
.IncRow( -1 );
442 Rectangle
XclImpDrawObjBase::GetAnchorRect() const
444 Rectangle aAnchorRect
;
446 aAnchorRect
= mxAnchor
->GetRect( GetDoc(), MAP_100TH_MM
);
450 sal_Size
XclImpDrawObjBase::GetProgressSize() const
452 return DoGetProgressSize();
455 SdrObject
* XclImpDrawObjBase::CreateSdrObject( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
, bool bDffImport
) const
457 SdrObjectPtr xSdrObj
;
458 if( bDffImport
&& !mbCustomDff
)
460 rProgress
.Progress( GetProgressSize() );
464 xSdrObj
.reset( DoCreateSdrObj( rAnchorRect
, rProgress
) );
466 xSdrObj
->SetModel( GetDoc().GetDrawLayer() );
468 return xSdrObj
.release();
471 void XclImpDrawObjBase::ProcessSdrObject( SdrObject
& rSdrObj
) const
473 // default: front layer, derived classes may have to set other layer in DoProcessSdrObj()
474 rSdrObj
.NbcSetLayer( SC_LAYER_FRONT
);
476 // set object name (GetObjName() will always return a non-empty name)
477 rSdrObj
.SetName( GetObjName() );
479 // #i39167# full width for all objects regardless of horizontal alignment
480 rSdrObj
.SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK
) );
482 // automatic text margin
485 sal_Int32 nMargin
= GetObjectManager().GetDffManager().GetDefaultTextMargin();
486 rSdrObj
.SetMergedItem( SdrTextLeftDistItem( nMargin
) );
487 rSdrObj
.SetMergedItem( SdrTextRightDistItem( nMargin
) );
488 rSdrObj
.SetMergedItem( SdrTextUpperDistItem( nMargin
) );
489 rSdrObj
.SetMergedItem( SdrTextLowerDistItem( nMargin
) );
492 // macro and hyperlink
493 if( mbSimpleMacro
&& ((maMacroName
.Len() > 0) ||
494 (maHyperlink
.Len() > 0)) )
496 if( ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( &rSdrObj
, TRUE
) )
498 pInfo
->SetMacro( XclControlHelper::GetScMacroName( maMacroName
, GetDocShell() ) );
499 pInfo
->SetHlink( maHyperlink
);
503 // call virtual function for object type specific processing
504 DoProcessSdrObj( rSdrObj
);
507 // protected ------------------------------------------------------------------
509 void XclImpDrawObjBase::ReadName5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
)
514 // name length field is repeated before the name
515 maObjName
= rStrm
.ReadByteString( false );
516 // skip padding byte for word boundaries
517 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
521 void XclImpDrawObjBase::ReadMacro3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
524 rStrm
.Ignore( nMacroSize
);
525 // skip padding byte for word boundaries, not contained in nMacroSize
526 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
529 void XclImpDrawObjBase::ReadMacro4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
532 rStrm
.Ignore( nMacroSize
);
535 void XclImpDrawObjBase::ReadMacro5( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
538 rStrm
.Ignore( nMacroSize
);
541 void XclImpDrawObjBase::ReadMacro8( XclImpStream
& rStrm
)
544 if( rStrm
.GetRecLeft() > 6 )
546 // macro is stored in a tNameXR token containing a link to a defined name
547 sal_uInt16 nFmlaSize
;
550 DBG_ASSERT( nFmlaSize
== 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" );
554 sal_uInt16 nExtSheet
, nExtName
;
555 rStrm
>> nTokenId
>> nExtSheet
>> nExtName
;
556 DBG_ASSERT( nTokenId
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
),
557 "XclImpDrawObjBase::ReadMacro - tNameXR token expected" );
558 if( nTokenId
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
) )
560 maMacroName
= GetLinkManager().GetMacroName( nExtSheet
, nExtName
);
561 // #i38718# missing module name - try to find the macro in the imported modules
562 if( maMacroName
.Len() && (maMacroName
.Search( '.' ) == STRING_NOTFOUND
) )
563 if( SfxObjectShell
* pDocShell
= GetDocShell() )
564 if( StarBASIC
* pBasic
= pDocShell
->GetBasic() )
565 if( SbMethod
* pMethod
= dynamic_cast< SbMethod
* >( pBasic
->Find( maMacroName
, SbxCLASS_METHOD
) ) )
566 if( SbModule
* pModule
= pMethod
->GetModule() )
567 maMacroName
.Insert( '.', 0 ).Insert( pModule
->GetName(), 0 );
573 void XclImpDrawObjBase::ConvertLineStyle( SdrObject
& rSdrObj
, const XclObjLineData
& rLineData
) const
575 if( rLineData
.IsAuto() )
577 XclObjLineData aAutoData
;
578 aAutoData
.mnAuto
= 0;
579 ConvertLineStyle( rSdrObj
, aAutoData
);
583 long nLineWidth
= 35 * ::std::min( rLineData
.mnWidth
, EXC_OBJ_LINE_THICK
);
584 rSdrObj
.SetMergedItem( XLineWidthItem( nLineWidth
) );
585 rSdrObj
.SetMergedItem( XLineColorItem( EMPTY_STRING
, GetPalette().GetColor( rLineData
.mnColorIdx
) ) );
586 rSdrObj
.SetMergedItem( XLineJointItem( XLINEJOINT_MITER
) );
588 ULONG nDotLen
= ::std::max
< ULONG
>( 70 * rLineData
.mnWidth
, 35 );
589 ULONG nDashLen
= 3 * nDotLen
;
590 ULONG nDist
= 2 * nDotLen
;
592 switch( rLineData
.mnStyle
)
595 case EXC_OBJ_LINE_SOLID
:
596 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
598 case EXC_OBJ_LINE_DASH
:
599 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
600 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 0, nDotLen
, 1, nDashLen
, nDist
) ) );
602 case EXC_OBJ_LINE_DOT
:
603 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
604 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 1, nDotLen
, 0, nDashLen
, nDist
) ) );
606 case EXC_OBJ_LINE_DASHDOT
:
607 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
608 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 1, nDotLen
, 1, nDashLen
, nDist
) ) );
610 case EXC_OBJ_LINE_DASHDOTDOT
:
611 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
612 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 2, nDotLen
, 1, nDashLen
, nDist
) ) );
614 case EXC_OBJ_LINE_MEDTRANS
:
615 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
616 rSdrObj
.SetMergedItem( XLineTransparenceItem( 50 ) );
618 case EXC_OBJ_LINE_DARKTRANS
:
619 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
620 rSdrObj
.SetMergedItem( XLineTransparenceItem( 25 ) );
622 case EXC_OBJ_LINE_LIGHTTRANS
:
623 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
624 rSdrObj
.SetMergedItem( XLineTransparenceItem( 75 ) );
626 case EXC_OBJ_LINE_NONE
:
627 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_NONE
) );
633 void XclImpDrawObjBase::ConvertFillStyle( SdrObject
& rSdrObj
, const XclObjFillData
& rFillData
) const
635 if( rFillData
.IsAuto() )
637 XclObjFillData aAutoData
;
638 aAutoData
.mnAuto
= 0;
639 ConvertFillStyle( rSdrObj
, aAutoData
);
641 else if( rFillData
.mnPattern
== EXC_PATT_NONE
)
643 rSdrObj
.SetMergedItem( XFillStyleItem( XFILL_NONE
) );
647 Color aPattColor
= GetPalette().GetColor( rFillData
.mnPattColorIdx
);
648 Color aBackColor
= GetPalette().GetColor( rFillData
.mnBackColorIdx
);
649 if( (rFillData
.mnPattern
== EXC_PATT_SOLID
) || (aPattColor
== aBackColor
) )
651 rSdrObj
.SetMergedItem( XFillStyleItem( XFILL_SOLID
) );
652 rSdrObj
.SetMergedItem( XFillColorItem( EMPTY_STRING
, aPattColor
) );
656 static const sal_uInt8 sppnPatterns
[][ 8 ] =
658 { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
659 { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
660 { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
661 { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
662 { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
663 { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
664 { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
665 { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
666 { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
667 { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
668 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
669 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
670 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
671 { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
672 { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
673 { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
674 { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
676 const sal_uInt8
* const pnPattern
= sppnPatterns
[ ::std::min
< size_t >( rFillData
.mnPattern
- 2, STATIC_TABLE_SIZE( sppnPatterns
) ) ];
677 // create 2-colored 8x8 DIB
678 SvMemoryStream aMemStrm
;
679 aMemStrm
<< sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 );
680 aMemStrm
<< sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF );
681 aMemStrm
<< sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 );
682 for( size_t nIdx
= 0; nIdx
< 8; ++nIdx
)
683 aMemStrm
<< sal_uInt32( pnPattern
[ nIdx
] ); // 32-bit little-endian
684 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
686 aBitmap
.Read( aMemStrm
, FALSE
);
687 XOBitmap
aXOBitmap( aBitmap
);
688 aXOBitmap
.Bitmap2Array();
689 aXOBitmap
.SetBitmapType( XBITMAP_8X8
);
690 if( aXOBitmap
.GetBackgroundColor().GetColor() == COL_BLACK
)
691 ::std::swap( aPattColor
, aBackColor
);
692 aXOBitmap
.SetPixelColor( aPattColor
);
693 aXOBitmap
.SetBackgroundColor( aBackColor
);
694 rSdrObj
.SetMergedItem( XFillStyleItem( XFILL_BITMAP
) );
695 rSdrObj
.SetMergedItem( XFillBitmapItem( EMPTY_STRING
, aXOBitmap
) );
700 void XclImpDrawObjBase::ConvertFrameStyle( SdrObject
& rSdrObj
, sal_uInt16 nFrameFlags
) const
702 if( ::get_flag( nFrameFlags
, EXC_OBJ_FRAME_SHADOW
) )
704 rSdrObj
.SetMergedItem( SdrShadowItem( TRUE
) );
705 rSdrObj
.SetMergedItem( SdrShadowXDistItem( 35 ) );
706 rSdrObj
.SetMergedItem( SdrShadowYDistItem( 35 ) );
707 rSdrObj
.SetMergedItem( SdrShadowColorItem( EMPTY_STRING
, GetPalette().GetColor( EXC_COLOR_WINDOWTEXT
) ) );
711 Color
XclImpDrawObjBase::GetSolidLineColor( const XclObjLineData
& rLineData
) const
713 Color
aColor( COL_TRANSPARENT
);
714 if( rLineData
.IsAuto() )
716 XclObjLineData aAutoData
;
717 aAutoData
.mnAuto
= 0;
718 aColor
= GetSolidLineColor( aAutoData
);
720 else if( rLineData
.mnStyle
!= EXC_OBJ_LINE_NONE
)
722 aColor
= GetPalette().GetColor( rLineData
.mnColorIdx
);
727 Color
XclImpDrawObjBase::GetSolidFillColor( const XclObjFillData
& rFillData
) const
729 Color
aColor( COL_TRANSPARENT
);
730 if( rFillData
.IsAuto() )
732 XclObjFillData aAutoData
;
733 aAutoData
.mnAuto
= 0;
734 aColor
= GetSolidFillColor( aAutoData
);
736 else if( rFillData
.mnPattern
!= EXC_PATT_NONE
)
738 Color aPattColor
= GetPalette().GetColor( rFillData
.mnPattColorIdx
);
739 Color aBackColor
= GetPalette().GetColor( rFillData
.mnBackColorIdx
);
740 aColor
= XclTools::GetPatternColor( aPattColor
, aBackColor
, rFillData
.mnPattern
);
745 void XclImpDrawObjBase::DoReadObj3( XclImpStream
&, sal_uInt16
)
749 void XclImpDrawObjBase::DoReadObj4( XclImpStream
&, sal_uInt16
)
753 void XclImpDrawObjBase::DoReadObj5( XclImpStream
&, sal_uInt16
, sal_uInt16
)
757 void XclImpDrawObjBase::DoReadObj8SubRec( XclImpStream
&, sal_uInt16
, sal_uInt16
)
761 sal_Size
XclImpDrawObjBase::DoGetProgressSize() const
766 SdrObject
* XclImpDrawObjBase::DoCreateSdrObj( const Rectangle
&, ScfProgressBar
& rProgress
) const
768 rProgress
.Progress( GetProgressSize() );
772 void XclImpDrawObjBase::DoProcessSdrObj( SdrObject
& /*rSdrObj*/ ) const
774 // trace if object is not printable
776 GetTracer().TraceObjectNotPrintable();
779 void XclImpDrawObjBase::ImplReadObj3( XclImpStream
& rStrm
)
781 sal_uInt16 nObjFlags
, nMacroSize
;
782 XclObjAnchor
aAnchor( GetCurrScTab() );
784 // back to offset 4 (ignore object count field)
786 rStrm
>> mnObjType
>> maObjId
.mnObjId
>> nObjFlags
>> aAnchor
>> nMacroSize
;
789 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
790 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
791 SetAnchor( aAnchor
);
792 DoReadObj3( rStrm
, nMacroSize
);
795 void XclImpDrawObjBase::ImplReadObj4( XclImpStream
& rStrm
)
797 sal_uInt16 nObjFlags
, nMacroSize
;
798 XclObjAnchor
aAnchor( GetCurrScTab() );
800 // back to offset 4 (ignore object count field)
802 rStrm
>> mnObjType
>> maObjId
.mnObjId
>> nObjFlags
>> aAnchor
>> nMacroSize
;
805 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
806 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
807 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJ_PRINTABLE
);
808 SetAnchor( aAnchor
);
809 DoReadObj4( rStrm
, nMacroSize
);
812 void XclImpDrawObjBase::ImplReadObj5( XclImpStream
& rStrm
)
814 sal_uInt16 nObjFlags
, nMacroSize
, nNameLen
;
815 XclObjAnchor
aAnchor( GetCurrScTab() );
817 // back to offset 4 (ignore object count field)
819 rStrm
>> mnObjType
>> maObjId
.mnObjId
>> nObjFlags
>> aAnchor
>> nMacroSize
;
824 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
825 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
826 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJ_PRINTABLE
);
827 SetAnchor( aAnchor
);
828 DoReadObj5( rStrm
, nNameLen
, nMacroSize
);
831 void XclImpDrawObjBase::ImplReadObj8( XclImpStream
& rStrm
)
834 rStrm
.Seek( EXC_REC_SEEK_TO_BEGIN
);
837 while( bLoop
&& (rStrm
.GetRecLeft() >= 4) )
839 sal_uInt16 nSubRecId
, nSubRecSize
;
840 rStrm
>> nSubRecId
>> nSubRecSize
;
841 rStrm
.PushPosition();
842 // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
843 nSubRecSize
= static_cast< sal_uInt16
>( ::std::min
< sal_Size
>( nSubRecSize
, rStrm
.GetRecLeft() ) );
848 DBG_ASSERT( rStrm
.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" );
849 if( (rStrm
.GetRecPos() == 4) && (nSubRecSize
>= 6) )
851 sal_uInt16 nObjFlags
;
852 rStrm
>> mnObjType
>> maObjId
.mnObjId
>> nObjFlags
;
853 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJCMO_PRINTABLE
);
856 case EXC_ID_OBJMACRO
:
863 DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
867 rStrm
.Ignore( nSubRecSize
);
870 /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream
871 processing (e.g. charts), even if the OBJEND subrecord is missing. */
872 DoReadObj8SubRec( rStrm
, EXC_ID_OBJEND
, 0 );
874 /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
875 IMGDATA record following the OBJ record (but they use the image data
876 stored in DFF). The IMGDATA record may be continued by several CONTINUE
877 records. But the last CONTINUE record may be in fact an MSODRAWING
878 record that contains the DFF data of the next drawing object! So we
879 have to skip just enough CONTINUE records to look at the next
880 MSODRAWING/CONTINUE record. */
881 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
883 sal_uInt32 nDataSize
;
886 nDataSize
-= rStrm
.GetRecLeft();
887 // skip following CONTINUE records until IMGDATA ends
888 while( (nDataSize
> 0) && (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord() )
890 DBG_ASSERT( nDataSize
>= rStrm
.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" );
891 nDataSize
-= ::std::min
< sal_uInt32
>( rStrm
.GetRecLeft(), nDataSize
);
893 DBG_ASSERT( nDataSize
== 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" );
894 // next record may be MSODRAWING or CONTINUE or anything else
898 // ----------------------------------------------------------------------------
900 void XclImpDrawObjVector::InsertGrouped( XclImpDrawObjRef xDrawObj
)
903 if( XclImpGroupObj
* pGroupObj
= dynamic_cast< XclImpGroupObj
* >( back().get() ) )
904 if( pGroupObj
->TryInsert( xDrawObj
) )
906 push_back( xDrawObj
);
909 sal_Size
XclImpDrawObjVector::GetProgressSize() const
911 sal_Size nProgressSize
= 0;
912 for( const_iterator aIt
= begin(), aEnd
= end(); aIt
!= aEnd
; ++aIt
)
913 nProgressSize
+= (*aIt
)->GetProgressSize();
914 return nProgressSize
;
917 // ----------------------------------------------------------------------------
919 XclImpPhObj::XclImpPhObj( const XclImpRoot
& rRoot
) :
920 XclImpDrawObjBase( rRoot
)
922 SetProcessSdrObj( false );
925 // ----------------------------------------------------------------------------
927 XclImpGroupObj::XclImpGroupObj( const XclImpRoot
& rRoot
) :
928 XclImpDrawObjBase( rRoot
),
929 mnFirstUngrouped( 0 )
933 bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj
)
935 if( (xDrawObj
->GetScTab() != GetScTab()) || (xDrawObj
->GetObjId().mnObjId
== mnFirstUngrouped
) )
937 // insert into own list or into nested group
938 maChildren
.InsertGrouped( xDrawObj
);
942 void XclImpGroupObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
945 rStrm
>> mnFirstUngrouped
;
947 ReadMacro3( rStrm
, nMacroSize
);
950 void XclImpGroupObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
953 rStrm
>> mnFirstUngrouped
;
955 ReadMacro4( rStrm
, nMacroSize
);
958 void XclImpGroupObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
961 rStrm
>> mnFirstUngrouped
;
963 ReadName5( rStrm
, nNameLen
);
964 ReadMacro5( rStrm
, nMacroSize
);
967 sal_Size
XclImpGroupObj::DoGetProgressSize() const
969 return XclImpDrawObjBase::DoGetProgressSize() + maChildren
.GetProgressSize();
972 SdrObject
* XclImpGroupObj::DoCreateSdrObj( const Rectangle
& /*rAnchorRect*/, ScfProgressBar
& rProgress
) const
974 TSdrObjectPtr
< SdrObjGroup
> xSdrObj( new SdrObjGroup
);
975 // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle
976 for( XclImpDrawObjVector::const_iterator aIt
= maChildren
.begin(), aEnd
= maChildren
.end(); aIt
!= aEnd
; ++aIt
)
977 GetObjectManager().GetDffManager().ProcessObject( xSdrObj
->GetSubList(), **aIt
);
978 rProgress
.Progress();
979 return xSdrObj
.release();
982 // ----------------------------------------------------------------------------
984 XclImpLineObj::XclImpLineObj( const XclImpRoot
& rRoot
) :
985 XclImpDrawObjBase( rRoot
),
987 mnStartPoint( EXC_OBJ_LINE_TL
)
992 void XclImpLineObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
994 rStrm
>> maLineData
>> mnArrows
>> mnStartPoint
;
996 ReadMacro3( rStrm
, nMacroSize
);
999 void XclImpLineObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1001 rStrm
>> maLineData
>> mnArrows
>> mnStartPoint
;
1003 ReadMacro4( rStrm
, nMacroSize
);
1006 void XclImpLineObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1008 rStrm
>> maLineData
>> mnArrows
>> mnStartPoint
;
1010 ReadName5( rStrm
, nNameLen
);
1011 ReadMacro5( rStrm
, nMacroSize
);
1014 SdrObject
* XclImpLineObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1016 ::basegfx::B2DPolygon aB2DPolygon
;
1017 switch( mnStartPoint
)
1020 case EXC_OBJ_LINE_TL
:
1021 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Top() ) );
1022 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Bottom() ) );
1024 case EXC_OBJ_LINE_TR
:
1025 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Top() ) );
1026 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Bottom() ) );
1028 case EXC_OBJ_LINE_BR
:
1029 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Bottom() ) );
1030 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Top() ) );
1032 case EXC_OBJ_LINE_BL
:
1033 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Bottom() ) );
1034 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Top() ) );
1037 SdrObjectPtr
xSdrObj( new SdrPathObj( OBJ_LINE
, ::basegfx::B2DPolyPolygon( aB2DPolygon
) ) );
1038 ConvertLineStyle( *xSdrObj
, maLineData
);
1041 sal_uInt8 nArrowType
= ::extract_value
< sal_uInt8
>( mnArrows
, 0, 4 );
1042 bool bLineStart
= false;
1043 bool bLineEnd
= false;
1044 bool bFilled
= false;
1045 switch( nArrowType
)
1047 case EXC_OBJ_ARROW_OPEN
: bLineStart
= false; bLineEnd
= true; bFilled
= false; break;
1048 case EXC_OBJ_ARROW_OPENBOTH
: bLineStart
= true; bLineEnd
= true; bFilled
= false; break;
1049 case EXC_OBJ_ARROW_FILLED
: bLineStart
= false; bLineEnd
= true; bFilled
= true; break;
1050 case EXC_OBJ_ARROW_FILLEDBOTH
: bLineStart
= true; bLineEnd
= true; bFilled
= true; break;
1052 if( bLineStart
|| bLineEnd
)
1054 sal_uInt8 nArrowWidth
= ::extract_value
< sal_uInt8
>( mnArrows
, 4, 4 );
1055 double fArrowWidth
= 3.0;
1056 switch( nArrowWidth
)
1058 case EXC_OBJ_ARROW_NARROW
: fArrowWidth
= 2.0; break;
1059 case EXC_OBJ_ARROW_MEDIUM
: fArrowWidth
= 3.0; break;
1060 case EXC_OBJ_ARROW_WIDE
: fArrowWidth
= 5.0; break;
1063 sal_uInt8 nArrowLength
= ::extract_value
< sal_uInt8
>( mnArrows
, 8, 4 );
1064 double fArrowLength
= 3.0;
1065 switch( nArrowLength
)
1067 case EXC_OBJ_ARROW_NARROW
: fArrowLength
= 2.5; break;
1068 case EXC_OBJ_ARROW_MEDIUM
: fArrowLength
= 3.5; break;
1069 case EXC_OBJ_ARROW_WIDE
: fArrowLength
= 6.0; break;
1072 ::basegfx::B2DPolygon aArrowPoly
;
1073 #define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) )
1076 aArrowPoly
.append( EXC_ARROW_POINT( 0, 100 ) );
1077 aArrowPoly
.append( EXC_ARROW_POINT( 50, 0 ) );
1078 aArrowPoly
.append( EXC_ARROW_POINT( 100, 100 ) );
1082 sal_uInt8 nLineWidth
= ::limit_cast
< sal_uInt8
>( maLineData
.mnWidth
, EXC_OBJ_LINE_THIN
, EXC_OBJ_LINE_THICK
);
1083 aArrowPoly
.append( EXC_ARROW_POINT( 50, 0 ) );
1084 aArrowPoly
.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth
) );
1085 aArrowPoly
.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth
, 100 ) );
1086 aArrowPoly
.append( EXC_ARROW_POINT( 50, 12 * nLineWidth
) );
1087 aArrowPoly
.append( EXC_ARROW_POINT( 5 * nLineWidth
, 100 ) );
1088 aArrowPoly
.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth
) );
1090 #undef EXC_ARROW_POINT
1092 ::basegfx::B2DPolyPolygon
aArrowPolyPoly( aArrowPoly
);
1093 long nWidth
= static_cast< long >( 125 * fArrowWidth
);
1096 xSdrObj
->SetMergedItem( XLineStartItem( EMPTY_STRING
, aArrowPolyPoly
) );
1097 xSdrObj
->SetMergedItem( XLineStartWidthItem( nWidth
) );
1098 xSdrObj
->SetMergedItem( XLineStartCenterItem( FALSE
) );
1102 xSdrObj
->SetMergedItem( XLineEndItem( EMPTY_STRING
, aArrowPolyPoly
) );
1103 xSdrObj
->SetMergedItem( XLineEndWidthItem( nWidth
) );
1104 xSdrObj
->SetMergedItem( XLineEndCenterItem( FALSE
) );
1107 rProgress
.Progress();
1108 return xSdrObj
.release();
1111 // ----------------------------------------------------------------------------
1113 XclImpRectObj::XclImpRectObj( const XclImpRoot
& rRoot
) :
1114 XclImpDrawObjBase( rRoot
),
1120 void XclImpRectObj::ReadFrameData( XclImpStream
& rStrm
)
1122 rStrm
>> maFillData
>> maLineData
>> mnFrameFlags
;
1125 void XclImpRectObj::ConvertRectStyle( SdrObject
& rSdrObj
) const
1127 ConvertLineStyle( rSdrObj
, maLineData
);
1128 ConvertFillStyle( rSdrObj
, maFillData
);
1129 ConvertFrameStyle( rSdrObj
, mnFrameFlags
);
1132 void XclImpRectObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1134 ReadFrameData( rStrm
);
1135 ReadMacro3( rStrm
, nMacroSize
);
1138 void XclImpRectObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1140 ReadFrameData( rStrm
);
1141 ReadMacro4( rStrm
, nMacroSize
);
1144 void XclImpRectObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1146 ReadFrameData( rStrm
);
1147 ReadName5( rStrm
, nNameLen
);
1148 ReadMacro5( rStrm
, nMacroSize
);
1151 SdrObject
* XclImpRectObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1153 SdrObjectPtr
xSdrObj( new SdrRectObj( rAnchorRect
) );
1154 ConvertRectStyle( *xSdrObj
);
1155 rProgress
.Progress();
1156 return xSdrObj
.release();
1159 // ----------------------------------------------------------------------------
1161 XclImpOvalObj::XclImpOvalObj( const XclImpRoot
& rRoot
) :
1162 XclImpRectObj( rRoot
)
1166 SdrObject
* XclImpOvalObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1168 SdrObjectPtr
xSdrObj( new SdrCircObj( OBJ_CIRC
, rAnchorRect
) );
1169 ConvertRectStyle( *xSdrObj
);
1170 rProgress
.Progress();
1171 return xSdrObj
.release();
1174 // ----------------------------------------------------------------------------
1176 XclImpArcObj::XclImpArcObj( const XclImpRoot
& rRoot
) :
1177 XclImpDrawObjBase( rRoot
),
1178 mnQuadrant( EXC_OBJ_ARC_TR
)
1180 SetAreaObj( false ); // arc may be 2-dimensional
1183 void XclImpArcObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1185 rStrm
>> maFillData
>> maLineData
>> mnQuadrant
;
1187 ReadMacro3( rStrm
, nMacroSize
);
1190 void XclImpArcObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1192 rStrm
>> maFillData
>> maLineData
>> mnQuadrant
;
1194 ReadMacro4( rStrm
, nMacroSize
);
1197 void XclImpArcObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1199 rStrm
>> maFillData
>> maLineData
>> mnQuadrant
;
1201 ReadName5( rStrm
, nNameLen
);
1202 ReadMacro5( rStrm
, nMacroSize
);
1205 SdrObject
* XclImpArcObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1207 Rectangle aNewRect
= rAnchorRect
;
1208 long nStartAngle
= 0;
1210 switch( mnQuadrant
)
1213 case EXC_OBJ_ARC_TR
:
1216 aNewRect
.Left() -= rAnchorRect
.GetWidth();
1217 aNewRect
.Bottom() += rAnchorRect
.GetHeight();
1219 case EXC_OBJ_ARC_TL
:
1222 aNewRect
.Right() += rAnchorRect
.GetWidth();
1223 aNewRect
.Bottom() += rAnchorRect
.GetHeight();
1225 case EXC_OBJ_ARC_BL
:
1226 nStartAngle
= 18000;
1228 aNewRect
.Right() += rAnchorRect
.GetWidth();
1229 aNewRect
.Top() -= rAnchorRect
.GetHeight();
1231 case EXC_OBJ_ARC_BR
:
1232 nStartAngle
= 27000;
1234 aNewRect
.Left() -= rAnchorRect
.GetWidth();
1235 aNewRect
.Top() -= rAnchorRect
.GetHeight();
1238 SdrObjKind eObjKind
= maFillData
.IsFilled() ? OBJ_SECT
: OBJ_CARC
;
1239 SdrObjectPtr
xSdrObj( new SdrCircObj( eObjKind
, aNewRect
, nStartAngle
, nEndAngle
) );
1240 ConvertFillStyle( *xSdrObj
, maFillData
);
1241 ConvertLineStyle( *xSdrObj
, maLineData
);
1242 rProgress
.Progress();
1243 return xSdrObj
.release();
1246 // ----------------------------------------------------------------------------
1248 XclImpPolygonObj::XclImpPolygonObj( const XclImpRoot
& rRoot
) :
1249 XclImpRectObj( rRoot
),
1253 SetAreaObj( false ); // polygon may be 2-dimensional
1256 void XclImpPolygonObj::ReadCoordList( XclImpStream
& rStrm
)
1258 if( (rStrm
.GetNextRecId() == EXC_ID_COORDLIST
) && rStrm
.StartNextRecord() )
1260 DBG_ASSERT( rStrm
.GetRecLeft() / 4 == mnPointCount
, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" );
1261 while( rStrm
.GetRecLeft() >= 4 )
1265 maCoords
.push_back( Point( nX
, nY
) );
1270 void XclImpPolygonObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1272 ReadFrameData( rStrm
);
1273 rStrm
>> mnPolyFlags
;
1275 rStrm
>> mnPointCount
;
1277 ReadMacro4( rStrm
, nMacroSize
);
1278 ReadCoordList( rStrm
);
1281 void XclImpPolygonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1283 ReadFrameData( rStrm
);
1284 rStrm
>> mnPolyFlags
;
1286 rStrm
>> mnPointCount
;
1288 ReadName5( rStrm
, nNameLen
);
1289 ReadMacro5( rStrm
, nMacroSize
);
1290 ReadCoordList( rStrm
);
1295 ::basegfx::B2DPoint
lclGetPolyPoint( const Rectangle
& rAnchorRect
, const Point
& rPoint
)
1297 return ::basegfx::B2DPoint(
1298 rAnchorRect
.Left() + static_cast< sal_Int32
>( ::std::min
< double >( rPoint
.X(), 16384.0 ) / 16384.0 * rAnchorRect
.GetWidth() + 0.5 ),
1299 rAnchorRect
.Top() + static_cast< sal_Int32
>( ::std::min
< double >( rPoint
.Y(), 16384.0 ) / 16384.0 * rAnchorRect
.GetHeight() + 0.5 ) );
1304 SdrObject
* XclImpPolygonObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1306 SdrObjectPtr xSdrObj
;
1307 if( maCoords
.size() >= 2 )
1309 // create the polygon
1310 ::basegfx::B2DPolygon aB2DPolygon
;
1311 for( PointVector::const_iterator aIt
= maCoords
.begin(), aEnd
= maCoords
.end(); aIt
!= aEnd
; ++aIt
)
1312 aB2DPolygon
.append( lclGetPolyPoint( rAnchorRect
, *aIt
) );
1313 // close polygon if specified
1314 if( ::get_flag( mnPolyFlags
, EXC_OBJ_POLY_CLOSED
) && (maCoords
.front() != maCoords
.back()) )
1315 aB2DPolygon
.append( lclGetPolyPoint( rAnchorRect
, maCoords
.front() ) );
1316 // create the SdrObject
1317 SdrObjKind eObjKind
= maFillData
.IsFilled() ? OBJ_PATHPOLY
: OBJ_PATHPLIN
;
1318 xSdrObj
.reset( new SdrPathObj( eObjKind
, ::basegfx::B2DPolyPolygon( aB2DPolygon
) ) );
1319 ConvertRectStyle( *xSdrObj
);
1321 rProgress
.Progress();
1322 return xSdrObj
.release();
1325 // ----------------------------------------------------------------------------
1327 void XclImpObjTextData::ReadByteString( XclImpStream
& rStrm
)
1330 if( maData
.mnTextLen
> 0 )
1332 mxString
.reset( new XclImpString( rStrm
.ReadRawByteString( maData
.mnTextLen
) ) );
1333 // skip padding byte for word boundaries
1334 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
1338 void XclImpObjTextData::ReadFormats( XclImpStream
& rStrm
)
1341 mxString
->ReadObjFormats( rStrm
, maData
.mnFormatSize
);
1343 rStrm
.Ignore( maData
.mnFormatSize
);
1346 // ----------------------------------------------------------------------------
1348 XclImpTextObj::XclImpTextObj( const XclImpRoot
& rRoot
) :
1349 XclImpRectObj( rRoot
)
1353 void XclImpTextObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1355 ReadFrameData( rStrm
);
1356 maTextData
.maData
.ReadObj3( rStrm
);
1357 ReadMacro3( rStrm
, nMacroSize
);
1358 maTextData
.ReadByteString( rStrm
);
1359 maTextData
.ReadFormats( rStrm
);
1362 void XclImpTextObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1364 ReadFrameData( rStrm
);
1365 maTextData
.maData
.ReadObj3( rStrm
);
1366 ReadMacro4( rStrm
, nMacroSize
);
1367 maTextData
.ReadByteString( rStrm
);
1368 maTextData
.ReadFormats( rStrm
);
1371 void XclImpTextObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1373 ReadFrameData( rStrm
);
1374 maTextData
.maData
.ReadObj5( rStrm
);
1375 ReadName5( rStrm
, nNameLen
);
1376 ReadMacro5( rStrm
, nMacroSize
);
1377 maTextData
.ReadByteString( rStrm
);
1378 rStrm
.Ignore( maTextData
.maData
.mnLinkSize
); // ignore text link formula
1379 maTextData
.ReadFormats( rStrm
);
1382 SdrObject
* XclImpTextObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1384 TSdrObjectPtr
< SdrObjCustomShape
> xSdrObj( new SdrObjCustomShape
);
1385 xSdrObj
->NbcSetSnapRect( rAnchorRect
);
1386 OUString aRectType
= CREATE_OUSTRING( "rectangle" );
1387 xSdrObj
->MergeDefaultAttributes( &aRectType
);
1388 ConvertRectStyle( *xSdrObj
);
1389 BOOL bAutoSize
= ::get_flag( maTextData
.maData
.mnFlags
, EXC_OBJ_TEXT_AUTOSIZE
);
1390 xSdrObj
->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize
) );
1391 xSdrObj
->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize
) );
1392 xSdrObj
->SetMergedItem( SdrTextWordWrapItem( TRUE
) );
1393 rProgress
.Progress();
1394 return xSdrObj
.release();
1397 void XclImpTextObj::DoProcessSdrObj( SdrObject
& rSdrObj
) const
1400 if( SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( &rSdrObj
) )
1402 if( maTextData
.mxString
.is() )
1404 if( maTextData
.mxString
->IsRich() )
1407 ::std::auto_ptr
< EditTextObject
> xEditObj(
1408 XclImpStringHelper::CreateTextObject( GetRoot(), *maTextData
.mxString
) );
1409 OutlinerParaObject
* pOutlineObj
= new OutlinerParaObject( *xEditObj
);
1410 pOutlineObj
->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT
);
1411 // text object takes ownership of the outliner object
1412 pTextObj
->NbcSetOutlinerParaObject( pOutlineObj
);
1417 pTextObj
->NbcSetText( maTextData
.mxString
->GetText() );
1420 /* #i96858# Do not apply any formatting if there is no text.
1421 SdrObjCustomShape::SetVerticalWriting (initiated from
1422 SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which
1423 ensures that we can erroneously write a ClientTextbox record
1424 (with no content) while exporting to XLS, which can cause a
1425 corrupted exported document. */
1427 // horizontal text alignment
1428 SvxAdjust eHorAlign
= SVX_ADJUST_LEFT
;
1429 switch( maTextData
.maData
.GetHorAlign() )
1431 case EXC_OBJ_HOR_LEFT
: eHorAlign
= SVX_ADJUST_LEFT
; break;
1432 case EXC_OBJ_HOR_CENTER
: eHorAlign
= SVX_ADJUST_CENTER
; break;
1433 case EXC_OBJ_HOR_RIGHT
: eHorAlign
= SVX_ADJUST_RIGHT
; break;
1434 case EXC_OBJ_HOR_JUSTIFY
: eHorAlign
= SVX_ADJUST_BLOCK
; break;
1436 rSdrObj
.SetMergedItem( SvxAdjustItem( eHorAlign
, EE_PARA_JUST
) );
1438 // vertical text alignment
1439 SdrTextVertAdjust eVerAlign
= SDRTEXTVERTADJUST_TOP
;
1440 switch( maTextData
.maData
.GetVerAlign() )
1442 case EXC_OBJ_VER_TOP
: eVerAlign
= SDRTEXTVERTADJUST_TOP
; break;
1443 case EXC_OBJ_VER_CENTER
: eVerAlign
= SDRTEXTVERTADJUST_CENTER
; break;
1444 case EXC_OBJ_VER_BOTTOM
: eVerAlign
= SDRTEXTVERTADJUST_BOTTOM
; break;
1445 case EXC_OBJ_VER_JUSTIFY
: eVerAlign
= SDRTEXTVERTADJUST_BLOCK
; break;
1447 rSdrObj
.SetMergedItem( SdrTextVertAdjustItem( eVerAlign
) );
1449 // orientation (this is only a fake, drawing does not support real text orientation)
1450 namespace csst
= ::com::sun::star::text
;
1451 csst::WritingMode eWriteMode
= csst::WritingMode_LR_TB
;
1452 switch( maTextData
.maData
.mnOrient
)
1454 case EXC_OBJ_ORIENT_NONE
: eWriteMode
= csst::WritingMode_LR_TB
; break;
1455 case EXC_OBJ_ORIENT_STACKED
: eWriteMode
= csst::WritingMode_TB_RL
; break;
1456 case EXC_OBJ_ORIENT_90CCW
: eWriteMode
= csst::WritingMode_TB_RL
; break;
1457 case EXC_OBJ_ORIENT_90CW
: eWriteMode
= csst::WritingMode_TB_RL
; break;
1459 rSdrObj
.SetMergedItem( SvxWritingModeItem( eWriteMode
, SDRATTR_TEXTDIRECTION
) );
1462 // base class processing
1463 XclImpRectObj::DoProcessSdrObj( rSdrObj
);
1466 // ----------------------------------------------------------------------------
1468 XclImpChartObj::XclImpChartObj( const XclImpRoot
& rRoot
, bool bOwnTab
) :
1469 XclImpRectObj( rRoot
),
1472 SetSimpleMacro( false );
1473 SetCustomDffObj( true );
1476 void XclImpChartObj::ReadChartSubStream( XclImpStream
& rStrm
)
1478 if( mbOwnTab
? (rStrm
.GetRecId() == EXC_ID5_BOF
) : ((rStrm
.GetNextRecId() == EXC_ID5_BOF
) && rStrm
.StartNextRecord()) )
1480 sal_uInt16 nBofType
;
1483 DBG_ASSERT( nBofType
== EXC_BOF_CHART
, "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
1485 // read chart, even if BOF record contains wrong substream identifier
1486 mxChart
.reset( new XclImpChart( GetRoot(), mbOwnTab
) );
1487 mxChart
->ReadChartSubStream( rStrm
);
1493 DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" );
1497 void XclImpChartObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1499 // read OBJ record and the following chart substream
1500 ReadFrameData( rStrm
);
1502 ReadMacro3( rStrm
, nMacroSize
);
1504 ReadChartSubStream( rStrm
);
1506 // set frame format from OBJ record, it is used if chart itself is transparent
1508 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1511 void XclImpChartObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1513 // read OBJ record and the following chart substream
1514 ReadFrameData( rStrm
);
1516 ReadMacro4( rStrm
, nMacroSize
);
1518 ReadChartSubStream( rStrm
);
1520 // set frame format from OBJ record, it is used if chart itself is transparent
1522 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1525 void XclImpChartObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1527 // read OBJ record and the following chart substream
1528 ReadFrameData( rStrm
);
1530 ReadName5( rStrm
, nNameLen
);
1531 ReadMacro5( rStrm
, nMacroSize
);
1532 ReadChartSubStream( rStrm
);
1533 // set frame format from OBJ record, it is used if chart itself is transparent
1535 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1538 void XclImpChartObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16
/*nSubRecSize*/ )
1540 // read the following chart substream
1541 if( nSubRecId
== EXC_ID_OBJEND
)
1543 // enable CONTINUE handling for the entire chart substream
1544 rStrm
.ResetRecord( true );
1545 ReadChartSubStream( rStrm
);
1546 /* #90118# disable CONTINUE handling again to be able to read
1547 following CONTINUE records as MSODRAWING records. */
1548 rStrm
.ResetRecord( false );
1552 sal_Size
XclImpChartObj::DoGetProgressSize() const
1554 return mxChart
.is() ? mxChart
->GetProgressSize() : 1;
1557 SdrObject
* XclImpChartObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1559 SdrObjectPtr xSdrObj
;
1560 SfxObjectShell
* pDocShell
= GetDocShell();
1561 if( SvtModuleOptions().IsChart() && pDocShell
&& mxChart
.is() && !mxChart
->IsPivotChart() )
1563 // create embedded chart object
1564 OUString aEmbObjName
;
1565 Reference
< XEmbeddedObject
> xEmbObj
= pDocShell
->GetEmbeddedObjectContainer().
1566 CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID
).GetByteSequence(), aEmbObjName
);
1568 /* Set the size to the embedded object, this prevents that font sizes
1569 of text objects are changed in the chart when the object is
1570 inserted into the draw page. */
1571 sal_Int64 nAspect
= ::com::sun::star::embed::Aspects::MSOLE_CONTENT
;
1572 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj
->getMapUnit( nAspect
) );
1573 Size
aSize( Window::LogicToLogic( rAnchorRect
.GetSize(), MapMode( MAP_100TH_MM
), MapMode( aUnit
) ) );
1574 ::com::sun::star::awt::Size
aAwtSize( aSize
.Width(), aSize
.Height() );
1575 xEmbObj
->setVisualAreaSize( nAspect
, aAwtSize
);
1577 // create the container OLE object
1578 xSdrObj
.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj
, nAspect
), aEmbObjName
, rAnchorRect
) );
1580 // convert Excel chart to OOo Chart
1581 if( svt::EmbeddedObjectRef::TryRunningState( xEmbObj
) )
1583 Reference
< XModel
> xModel( xEmbObj
->getComponent(), UNO_QUERY
);
1584 mxChart
->Convert( xModel
, rProgress
, aEmbObjName
);
1586 Reference
< XEmbedPersist
> xPers( xEmbObj
, UNO_QUERY
);
1592 return xSdrObj
.release();
1595 void XclImpChartObj::FinalizeTabChart()
1597 /* #i44077# Calculate and store DFF anchor for sheet charts.
1598 Needed to get used area if this chart is inserted as OLE object. */
1599 DBG_ASSERT( mbOwnTab
, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" );
1601 // set uninitialized page to landscape
1602 if( !GetPageSettings().GetPageData().mbValid
)
1603 GetPageSettings().SetPaperSize( EXC_PAPERSIZE_DEFAULT
, false );
1605 // calculate size of the chart object
1606 const XclPageData
& rPageData
= GetPageSettings().GetPageData();
1607 Size
aPaperSize( rPageData
.GetScPaperSize() );
1609 long nWidth
= XclTools::GetHmmFromTwips( aPaperSize
.Width() );
1610 long nHeight
= XclTools::GetHmmFromTwips( aPaperSize
.Height() );
1612 // subtract page margins, give 1cm extra space
1613 nWidth
-= (XclTools::GetHmmFromInch( rPageData
.mfLeftMargin
+ rPageData
.mfRightMargin
) + 2000);
1614 nHeight
-= (XclTools::GetHmmFromInch( rPageData
.mfTopMargin
+ rPageData
.mfBottomMargin
) + 1000);
1616 // print column/row headers?
1617 if( rPageData
.mbPrintHeadings
)
1623 // create the object anchor
1624 XclObjAnchor
aAnchor( GetScTab() );
1625 aAnchor
.SetRect( GetDoc(), Rectangle( 1000, 500, nWidth
, nHeight
), MAP_100TH_MM
);
1626 SetAnchor( aAnchor
);
1629 // ----------------------------------------------------------------------------
1631 XclImpNoteObj::XclImpNoteObj( const XclImpRoot
& rRoot
) :
1632 XclImpTextObj( rRoot
),
1633 maScPos( ScAddress::INITIALIZE_INVALID
),
1636 SetSimpleMacro( false );
1637 // caption object will be created manually
1638 SetInsertSdrObj( false );
1641 void XclImpNoteObj::SetNoteData( const ScAddress
& rScPos
, sal_uInt16 nNoteFlags
)
1644 mnNoteFlags
= nNoteFlags
;
1647 void XclImpNoteObj::DoProcessSdrObj( SdrObject
& rSdrObj
) const
1649 // create formatted text
1650 XclImpTextObj::DoProcessSdrObj( rSdrObj
);
1651 OutlinerParaObject
* pOutlinerObj
= rSdrObj
.GetOutlinerParaObject();
1652 if( maScPos
.IsValid() && pOutlinerObj
)
1654 // create cell note with all data from drawing object
1655 ScNoteUtil::CreateNoteFromObjectData(
1657 rSdrObj
.GetMergedItemSet().Clone(), // new object on heap expected
1658 new OutlinerParaObject( *pOutlinerObj
), // new object on heap expected
1659 rSdrObj
.GetLogicRect(),
1660 ::get_flag( mnNoteFlags
, EXC_NOTE_VISIBLE
),
1665 // ----------------------------------------------------------------------------
1667 XclImpControlHelper::XclImpControlHelper( const XclImpRoot
& rRoot
, XclCtrlBindMode eBindMode
) :
1669 meBindMode( eBindMode
)
1673 XclImpControlHelper::~XclImpControlHelper()
1677 SdrObject
* XclImpControlHelper::CreateSdrObjectFromShape(
1678 const Reference
< XShape
>& rxShape
, const Rectangle
& rAnchorRect
) const
1681 SdrObjectPtr
xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape
) );
1684 xSdrObj
->NbcSetSnapRect( rAnchorRect
);
1685 // #i30543# insert into control layer
1686 xSdrObj
->NbcSetLayer( SC_LAYER_CONTROLS
);
1688 return xSdrObj
.release();
1691 void XclImpControlHelper::ApplySheetLinkProps() const
1694 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( mxShape
);
1695 if( !xCtrlModel
.is() )
1697 ScfPropertySet
aPropSet( xCtrlModel
);
1700 if( SfxObjectShell
* pDocShell
= mrRoot
.GetDocShell() )
1702 Reference
< XMultiServiceFactory
> xFactory( pDocShell
->GetModel(), UNO_QUERY
);
1706 if( mxCellLink
.is() ) try
1708 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY_THROW
);
1710 // create argument sequence for createInstanceWithArguments()
1711 CellAddress aApiAddress
;
1712 ScUnoConversion::FillApiAddress( aApiAddress
, *mxCellLink
);
1715 aValue
.Name
= CREATE_OUSTRING( SC_UNONAME_BOUNDCELL
);
1716 aValue
.Value
<<= aApiAddress
;
1718 Sequence
< Any
> aArgs( 1 );
1719 aArgs
[ 0 ] <<= aValue
;
1721 // create the CellValueBinding instance and set at the control model
1722 OUString aServiceName
;
1723 switch( meBindMode
)
1725 case EXC_CTRL_BINDCONTENT
: aServiceName
= CREATE_OUSTRING( SC_SERVICENAME_VALBIND
); break;
1726 case EXC_CTRL_BINDPOSITION
: aServiceName
= CREATE_OUSTRING( SC_SERVICENAME_LISTCELLBIND
); break;
1728 Reference
< XValueBinding
> xBinding(
1729 xFactory
->createInstanceWithArguments( aServiceName
, aArgs
), UNO_QUERY_THROW
);
1730 xBindable
->setValueBinding( xBinding
);
1732 catch( const Exception
& )
1737 if( mxSrcRange
.is() ) try
1739 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY_THROW
);
1741 // create argument sequence for createInstanceWithArguments()
1742 CellRangeAddress aApiRange
;
1743 ScUnoConversion::FillApiRange( aApiRange
, *mxSrcRange
);
1746 aValue
.Name
= CREATE_OUSTRING( SC_UNONAME_CELLRANGE
);
1747 aValue
.Value
<<= aApiRange
;
1749 Sequence
< Any
> aArgs( 1 );
1750 aArgs
[ 0 ] <<= aValue
;
1752 // create the EntrySource instance and set at the control model
1753 Reference
< XListEntrySource
> xEntrySource( xFactory
->createInstanceWithArguments(
1754 CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE
), aArgs
), UNO_QUERY_THROW
);
1755 xEntrySink
->setListEntrySource( xEntrySource
);
1757 catch( const Exception
& )
1764 void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase
& rDrawObj
) const
1766 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( mxShape
);
1767 if( !xCtrlModel
.is() )
1770 ApplySheetLinkProps();
1772 ScfPropertySet
aPropSet( xCtrlModel
);
1774 // #118053# #i51348# set object name at control model
1775 aPropSet
.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj
.GetObjName() );
1777 // control visible and printable?
1778 aPropSet
.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj
.IsVisible() );
1779 aPropSet
.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj
.IsPrintable() );
1782 // virtual call for type specific processing
1783 DoProcessControl( aPropSet
);
1786 void XclImpControlHelper::ReadCellLinkFormula( XclImpStream
& rStrm
, bool bWithBoundSize
)
1788 ScRangeList aScRanges
;
1789 ReadRangeList( aScRanges
, rStrm
, bWithBoundSize
);
1790 // Use first cell of first range
1791 if( const ScRange
* pScRange
= aScRanges
.GetObject( 0 ) )
1792 mxCellLink
.reset( new ScAddress( pScRange
->aStart
) );
1795 void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream
& rStrm
, bool bWithBoundSize
)
1797 ScRangeList aScRanges
;
1798 ReadRangeList( aScRanges
, rStrm
, bWithBoundSize
);
1800 if( const ScRange
* pScRange
= aScRanges
.GetObject( 0 ) )
1801 mxSrcRange
.reset( new ScRange( *pScRange
) );
1804 void XclImpControlHelper::DoProcessControl( ScfPropertySet
& ) const
1808 void XclImpControlHelper::ReadRangeList( ScRangeList
& rScRanges
, XclImpStream
& rStrm
)
1810 XclTokenArray aXclTokArr
;
1811 aXclTokArr
.ReadSize( rStrm
);
1813 aXclTokArr
.ReadArray( rStrm
);
1814 mrRoot
.GetFormulaCompiler().CreateRangeList( rScRanges
, EXC_FMLATYPE_CONTROL
, aXclTokArr
, rStrm
);
1817 void XclImpControlHelper::ReadRangeList( ScRangeList
& rScRanges
, XclImpStream
& rStrm
, bool bWithBoundSize
)
1819 if( bWithBoundSize
)
1825 rStrm
.PushPosition();
1826 ReadRangeList( rScRanges
, rStrm
);
1827 rStrm
.PopPosition();
1828 rStrm
.Ignore( nSize
);
1833 ReadRangeList( rScRanges
, rStrm
);
1837 // ----------------------------------------------------------------------------
1839 XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot
& rRoot
) :
1840 XclImpTextObj( rRoot
),
1841 XclImpControlHelper( rRoot
, EXC_CTRL_BINDPOSITION
)
1843 SetSimpleMacro( false );
1844 SetCustomDffObj( true );
1849 void lclExtractColor( sal_uInt8
& rnColorIdx
, const DffPropSet
& rDffPropSet
, sal_uInt32 nPropId
)
1851 if( rDffPropSet
.IsProperty( nPropId
) )
1853 sal_uInt32 nColor
= rDffPropSet
.GetPropertyValue( nPropId
);
1854 if( (nColor
& 0xFF000000) == 0x08000000 )
1855 rnColorIdx
= ::extract_value
< sal_uInt8
>( nColor
, 0, 8 );
1861 void XclImpTbxObjBase::SetDffProperties( const DffPropSet
& rDffPropSet
)
1863 maFillData
.mnPattern
= rDffPropSet
.GetPropertyBool( DFF_Prop_fFilled
) ? EXC_PATT_SOLID
: EXC_PATT_NONE
;
1864 lclExtractColor( maFillData
.mnBackColorIdx
, rDffPropSet
, DFF_Prop_fillBackColor
);
1865 lclExtractColor( maFillData
.mnPattColorIdx
, rDffPropSet
, DFF_Prop_fillColor
);
1866 ::set_flag( maFillData
.mnAuto
, EXC_OBJ_LINE_AUTO
, false );
1868 maLineData
.mnStyle
= rDffPropSet
.GetPropertyBool( DFF_Prop_fLine
) ? EXC_OBJ_LINE_SOLID
: EXC_OBJ_LINE_NONE
;
1869 lclExtractColor( maLineData
.mnColorIdx
, rDffPropSet
, DFF_Prop_lineColor
);
1870 ::set_flag( maLineData
.mnAuto
, EXC_OBJ_FILL_AUTO
, false );
1873 bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor
& rDescriptor
) const
1875 return XclControlHelper::FillMacroDescriptor( rDescriptor
, DoGetEventType(), GetMacroName(), GetDocShell() );
1878 void XclImpTbxObjBase::ConvertFont( ScfPropertySet
& rPropSet
) const
1880 if( maTextData
.mxString
.is() )
1882 const XclFormatRunVec
& rFormatRuns
= maTextData
.mxString
->GetFormats();
1883 if( rFormatRuns
.empty() )
1884 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet
);
1886 GetFontBuffer().WriteFontProperties( rPropSet
, EXC_FONTPROPSET_CONTROL
, rFormatRuns
.front().mnFontIdx
);
1890 void XclImpTbxObjBase::ConvertLabel( ScfPropertySet
& rPropSet
) const
1892 if( maTextData
.mxString
.is() )
1894 String aLabel
= maTextData
.mxString
->GetText();
1895 if( maTextData
.maData
.mnShortcut
> 0 )
1897 xub_StrLen nPos
= aLabel
.Search( static_cast< sal_Unicode
>( maTextData
.maData
.mnShortcut
) );
1898 if( nPos
!= STRING_NOTFOUND
)
1899 aLabel
.Insert( '~', nPos
);
1901 rPropSet
.SetStringProperty( CREATE_OUSTRING( "Label" ), aLabel
);
1903 ConvertFont( rPropSet
);
1906 SdrObject
* XclImpTbxObjBase::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
1908 SdrObjectPtr
xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect
) );
1909 rProgress
.Progress();
1910 return xSdrObj
.release();
1913 void XclImpTbxObjBase::DoProcessSdrObj( SdrObject
& /*rSdrObj*/ ) const
1915 // do not call DoProcessSdrObj() from base class (to skip text processing)
1916 ProcessControl( *this );
1919 // ----------------------------------------------------------------------------
1921 XclImpButtonObj::XclImpButtonObj( const XclImpRoot
& rRoot
) :
1922 XclImpTbxObjBase( rRoot
)
1926 void XclImpButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
1928 // label and text formatting
1929 ConvertLabel( rPropSet
);
1931 /* Horizontal text alignment. For unknown reason, the property type is a
1932 simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
1933 sal_Int16 nHorAlign
= 1;
1934 switch( maTextData
.maData
.GetHorAlign() )
1936 case EXC_OBJ_HOR_LEFT
: nHorAlign
= 0; break;
1937 case EXC_OBJ_HOR_CENTER
: nHorAlign
= 1; break;
1938 case EXC_OBJ_HOR_RIGHT
: nHorAlign
= 2; break;
1940 rPropSet
.SetProperty( CREATE_OUSTRING( "Align" ), nHorAlign
);
1942 // vertical text alignment
1943 namespace csss
= ::com::sun::star::style
;
1944 csss::VerticalAlignment eVerAlign
= csss::VerticalAlignment_MIDDLE
;
1945 switch( maTextData
.maData
.GetVerAlign() )
1947 case EXC_OBJ_VER_TOP
: eVerAlign
= csss::VerticalAlignment_TOP
; break;
1948 case EXC_OBJ_VER_CENTER
: eVerAlign
= csss::VerticalAlignment_MIDDLE
; break;
1949 case EXC_OBJ_VER_BOTTOM
: eVerAlign
= csss::VerticalAlignment_BOTTOM
; break;
1951 rPropSet
.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), eVerAlign
);
1953 // always wrap text automatically
1954 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
1957 bool bDefButton
= ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_DEFAULT
);
1958 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "DefaultButton" ), bDefButton
);
1960 // button type (flags cannot be combined in OOo)
1961 namespace cssa
= ::com::sun::star::awt
;
1962 cssa::PushButtonType eButtonType
= cssa::PushButtonType_STANDARD
;
1963 if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_CLOSE
) )
1964 eButtonType
= cssa::PushButtonType_OK
;
1965 else if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_CANCEL
) )
1966 eButtonType
= cssa::PushButtonType_CANCEL
;
1967 else if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_HELP
) )
1968 eButtonType
= cssa::PushButtonType_HELP
;
1969 // property type is short, not enum
1970 rPropSet
.SetProperty( CREATE_OUSTRING( "PushButtonType" ), sal_Int16( eButtonType
) );
1973 OUString
XclImpButtonObj::DoGetServiceName() const
1975 return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" );
1978 XclTbxEventType
XclImpButtonObj::DoGetEventType() const
1980 return EXC_TBX_EVENT_ACTION
;
1983 // ----------------------------------------------------------------------------
1985 XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot
& rRoot
) :
1986 XclImpTbxObjBase( rRoot
),
1987 mnState( EXC_OBJ_CHECKBOX_UNCHECKED
),
1988 mnCheckBoxFlags( 0 )
1992 void XclImpCheckBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
1994 ReadFrameData( rStrm
);
1996 rStrm
>> maTextData
.maData
.mnFlags
;
1998 ReadName5( rStrm
, nNameLen
);
1999 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2000 ReadCellLinkFormula( rStrm
, true );
2001 rStrm
>> maTextData
.maData
.mnTextLen
;
2002 maTextData
.ReadByteString( rStrm
);
2003 rStrm
>> mnState
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnCheckBoxFlags
;
2006 void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2010 case EXC_ID_OBJCBLS
:
2011 // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
2014 rStrm
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnCheckBoxFlags
;
2016 case EXC_ID_OBJCBLSFMLA
:
2017 ReadCellLinkFormula( rStrm
, false );
2020 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2024 void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2026 // label and text formatting
2027 ConvertLabel( rPropSet
);
2030 bool bSupportsTristate
= GetObjType() == EXC_OBJTYPE_CHECKBOX
;
2031 sal_Int16 nApiState
= 0;
2034 case EXC_OBJ_CHECKBOX_UNCHECKED
: nApiState
= 0; break;
2035 case EXC_OBJ_CHECKBOX_CHECKED
: nApiState
= 1; break;
2036 case EXC_OBJ_CHECKBOX_TRISTATE
: nApiState
= bSupportsTristate
? 2 : 1; break;
2038 if( bSupportsTristate
)
2039 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "TriState" ), nApiState
== 2 );
2040 rPropSet
.SetProperty( CREATE_OUSTRING( "DefaultState" ), nApiState
);
2043 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
2044 sal_Int16 nEffect
= ::get_flagvalue( mnCheckBoxFlags
, EXC_OBJ_CHECKBOX_FLAT
, AwtVisualEffect::FLAT
, AwtVisualEffect::LOOK3D
);
2045 rPropSet
.SetProperty( CREATE_OUSTRING( "VisualEffect" ), nEffect
);
2047 // do not wrap text automatically
2048 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), false );
2050 // #i40279# always centered vertically
2051 namespace csss
= ::com::sun::star::style
;
2052 rPropSet
.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_MIDDLE
);
2055 if( maFillData
.IsFilled() )
2057 sal_Int32 nColor
= static_cast< sal_Int32
>( GetSolidFillColor( maFillData
).GetColor() );
2058 rPropSet
.SetProperty( CREATE_OUSTRING( "BackgroundColor" ), nColor
);
2062 OUString
XclImpCheckBoxObj::DoGetServiceName() const
2064 return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" );
2067 XclTbxEventType
XclImpCheckBoxObj::DoGetEventType() const
2069 return EXC_TBX_EVENT_ACTION
;
2072 // ----------------------------------------------------------------------------
2074 XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot
& rRoot
) :
2075 XclImpCheckBoxObj( rRoot
),
2081 void XclImpOptionButtonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2083 ReadFrameData( rStrm
);
2085 rStrm
>> maTextData
.maData
.mnFlags
;
2087 ReadName5( rStrm
, nNameLen
);
2088 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2089 ReadCellLinkFormula( rStrm
, true );
2090 rStrm
>> maTextData
.maData
.mnTextLen
;
2091 maTextData
.ReadByteString( rStrm
);
2092 rStrm
>> mnState
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
;
2093 rStrm
>> mnCheckBoxFlags
>> mnNextInGroup
>> mnFirstInGroup
;
2096 void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2100 case EXC_ID_OBJRBODATA
:
2101 rStrm
>> mnNextInGroup
>> mnFirstInGroup
;
2104 XclImpCheckBoxObj::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2108 void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2110 XclImpCheckBoxObj::DoProcessControl( rPropSet
);
2112 XclImpOptionButtonObj
* pTbxObj
= dynamic_cast< XclImpOptionButtonObj
* >( GetObjectManager().FindDrawObj( XclObjId( GetScTab(), mnNextInGroup
) ).get() );
2113 if ( ( pTbxObj
&& pTbxObj
->mnFirstInGroup
) )
2115 // Group has terminated
2116 // traverse each RadioButton in group and
2117 // a) apply the groupname
2118 // b) propagate the linked cell from the lead radiobutton
2119 // c) apply the correct Ref value
2120 XclImpOptionButtonObj
* pLeader
= pTbxObj
;
2122 sal_Int32 nRefVal
= 1;
2123 OSL_TRACE( "0x%x start group ", pLeader
->GetObjId().mnObjId
);
2127 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( pTbxObj
->mxShape
);
2128 if ( xCtrlModel
.is() )
2130 ScfPropertySet
aProps( xCtrlModel
);
2131 rtl::OUString sGroupName
= rtl::OUString::valueOf( static_cast< sal_Int32
>( pLeader
->GetDffShapeId() ) );
2133 aProps
.SetStringProperty( CREATE_OUSTRING( "GroupName" ), sGroupName
);
2134 aProps
.SetStringProperty( CREATE_OUSTRING( "RefValue" ), rtl::OUString::valueOf( nRefVal
++ ) );
2135 if ( pLeader
->HasCellLink() && !pTbxObj
->HasCellLink() )
2137 // propagate cell link info
2138 pTbxObj
->mxCellLink
.reset( new ScAddress( *pLeader
->mxCellLink
.get() ) );
2139 pTbxObj
->ApplySheetLinkProps();
2141 pTbxObj
= dynamic_cast< XclImpOptionButtonObj
* >( GetObjectManager().FindDrawObj( XclObjId( GetScTab(), pTbxObj
->mnNextInGroup
) ).get() );
2145 } while ( pTbxObj
&& !( pTbxObj
->mnFirstInGroup
== 1 ) );
2149 // not the leader? try and find it
2153 OUString
XclImpOptionButtonObj::DoGetServiceName() const
2155 return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
2158 XclTbxEventType
XclImpOptionButtonObj::DoGetEventType() const
2160 return EXC_TBX_EVENT_ACTION
;
2163 // ----------------------------------------------------------------------------
2165 XclImpLabelObj::XclImpLabelObj( const XclImpRoot
& rRoot
) :
2166 XclImpTbxObjBase( rRoot
)
2170 void XclImpLabelObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2172 // label and text formatting
2173 ConvertLabel( rPropSet
);
2175 // text alignment (always top/left aligned)
2176 rPropSet
.SetProperty( CREATE_OUSTRING( "Align" ), sal_Int16( 0 ) );
2177 namespace csss
= ::com::sun::star::style
;
2178 rPropSet
.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_TOP
);
2180 // always wrap text automatically
2181 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
2184 OUString
XclImpLabelObj::DoGetServiceName() const
2186 return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" );
2189 XclTbxEventType
XclImpLabelObj::DoGetEventType() const
2191 return EXC_TBX_EVENT_MOUSE
;
2194 // ----------------------------------------------------------------------------
2196 XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot
& rRoot
) :
2197 XclImpTbxObjBase( rRoot
),
2198 mnGroupBoxFlags( 0 )
2202 void XclImpGroupBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2204 ReadFrameData( rStrm
);
2206 rStrm
>> maTextData
.maData
.mnFlags
;
2208 ReadName5( rStrm
, nNameLen
);
2209 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2210 rStrm
>> maTextData
.maData
.mnTextLen
;
2211 maTextData
.ReadByteString( rStrm
);
2212 rStrm
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnGroupBoxFlags
;
2215 void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2219 case EXC_ID_OBJGBODATA
:
2220 rStrm
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnGroupBoxFlags
;
2223 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2227 void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2229 // label and text formatting
2230 ConvertLabel( rPropSet
);
2233 OUString
XclImpGroupBoxObj::DoGetServiceName() const
2235 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2238 XclTbxEventType
XclImpGroupBoxObj::DoGetEventType() const
2240 return EXC_TBX_EVENT_MOUSE
;
2243 // ----------------------------------------------------------------------------
2245 XclImpDialogObj::XclImpDialogObj( const XclImpRoot
& rRoot
) :
2246 XclImpTbxObjBase( rRoot
)
2250 void XclImpDialogObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2252 // label and text formatting
2253 ConvertLabel( rPropSet
);
2256 OUString
XclImpDialogObj::DoGetServiceName() const
2258 // dialog frame faked by a groupbox
2259 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2262 XclTbxEventType
XclImpDialogObj::DoGetEventType() const
2264 return EXC_TBX_EVENT_MOUSE
;
2267 // ----------------------------------------------------------------------------
2269 XclImpEditObj::XclImpEditObj( const XclImpRoot
& rRoot
) :
2270 XclImpTbxObjBase( rRoot
),
2271 mnContentType( EXC_OBJ_EDIT_TEXT
),
2278 bool XclImpEditObj::IsNumeric() const
2280 return (mnContentType
== EXC_OBJ_EDIT_INTEGER
) || (mnContentType
== EXC_OBJ_EDIT_DOUBLE
);
2283 void XclImpEditObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2285 ReadFrameData( rStrm
);
2287 rStrm
>> maTextData
.maData
.mnFlags
;
2289 ReadName5( rStrm
, nNameLen
);
2290 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2291 rStrm
>> maTextData
.maData
.mnTextLen
;
2292 maTextData
.ReadByteString( rStrm
);
2293 rStrm
>> mnContentType
>> mnMultiLine
>> mnScrollBar
>> mnListBoxObjId
;
2296 void XclImpEditObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2300 case EXC_ID_OBJEDODATA
:
2301 rStrm
>> mnContentType
>> mnMultiLine
>> mnScrollBar
>> mnListBoxObjId
;
2304 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2308 void XclImpEditObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2310 if( maTextData
.mxString
.is() )
2312 OUString aText
= maTextData
.mxString
->GetText();
2315 // TODO: OUString::toDouble() does not handle local decimal separator
2316 rPropSet
.SetProperty( CREATE_OUSTRING( "DefaultValue" ), aText
.toDouble() );
2317 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "Spin" ), mnScrollBar
!= 0 );
2321 rPropSet
.SetProperty( CREATE_OUSTRING( "DefaultText" ), aText
);
2322 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), mnMultiLine
!= 0 );
2323 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "VScroll" ), mnScrollBar
!= 0 );
2326 ConvertFont( rPropSet
);
2329 OUString
XclImpEditObj::DoGetServiceName() const
2331 return IsNumeric() ?
2332 CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ) :
2333 CREATE_OUSTRING( "com.sun.star.form.component.TextField" );
2336 XclTbxEventType
XclImpEditObj::DoGetEventType() const
2338 return EXC_TBX_EVENT_TEXT
;
2341 // ----------------------------------------------------------------------------
2343 XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot
& rRoot
) :
2344 XclImpTbxObjBase( rRoot
),
2356 void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream
& rStrm
)
2359 rStrm
>> mnValue
>> mnMin
>> mnMax
>> mnStep
>> mnPageStep
>> mnOrient
>> mnThumbWidth
>> mnScrollFlags
;
2362 void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2369 case EXC_ID_OBJSBSFMLA
:
2370 ReadCellLinkFormula( rStrm
, false );
2373 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2377 // ----------------------------------------------------------------------------
2379 XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot
& rRoot
) :
2380 XclImpTbxObjScrollableBase( rRoot
)
2384 void XclImpSpinButtonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2386 ReadFrameData( rStrm
);
2388 ReadName5( rStrm
, nNameLen
);
2389 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2390 ReadCellLinkFormula( rStrm
, true );
2393 void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2395 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2396 rPropSet
.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE
);
2397 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "DefaultSpinValue" ), mnValue
);
2398 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "SpinValueMin" ), mnMin
);
2399 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "SpinValueMax" ), mnMax
);
2400 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "SpinIncrement" ), mnStep
);
2402 // Excel spin buttons always vertical
2403 rPropSet
.SetProperty( CREATE_OUSTRING( "Orientation" ), ::com::sun::star::awt::ScrollBarOrientation::VERTICAL
);
2406 OUString
XclImpSpinButtonObj::DoGetServiceName() const
2408 return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
2411 XclTbxEventType
XclImpSpinButtonObj::DoGetEventType() const
2413 return EXC_TBX_EVENT_VALUE
;
2416 // ----------------------------------------------------------------------------
2418 XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot
& rRoot
) :
2419 XclImpTbxObjScrollableBase( rRoot
)
2423 void XclImpScrollBarObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2425 ReadFrameData( rStrm
);
2427 ReadName5( rStrm
, nNameLen
);
2428 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2429 ReadCellLinkFormula( rStrm
, true );
2432 void XclImpScrollBarObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2434 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2435 rPropSet
.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE
);
2436 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "DefaultScrollValue" ), mnValue
);
2437 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "ScrollValueMin" ), mnMin
);
2438 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "ScrollValueMax" ), mnMax
);
2439 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "LineIncrement" ), mnStep
);
2440 rPropSet
.SetProperty
< sal_Int32
>( CREATE_OUSTRING( "BlockIncrement" ), mnPageStep
);
2441 rPropSet
.SetProperty( CREATE_OUSTRING( "VisibleSize" ), ::std::min
< sal_Int32
>( mnPageStep
, 1 ) );
2443 namespace AwtScrollOrient
= ::com::sun::star::awt::ScrollBarOrientation
;
2444 sal_Int32 nApiOrient
= ::get_flagvalue( mnOrient
, EXC_OBJ_SCROLLBAR_HOR
, AwtScrollOrient::HORIZONTAL
, AwtScrollOrient::VERTICAL
);
2445 rPropSet
.SetProperty( CREATE_OUSTRING( "Orientation" ), nApiOrient
);
2448 OUString
XclImpScrollBarObj::DoGetServiceName() const
2450 return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
2453 XclTbxEventType
XclImpScrollBarObj::DoGetEventType() const
2455 return EXC_TBX_EVENT_VALUE
;
2458 // ----------------------------------------------------------------------------
2460 XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot
& rRoot
) :
2461 XclImpTbxObjScrollableBase( rRoot
),
2466 mbHasDefFontIdx( false )
2470 void XclImpTbxObjListBase::ReadLbsData( XclImpStream
& rStrm
)
2472 ReadSourceRangeFormula( rStrm
, true );
2473 rStrm
>> mnEntryCount
>> mnSelEntry
>> mnListFlags
>> mnEditObjId
;
2476 void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet
& rPropSet
) const
2479 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
2480 sal_Int16 nApiBorder
= ::get_flagvalue( mnListFlags
, EXC_OBJ_LISTBOX_FLAT
, AwtVisualEffect::FLAT
, AwtVisualEffect::LOOK3D
);
2481 rPropSet
.SetProperty( CREATE_OUSTRING( "Border" ), nApiBorder
);
2484 if( mbHasDefFontIdx
)
2485 GetFontBuffer().WriteFontProperties( rPropSet
, EXC_FONTPROPSET_CONTROL
, maTextData
.maData
.mnDefFontIdx
);
2487 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet
);
2490 // ----------------------------------------------------------------------------
2492 XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot
& rRoot
) :
2493 XclImpTbxObjListBase( rRoot
)
2497 void XclImpListBoxObj::ReadFullLbsData( XclImpStream
& rStrm
, sal_Size nRecLeft
)
2499 sal_Size nRecEnd
= rStrm
.GetRecPos() + nRecLeft
;
2500 ReadLbsData( rStrm
);
2501 DBG_ASSERT( (rStrm
.GetRecPos() == nRecEnd
) || (rStrm
.GetRecPos() + mnEntryCount
== nRecEnd
),
2502 "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
2503 while( rStrm
.IsValid() && (rStrm
.GetRecPos() < nRecEnd
) )
2504 maSelection
.push_back( rStrm
.ReaduInt8() );
2507 void XclImpListBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2509 ReadFrameData( rStrm
);
2512 rStrm
>> maTextData
.maData
.mnDefFontIdx
;
2514 ReadName5( rStrm
, nNameLen
);
2515 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2516 ReadCellLinkFormula( rStrm
, true );
2517 ReadFullLbsData( rStrm
, rStrm
.GetRecLeft() );
2518 mbHasDefFontIdx
= true;
2521 void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2525 case EXC_ID_OBJLBSDATA
:
2526 ReadFullLbsData( rStrm
, nSubRecSize
);
2529 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2533 void XclImpListBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2535 // listbox formatting
2536 SetBoxFormatting( rPropSet
);
2539 sal_uInt8 nSelType
= ::extract_value
< sal_uInt8
>( mnListFlags
, 4, 2 );
2540 bool bMultiSel
= nSelType
!= EXC_OBJ_LISTBOX_SINGLE
;
2541 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "MultiSelection" ), bMultiSel
);
2543 // selection (do not set, if listbox is linked to a cell)
2544 if( !HasCellLink() )
2546 ScfInt16Vec aSelVec
;
2548 // multi selection: API expects sequence of list entry indexes
2550 for( ScfUInt8Vec::const_iterator aBeg
= maSelection
.begin(), aIt
= aBeg
, aEnd
= maSelection
.end(); aIt
!= aEnd
; ++aIt
)
2552 aSelVec
.push_back( static_cast< sal_Int16
>( aIt
- aBeg
) );
2553 // single selection: mnSelEntry is one-based, API expects zero-based
2554 else if( mnSelEntry
> 0 )
2555 aSelVec
.push_back( static_cast< sal_Int16
>( mnSelEntry
- 1 ) );
2557 if( !aSelVec
.empty() )
2559 Sequence
< sal_Int16
> aSelSeq( &aSelVec
.front(), static_cast< sal_Int32
>( aSelVec
.size() ) );
2560 rPropSet
.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq
);
2565 OUString
XclImpListBoxObj::DoGetServiceName() const
2567 return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2570 XclTbxEventType
XclImpListBoxObj::DoGetEventType() const
2572 return EXC_TBX_EVENT_CHANGE
;
2575 // ----------------------------------------------------------------------------
2577 XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot
& rRoot
) :
2578 XclImpTbxObjListBase( rRoot
),
2583 mnDropDownFlags( 0 ),
2589 sal_uInt16
XclImpDropDownObj::GetDropDownType() const
2591 return ::extract_value
< sal_uInt8
>( mnDropDownFlags
, 0, 2 );
2594 void XclImpDropDownObj::ReadFullLbsData( XclImpStream
& rStrm
)
2596 ReadLbsData( rStrm
);
2597 rStrm
>> mnDropDownFlags
>> mnLineCount
>> mnMinWidth
>> maTextData
.maData
.mnTextLen
;
2598 maTextData
.ReadByteString( rStrm
);
2599 // dropdowns of auto-filters have 'simple' style, they don't have a text area
2600 if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE
)
2601 SetProcessSdrObj( false );
2604 void XclImpDropDownObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2606 ReadFrameData( rStrm
);
2609 rStrm
>> maTextData
.maData
.mnDefFontIdx
;
2611 rStrm
>> mnLeft
>> mnTop
>> mnRight
>> mnBottom
;
2613 ReadName5( rStrm
, nNameLen
);
2614 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2615 ReadCellLinkFormula( rStrm
, true );
2616 ReadFullLbsData( rStrm
);
2617 mbHasDefFontIdx
= true;
2620 void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2624 case EXC_ID_OBJLBSDATA
:
2625 ReadFullLbsData( rStrm
);
2628 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2632 void XclImpDropDownObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2634 // dropdown listbox formatting
2635 SetBoxFormatting( rPropSet
);
2636 // enable dropdown button
2637 rPropSet
.SetBoolProperty( CREATE_OUSTRING( "Dropdown" ), true );
2638 // dropdown line count
2639 rPropSet
.SetProperty( CREATE_OUSTRING( "LineCount" ), mnLineCount
);
2641 if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
)
2643 // text of editable combobox
2644 if( maTextData
.mxString
.is() )
2645 rPropSet
.SetStringProperty( CREATE_OUSTRING( "DefaultText" ), maTextData
.mxString
->GetText() );
2649 // selection (do not set, if dropdown is linked to a cell)
2650 if( !HasCellLink() && (mnSelEntry
> 0) )
2652 Sequence
< sal_Int16
> aSelSeq( 1 );
2653 aSelSeq
[ 0 ] = mnSelEntry
- 1;
2654 rPropSet
.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq
);
2659 OUString
XclImpDropDownObj::DoGetServiceName() const
2661 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
) ?
2662 CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ) :
2663 CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2666 XclTbxEventType
XclImpDropDownObj::DoGetEventType() const
2668 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
) ? EXC_TBX_EVENT_TEXT
: EXC_TBX_EVENT_CHANGE
;
2671 // ----------------------------------------------------------------------------
2673 XclImpPictureObj::XclImpPictureObj( const XclImpRoot
& rRoot
) :
2674 XclImpRectObj( rRoot
),
2675 XclImpControlHelper( rRoot
, EXC_CTRL_BINDCONTENT
),
2678 mnCtlsStrmSize( 0 ),
2679 mbEmbedded( false ),
2683 mbUseCtlsStrm( false )
2686 SetSimpleMacro( false );
2687 SetCustomDffObj( true );
2690 String
XclImpPictureObj::GetOleStorageName() const
2693 if( (mbEmbedded
|| mbLinked
) && !mbControl
&& (mnStorageId
> 0) )
2695 aStrgName
= mbEmbedded
? EXC_STORAGE_OLE_EMBEDDED
: EXC_STORAGE_OLE_LINKED
;
2696 static const sal_Char spcHexChars
[] = "0123456789ABCDEF";
2697 for( sal_uInt8 nIndex
= 32; nIndex
> 0; nIndex
-= 4 )
2698 aStrgName
.Append( sal_Unicode( spcHexChars
[ ::extract_value
< sal_uInt8
>( mnStorageId
, nIndex
- 4, 4 ) ] ) );
2703 void XclImpPictureObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
2705 sal_uInt16 nLinkSize
;
2706 ReadFrameData( rStrm
);
2710 ReadFlags3( rStrm
);
2711 ReadMacro3( rStrm
, nMacroSize
);
2712 ReadPictFmla( rStrm
, nLinkSize
);
2714 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2715 maGraphic
= XclImpObjectManager::ReadImgData( rStrm
);
2718 void XclImpPictureObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
2720 sal_uInt16 nLinkSize
;
2721 ReadFrameData( rStrm
);
2725 ReadFlags3( rStrm
);
2726 ReadMacro4( rStrm
, nMacroSize
);
2727 ReadPictFmla( rStrm
, nLinkSize
);
2729 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2730 maGraphic
= XclImpObjectManager::ReadImgData( rStrm
);
2733 void XclImpPictureObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
2735 sal_uInt16 nLinkSize
;
2736 ReadFrameData( rStrm
);
2740 ReadFlags3( rStrm
);
2742 ReadName5( rStrm
, nNameLen
);
2743 ReadMacro5( rStrm
, nMacroSize
);
2744 ReadPictFmla( rStrm
, nLinkSize
);
2746 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2748 // page background is stored as hidden picture with name "__BkgndObj"
2749 if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) )
2750 GetPageSettings().ReadImgData( rStrm
);
2752 maGraphic
= XclImpObjectManager::ReadImgData( rStrm
);
2756 void XclImpPictureObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2760 case EXC_ID_OBJFLAGS
:
2761 ReadFlags8( rStrm
);
2763 case EXC_ID_OBJPICTFMLA
:
2764 ReadPictFmla( rStrm
, rStrm
.ReaduInt16() );
2767 XclImpDrawObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2771 SdrObject
* XclImpPictureObj::DoCreateSdrObj( const Rectangle
& rAnchorRect
, ScfProgressBar
& rProgress
) const
2773 // try to create an OLE object or form control
2774 SdrObjectPtr
xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect
) );
2776 // no OLE - create a plain picture from IMGDATA record data
2777 if( !xSdrObj
&& (maGraphic
.GetType() != GRAPHIC_NONE
) )
2779 xSdrObj
.reset( new SdrGrafObj( maGraphic
, rAnchorRect
) );
2780 ConvertRectStyle( *xSdrObj
);
2783 rProgress
.Progress();
2784 return xSdrObj
.release();
2787 void XclImpPictureObj::DoProcessSdrObj( SdrObject
& rSdrObj
) const
2789 if( IsOcxControl() )
2791 // do not call XclImpRectObj::DoProcessSdrObj(), it would trace missing "printable" feature
2792 ProcessControl( *this );
2794 else if( mbEmbedded
|| mbLinked
)
2796 // trace missing "printable" feature
2797 XclImpRectObj::DoProcessSdrObj( rSdrObj
);
2799 SfxObjectShell
* pDocShell
= GetDocShell();
2800 SdrOle2Obj
* pOleSdrObj
= dynamic_cast< SdrOle2Obj
* >( &rSdrObj
);
2801 if( pOleSdrObj
&& pDocShell
)
2803 comphelper::EmbeddedObjectContainer
& rEmbObjCont
= pDocShell
->GetEmbeddedObjectContainer();
2804 Reference
< XEmbeddedObject
> xEmbObj
= pOleSdrObj
->GetObjRef();
2805 OUString
aOldName( pOleSdrObj
->GetPersistName() );
2807 /* The object persistence should be already in the storage, but
2808 the object still might not be inserted into the container. */
2809 if( rEmbObjCont
.HasEmbeddedObject( aOldName
) )
2811 if( !rEmbObjCont
.HasEmbeddedObject( xEmbObj
) )
2812 // filter code is allowed to call the following method
2813 rEmbObjCont
.AddEmbeddedObject( xEmbObj
, aOldName
);
2817 /* If the object is still not in container it must be inserted
2818 there, the name must be generated in this case. */
2820 rEmbObjCont
.InsertEmbeddedObject( xEmbObj
, aNewName
);
2821 if( aOldName
!= aNewName
)
2822 // #95381# SetPersistName, not SetName
2823 pOleSdrObj
->SetPersistName( aNewName
);
2829 void XclImpPictureObj::ReadFlags3( XclImpStream
& rStrm
)
2833 mbSymbol
= ::get_flag( nFlags
, EXC_OBJ_PIC_SYMBOL
);
2836 void XclImpPictureObj::ReadFlags8( XclImpStream
& rStrm
)
2840 mbSymbol
= ::get_flag( nFlags
, EXC_OBJ_PIC_SYMBOL
);
2841 mbControl
= ::get_flag( nFlags
, EXC_OBJ_PIC_CONTROL
);
2842 mbUseCtlsStrm
= ::get_flag( nFlags
, EXC_OBJ_PIC_CTLSSTREAM
);
2843 DBG_ASSERT( mbControl
|| !mbUseCtlsStrm
, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
2844 SetProcessSdrObj( mbControl
|| !mbUseCtlsStrm
);
2847 void XclImpPictureObj::ReadPictFmla( XclImpStream
& rStrm
, sal_uInt16 nLinkSize
)
2849 sal_Size nLinkEnd
= rStrm
.GetRecPos() + nLinkSize
;
2850 if( nLinkSize
>= 6 )
2852 sal_uInt16 nFmlaSize
;
2854 DBG_ASSERT( nFmlaSize
> 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
2855 // BIFF3/BIFF4 do not support storages, nothing to do here
2856 if( (nFmlaSize
> 0) && (GetBiff() >= EXC_BIFF5
) )
2862 // different processing for linked vs. embedded OLE objects
2863 if( nToken
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
) )
2871 sal_uInt16 nNameIdx
;
2876 const ExtName
* pExtName
= GetOldRoot().pExtNameBuff
->GetNameByIndex( nRefIdx
, nNameIdx
);
2877 if( pExtName
&& pExtName
->IsOLE() )
2878 mnStorageId
= pExtName
->nStorageId
;
2883 sal_uInt16 nXti
, nExtName
;
2884 rStrm
>> nXti
>> nExtName
;
2885 const XclImpExtName
* pExtName
= GetLinkManager().GetExternName( nXti
, nExtName
);
2886 if( pExtName
&& (pExtName
->GetType() == xlExtOLE
) )
2887 mnStorageId
= pExtName
->GetStorageId();
2894 else if( nToken
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL
, EXC_TOKCLASS_NONE
) )
2897 DBG_ASSERT( nFmlaSize
== 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
2898 rStrm
.Ignore( nFmlaSize
- 1 ); // token ID already read
2900 rStrm
.Ignore( 1 ); // padding byte
2902 // a class name may follow inside the picture link
2903 if( rStrm
.GetRecPos() + 2 <= nLinkEnd
)
2908 maClassName
= (GetBiff() == EXC_BIFF8
) ? rStrm
.ReadUniString( nLen
) : rStrm
.ReadRawByteString( nLen
);
2911 // else: ignore other formulas, e.g. pictures linked to cell ranges
2915 // seek behind picture link data
2916 rStrm
.Seek( nLinkEnd
);
2918 // read additional data for embedded OLE objects following the picture link
2919 if( IsOcxControl() )
2921 // #i26521# form controls to be ignored
2922 if( maClassName
.EqualsAscii( "Forms.HTML:Hidden.1" ) )
2924 SetProcessSdrObj( false );
2928 if( rStrm
.GetRecLeft() <= 8 ) return;
2930 // position and size of control data in 'Ctls' stream
2931 mnCtlsStrmPos
= static_cast< sal_Size
>( rStrm
.ReaduInt32() );
2932 mnCtlsStrmSize
= static_cast< sal_Size
>( rStrm
.ReaduInt32() );
2934 if( rStrm
.GetRecLeft() <= 8 ) return;
2936 // additional string (16-bit characters), e.g. for progress bar control
2937 sal_uInt32 nAddStrSize
;
2938 rStrm
>> nAddStrSize
;
2939 DBG_ASSERT( rStrm
.GetRecLeft() >= nAddStrSize
+ 4, "XclImpPictureObj::ReadPictFmla - missing data" );
2940 if( rStrm
.GetRecLeft() >= nAddStrSize
+ 4 )
2942 rStrm
.Ignore( nAddStrSize
);
2943 // cell link and source range
2944 ReadCellLinkFormula( rStrm
, true );
2945 ReadSourceRangeFormula( rStrm
, true );
2948 else if( mbEmbedded
&& (rStrm
.GetRecLeft() >= 4) )
2950 rStrm
>> mnStorageId
;
2954 // DFF stream conversion ======================================================
2956 //UNUSED2009-05 void XclImpSolverContainer::ReadSolverContainer( SvStream& rDffStrm )
2958 //UNUSED2009-05 rDffStrm >> *this;
2961 void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject
& rSdrObj
, sal_uInt32 nDffShapeId
, sal_uInt32 nDffFlags
)
2963 if( nDffShapeId
> 0 )
2965 maSdrInfoMap
[ nDffShapeId
].Set( &rSdrObj
, nDffFlags
);
2966 maSdrObjMap
[ &rSdrObj
] = nDffShapeId
;
2970 void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject
& rSdrObj
)
2972 // remove info of passed object from the maps
2973 XclImpSdrObjMap::iterator aIt
= maSdrObjMap
.find( &rSdrObj
);
2974 if( aIt
!= maSdrObjMap
.end() )
2976 maSdrInfoMap
.erase( aIt
->second
);
2977 maSdrObjMap
.erase( aIt
);
2980 // remove info of all child objects of a group object
2981 if( SdrObjGroup
* pGroupObj
= dynamic_cast< SdrObjGroup
* >( &rSdrObj
) )
2983 if( SdrObjList
* pSubList
= pGroupObj
->GetSubList() )
2985 // iterate flat over the list because this function already works recursively
2986 SdrObjListIter
aObjIt( *pSubList
, IM_FLAT
);
2987 for( SdrObject
* pChildObj
= aObjIt
.Next(); pChildObj
; pChildObj
= aObjIt
.Next() )
2988 RemoveSdrObjectInfo( *pChildObj
);
2993 void XclImpSolverContainer::UpdateConnectorRules()
2995 for( SvxMSDffConnectorRule
* pRule
= GetFirstRule(); pRule
; pRule
= GetNextRule() )
2997 UpdateConnection( pRule
->nShapeA
, pRule
->pAObj
, &pRule
->nSpFlagsA
);
2998 UpdateConnection( pRule
->nShapeB
, pRule
->pBObj
, &pRule
->nSpFlagsB
);
2999 UpdateConnection( pRule
->nShapeC
, pRule
->pCObj
);
3003 void XclImpSolverContainer::RemoveConnectorRules()
3005 // base class from SVX uses plain untyped tools/List
3006 for( SvxMSDffConnectorRule
* pRule
= GetFirstRule(); pRule
; pRule
= GetNextRule() )
3010 maSdrInfoMap
.clear();
3011 maSdrObjMap
.clear();
3014 SvxMSDffConnectorRule
* XclImpSolverContainer::GetFirstRule()
3016 return static_cast< SvxMSDffConnectorRule
* >( aCList
.First() );
3019 SvxMSDffConnectorRule
* XclImpSolverContainer::GetNextRule()
3021 return static_cast< SvxMSDffConnectorRule
* >( aCList
.Next() );
3024 void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId
, SdrObject
*& rpSdrObj
, sal_uInt32
* pnDffFlags
)
3026 XclImpSdrInfoMap::const_iterator aIt
= maSdrInfoMap
.find( nDffShapeId
);
3027 if( aIt
!= maSdrInfoMap
.end() )
3029 rpSdrObj
= aIt
->second
.mpSdrObj
;
3031 *pnDffFlags
= aIt
->second
.mnDffFlags
;
3035 // ----------------------------------------------------------------------------
3037 XclImpSimpleDffManager::XclImpSimpleDffManager( const XclImpRoot
& rRoot
, SvStream
& rDffStrm
) :
3038 SvxMSDffManager( rDffStrm
, rRoot
.GetBasePath(), 0, 0, rRoot
.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT
, 24, 0, &rRoot
.GetTracer().GetBaseTracer() ),
3041 SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS
| SVXMSDFF_SETTINGS_IMPORT_EXCEL
);
3044 XclImpSimpleDffManager::~XclImpSimpleDffManager()
3048 FASTBOOL
XclImpSimpleDffManager::GetColorFromPalette( USHORT nIndex
, Color
& rColor
) const
3050 ColorData nColor
= GetPalette().GetColorData( static_cast< sal_uInt16
>( nIndex
) );
3052 if( nColor
== COL_AUTO
)
3055 rColor
.SetColor( nColor
);
3059 // ----------------------------------------------------------------------------
3061 XclImpDffManager::XclImpDffManager(
3062 const XclImpRoot
& rRoot
, XclImpObjectManager
& rObjManager
, SvStream
& rDffStrm
) :
3063 XclImpSimpleDffManager( rRoot
, rDffStrm
),
3064 SvxMSConvertOCXControls( rRoot
.GetDocShell(), 0 ),
3065 mrObjManager( rObjManager
),
3067 mnLastCtrlIndex( -1 ),
3068 mnCurrFormScTab( -1 )
3070 if( SvtFilterOptions
* pFilterOpt
= SvtFilterOptions::Get() )
3072 if( pFilterOpt
->IsMathType2Math() )
3073 mnOleImpFlags
|= OLE_MATHTYPE_2_STARMATH
;
3074 if( pFilterOpt
->IsWinWord2Writer() )
3075 mnOleImpFlags
|= OLE_WINWORD_2_STARWRITER
;
3076 if( pFilterOpt
->IsPowerPoint2Impress() )
3077 mnOleImpFlags
|= OLE_POWERPOINT_2_STARIMPRESS
;
3080 // try to open the 'Ctls' storage stream containing OCX control properties
3081 mxCtlsStrm
= OpenStream( EXC_STREAM_CTLS
);
3083 // default text margin (convert EMU to drawing layer units)
3084 mnDefTextMargin
= EXC_OBJ_TEXT_MARGIN
;
3085 ScaleEmu( mnDefTextMargin
);
3088 XclImpDffManager::~XclImpDffManager()
3092 String
XclImpObjectManager::GetOleNameOverride( const XclObjId
& nObjId
)
3095 String sCodeName
= GetExtDocOptions().GetCodeName( nObjId
.mnScTab
);
3097 CodeNameToCntrlObjIdInfo::iterator it
= maOleCtrlNameOverride
.find( sCodeName
);
3098 if ( it
!= maOleCtrlNameOverride
.end() )
3100 CntrlObjIdToName::iterator it_id
= it
->second
.find( nObjId
.mnObjId
);
3101 if ( it_id
!= it
->second
.end() )
3103 sOleName
= it_id
->second
;
3109 void XclImpDffManager::StartProgressBar( sal_Size nProgressSize
)
3111 mxProgress
.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING
) );
3112 mxProgress
->AddSegment( nProgressSize
);
3113 mxProgress
->Activate();
3116 void XclImpDffManager::ProcessObject( SdrObjList
* pObjList
, const XclImpDrawObjBase
& rDrawObj
)
3118 Rectangle aAnchorRect
= rDrawObj
.GetAnchorRect();
3119 if( rDrawObj
.IsProcessSdrObj() && rDrawObj
.IsValidSize( aAnchorRect
) )
3121 // CreateSdrObject() recursively creates embedded child objects
3122 SdrObjectPtr
xSdrObj( rDrawObj
.CreateSdrObject( aAnchorRect
, *mxProgress
, false ) );
3124 rDrawObj
.ProcessSdrObject( *xSdrObj
);
3125 // call InsertSdrObject() also, if SdrObject is missing
3126 InsertSdrObject( pObjList
, rDrawObj
, xSdrObj
.release() );
3127 UpdateUsedArea( rDrawObj
);
3131 void XclImpDffManager::ProcessDrawingGroup( SvStream
& rDffStrm
)
3133 rDffStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
3134 DffRecordHeader aHeader
;
3135 rDffStrm
>> aHeader
;
3136 if( aHeader
.nRecType
== DFF_msofbtDggContainer
)
3137 ProcessDggContainer( rDffStrm
, aHeader
);
3140 DBG_ERRORFILE( "XclImpDffManager::ProcessDrawingGroup - unexpected record" );
3144 void XclImpDffManager::ProcessDrawing( SvStream
& rDffStrm
, sal_Size nStrmPos
)
3146 rDffStrm
.Seek( nStrmPos
);
3147 DffRecordHeader aHeader
;
3148 rDffStrm
>> aHeader
;
3149 if( aHeader
.nRecType
== DFF_msofbtDgContainer
)
3150 ProcessDgContainer( rDffStrm
, aHeader
);
3153 DBG_ERRORFILE( "XclImpDffManager::ProcessDrawing - unexpected record" );
3157 SdrObject
* XclImpDffManager::CreateSdrObject( const XclImpTbxObjBase
& rTbxObj
, const Rectangle
& rAnchorRect
)
3159 SdrObjectPtr xSdrObj
;
3161 OUString aServiceName
= rTbxObj
.GetServiceName();
3162 if( aServiceName
.getLength() > 0 ) try
3164 // create the form control from scratch
3165 Reference
< XFormComponent
> xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName
), UNO_QUERY_THROW
);
3166 // set current controls form, needed in virtual function InsertControl()
3167 SetCurrentForm( rTbxObj
.GetScTab() );
3168 // try to insert the control into the form
3169 ::com::sun::star::awt::Size aDummySize
;
3170 Reference
< XShape
> xShape
;
3171 if( mxCurrForm
.is() && InsertControl( xFormComp
, aDummySize
, &xShape
, TRUE
) )
3173 xSdrObj
.reset( rTbxObj
.CreateSdrObjectFromShape( xShape
, rAnchorRect
) );
3174 // try to attach a macro to the control
3175 ScriptEventDescriptor aDescriptor
;
3176 if( (mnLastCtrlIndex
>= 0) && rTbxObj
.FillMacroDescriptor( aDescriptor
) )
3178 Reference
< XEventAttacherManager
> xEventMgr( mxCurrForm
, UNO_QUERY_THROW
);
3179 xEventMgr
->registerScriptEvent( mnLastCtrlIndex
, aDescriptor
);
3187 return xSdrObj
.release();
3190 SdrObject
* XclImpDffManager::CreateSdrObject( const XclImpPictureObj
& rPicObj
, const Rectangle
& rAnchorRect
)
3192 SdrObjectPtr xSdrObj
;
3194 if( rPicObj
.IsOcxControl() )
3196 if( mxCtlsStrm
.Is() ) try
3198 /* set current controls form, needed in virtual function InsertControl()
3199 called from ReadOCXExcelKludgeStream() */
3200 SetCurrentForm( rPicObj
.GetScTab() );
3201 // seek to stream position of the extra data for this control
3202 mxCtlsStrm
->Seek( rPicObj
.GetCtlsStreamPos() );
3203 // read from mxCtlsStrm into xShape, insert the control model into the form
3204 Reference
< XShape
> xShape
;
3205 if( mxCurrForm
.is() && ReadOCXExcelKludgeStream( mxCtlsStrm
, &xShape
, TRUE
) )
3206 xSdrObj
.reset( rPicObj
.CreateSdrObjectFromShape( xShape
, rAnchorRect
) );
3214 SfxObjectShell
* pDocShell
= GetDocShell();
3215 SotStorageRef xSrcStrg
= GetRootStorage();
3216 String aStrgName
= rPicObj
.GetOleStorageName();
3217 if( pDocShell
&& xSrcStrg
.Is() && (aStrgName
.Len() > 0) )
3219 // first try to resolve graphic from DFF storage
3222 if( !GetBLIP( GetPropertyValue( DFF_Prop_pib
), aGraphic
, &aVisArea
) )
3224 // if not found, use graphic from object (imported from IMGDATA record)
3225 aGraphic
= rPicObj
.GetGraphic();
3226 aVisArea
= rPicObj
.GetVisArea();
3228 if( aGraphic
.GetType() != GRAPHIC_NONE
)
3230 ErrCode nError
= ERRCODE_NONE
;
3231 namespace cssea
= ::com::sun::star::embed::Aspects
;
3232 sal_Int64 nAspects
= rPicObj
.IsSymbol() ? cssea::MSOLE_ICON
: cssea::MSOLE_CONTENT
;
3233 xSdrObj
.reset( CreateSdrOLEFromStorage(
3234 aStrgName
, xSrcStrg
, pDocShell
->GetStorage(), aGraphic
,
3235 rAnchorRect
, aVisArea
, 0, nError
, mnOleImpFlags
, nAspects
) );
3240 return xSdrObj
.release();
3243 ScRange
XclImpDffManager::GetUsedArea( SCTAB nScTab
) const
3245 ScRange
aScUsedArea( ScAddress::INITIALIZE_INVALID
);
3246 ScRangeMap::const_iterator aIt
= maUsedAreaMap
.find( nScTab
);
3247 if( aIt
!= maUsedAreaMap
.end() )
3248 aScUsedArea
= aIt
->second
;
3252 // virtual functions ----------------------------------------------------------
3254 void XclImpDffManager::ProcessClientAnchor2( SvStream
& rDffStrm
,
3255 DffRecordHeader
& rHeader
, void* /*pClientData*/, DffObjData
& rObjData
)
3257 // find the OBJ record data related to the processed shape
3258 if( XclImpDrawObjBase
* pDrawObj
= mrObjManager
.FindDrawObj( rObjData
.rSpHd
).get() )
3260 DBG_ASSERT( rHeader
.nRecType
== DFF_msofbtClientAnchor
, "XclImpDffManager::ProcessClientAnchor2 - no client anchor record" );
3261 XclObjAnchor
aAnchor( pDrawObj
->GetScTab() );
3262 rHeader
.SeekToContent( rDffStrm
);
3263 rDffStrm
.SeekRel( 2 ); // flags
3264 rDffStrm
>> aAnchor
; // anchor format equal to BIFF5 OBJ records
3265 pDrawObj
->SetAnchor( aAnchor
);
3266 rObjData
.aChildAnchor
= pDrawObj
->GetAnchorRect();
3267 rObjData
.bChildAnchor
= sal_True
;
3271 SdrObject
* XclImpDffManager::ProcessObj( SvStream
& rDffStrm
,
3272 DffObjData
& rDffObjData
, void* pClientData
, Rectangle
& /*rTextRect*/, SdrObject
* pOldSdrObj
)
3274 /* pOldSdrObj passes a generated SdrObject. This function owns this object
3275 and can modify it. The function has either to return it back to caller
3276 or to delete it by itself. */
3277 SdrObjectPtr
xSdrObj( pOldSdrObj
);
3279 // find the OBJ record data related to the processed shape
3280 XclImpDrawObjRef xDrawObj
= mrObjManager
.FindDrawObj( rDffObjData
.rSpHd
);
3281 const Rectangle
& rAnchorRect
= rDffObjData
.aChildAnchor
;
3283 // #102378# Do not process the global page group shape (flag SP_FPATRIARCH)
3284 bool bGlobalPageGroup
= ::get_flag
< sal_uInt32
>( rDffObjData
.nSpFlags
, SP_FPATRIARCH
);
3285 if( !xDrawObj
|| !xDrawObj
->IsProcessSdrObj() || bGlobalPageGroup
)
3286 return 0; // simply return, xSdrObj will be destroyed
3288 /* Pass pointer to top-level object back to caller. If the processed
3289 object is embedded in a group, the pointer is already set to the
3290 top-level parent object. */
3291 XclImpDrawObjBase
** ppTopLevelObj
= reinterpret_cast< XclImpDrawObjBase
** >( pClientData
);
3292 bool bIsTopLevel
= !ppTopLevelObj
|| !*ppTopLevelObj
;
3293 if( ppTopLevelObj
&& bIsTopLevel
)
3294 *ppTopLevelObj
= xDrawObj
.get();
3296 // #119010# connectors don't have to be area objects
3297 if( dynamic_cast< SdrEdgeObj
* >( xSdrObj
.get() ) )
3298 xDrawObj
->SetAreaObj( false );
3300 /* Check for valid size for all objects. Needed to ignore lots of invisible
3301 phantom objects from deleted rows or columns (for performance reasons).
3302 #i30816# Include objects embedded in groups.
3303 #i58780# Ignore group shapes, size is not initialized. */
3304 bool bEmbeddedGroup
= !bIsTopLevel
&& dynamic_cast< SdrObjGroup
* >( xSdrObj
.get() );
3305 if( !bEmbeddedGroup
&& !xDrawObj
->IsValidSize( rAnchorRect
) )
3306 return 0; // simply return, xSdrObj will be destroyed
3308 // set shape information from DFF stream
3309 String aObjName
= GetPropertyString( DFF_Prop_wzName
, rDffStrm
);
3310 String aHyperlink
= ReadHlinkProperty( rDffStrm
);
3311 bool bVisible
= !GetPropertyBool( DFF_Prop_fHidden
);
3312 bool bAutoMargin
= GetPropertyBool( DFF_Prop_AutoTextMargin
);
3313 xDrawObj
->SetDffData( rDffObjData
, aObjName
, aHyperlink
, bVisible
, bAutoMargin
);
3315 /* Connect textbox data (string, alignment, text orientation) to object.
3316 #98132# don't ask for a text-ID, DFF export doesn't set one. */
3317 if( XclImpTextObj
* pTextObj
= dynamic_cast< XclImpTextObj
* >( xDrawObj
.get() ) )
3318 if( const XclImpObjTextData
* pTextData
= mrObjManager
.FindTextData( rDffObjData
.rSpHd
) )
3319 pTextObj
->SetTextData( *pTextData
);
3321 // copy line and fill formatting of TBX form controls from DFF properties
3322 if( XclImpTbxObjBase
* pTbxObj
= dynamic_cast< XclImpTbxObjBase
* >( xDrawObj
.get() ) )
3323 pTbxObj
->SetDffProperties( *this );
3325 // try to create a custom SdrObject that overwrites the passed object
3326 SdrObjectPtr
xNewSdrObj( xDrawObj
->CreateSdrObject( rAnchorRect
, *mxProgress
, true ) );
3327 if( xNewSdrObj
.is() )
3328 xSdrObj
.reset( xNewSdrObj
.release() );
3330 // process the SdrObject
3333 // filled without color -> set system window color
3334 if( GetPropertyBool( DFF_Prop_fFilled
) && !IsProperty( DFF_Prop_fillColor
) )
3335 xSdrObj
->SetMergedItem( XFillColorItem( EMPTY_STRING
, GetPalette().GetColor( EXC_COLOR_WINDOWBACK
) ) );
3337 // additional processing on the SdrObject
3338 xDrawObj
->ProcessSdrObject( *xSdrObj
);
3340 // add the area used by this object to the internal map of used areas
3341 UpdateUsedArea( *xDrawObj
);
3343 /* If the SdrObject will not be inserted into the draw page, delete it
3344 here. Happens e.g. for notes: The ProcessSdrObject() call above has
3345 inserted the note into the document, and the SdrObject is not
3347 if( !xDrawObj
->IsInsertSdrObj() )
3351 /* Store the relation between shape ID and SdrObject for connectors. Must
3352 be done here (and not in InsertSdrObject() function), otherwise all
3353 SdrObjects embedded in groups would be lost. */
3355 maSolverCont
.InsertSdrObjectInfo( *xSdrObj
, xDrawObj
->GetDffShapeId(), xDrawObj
->GetDffFlags() );
3357 return xSdrObj
.release();
3360 ULONG
XclImpDffManager::Calc_nBLIPPos( ULONG
/*nOrgVal*/, ULONG nStreamPos
) const
3362 return nStreamPos
+ 4;
3365 sal_Bool
XclImpDffManager::InsertControl( const Reference
< XFormComponent
>& rxFormComp
,
3366 const ::com::sun::star::awt::Size
& /*rSize*/, Reference
< XShape
>* pxShape
,
3367 BOOL
/*bFloatingCtrl*/ )
3369 if( GetDocShell() ) try
3371 Reference
< XIndexContainer
> xFormIC( mxCurrForm
, UNO_QUERY_THROW
);
3372 Reference
< XControlModel
> xCtrlModel( rxFormComp
, UNO_QUERY_THROW
);
3374 // create the control shape
3375 Reference
< XShape
> xShape( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ) ), UNO_QUERY_THROW
);
3376 Reference
< XControlShape
> xCtrlShape( xShape
, UNO_QUERY_THROW
);
3378 // insert the new control into the form
3379 sal_Int32 nNewIndex
= xFormIC
->getCount();
3380 xFormIC
->insertByIndex( nNewIndex
, Any( rxFormComp
) );
3381 // on success: store new index of the control for later use (macro events)
3382 mnLastCtrlIndex
= nNewIndex
;
3384 // set control model at control shape and pass back shape to caller
3385 xCtrlShape
->setControl( xCtrlModel
);
3386 if( pxShape
) *pxShape
= xShape
;
3391 DBG_ERRORFILE( "XclImpDffManager::InsertControl - cannot create form control" );
3397 // private --------------------------------------------------------------------
3399 String
XclImpDffManager::ReadHlinkProperty( SvStream
& rDffStrm
) const
3401 /* Reads hyperlink data from a complex DFF property. Contents of this
3402 property are equal to the HLINK record, import of this record is
3403 implemented in class XclImpHyperlink. This function has to create an
3404 instance of the XclImpStream class to be able to reuse the
3405 functionality of XclImpHyperlink. */
3407 sal_uInt32 nBufferSize
= GetPropertyValue( DFF_Prop_pihlShape
);
3408 if( (0 < nBufferSize
) && (nBufferSize
<= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape
, rDffStrm
) )
3410 // create a faked BIFF record that can be read by XclImpStream class
3411 SvMemoryStream aMemStream
;
3412 aMemStream
<< sal_uInt16( 0 ) << static_cast< sal_uInt16
>( nBufferSize
);
3414 // copy from DFF stream to memory stream
3415 ::std::vector
< sal_uInt8
> aBuffer( nBufferSize
);
3416 sal_uInt8
* pnData
= &aBuffer
.front();
3417 if( rDffStrm
.Read( pnData
, nBufferSize
) == nBufferSize
)
3419 aMemStream
.Write( pnData
, nBufferSize
);
3421 // create BIFF import stream to be able to use XclImpHyperlink class
3422 XclImpStream
aXclStrm( aMemStream
, GetRoot() );
3423 if( aXclStrm
.StartNextRecord() )
3424 aString
= XclImpHyperlink::ReadEmbeddedData( aXclStrm
);
3430 void XclImpDffManager::ProcessDggContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rDggHeader
)
3432 // seek to end of drawing group container
3433 rDggHeader
.SeekToEndOfRecord( rDffStrm
);
3436 void XclImpDffManager::ProcessDgContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rDgHeader
)
3438 sal_Size nEndPos
= rDgHeader
.GetRecEndFilePos();
3439 while( rDffStrm
.Tell() < nEndPos
)
3441 DffRecordHeader aHeader
;
3442 rDffStrm
>> aHeader
;
3443 switch( aHeader
.nRecType
)
3445 case DFF_msofbtSolverContainer
:
3446 ProcessSolverContainer( rDffStrm
, aHeader
);
3448 case DFF_msofbtSpgrContainer
:
3449 ProcessShGrContainer( rDffStrm
, aHeader
);
3452 aHeader
.SeekToEndOfRecord( rDffStrm
);
3455 // seek to end of drawing page container
3456 rDgHeader
.SeekToEndOfRecord( rDffStrm
);
3458 // #i12638# #i37900# connector rules
3459 maSolverCont
.UpdateConnectorRules();
3460 SolveSolver( maSolverCont
);
3461 maSolverCont
.RemoveConnectorRules();
3464 void XclImpDffManager::ProcessShGrContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rShGrHeader
)
3466 sal_Size nEndPos
= rShGrHeader
.GetRecEndFilePos();
3467 while( rDffStrm
.Tell() < nEndPos
)
3469 DffRecordHeader aHeader
;
3470 rDffStrm
>> aHeader
;
3471 switch( aHeader
.nRecType
)
3473 case DFF_msofbtSpgrContainer
:
3474 case DFF_msofbtSpContainer
:
3475 ProcessShContainer( rDffStrm
, aHeader
);
3478 aHeader
.SeekToEndOfRecord( rDffStrm
);
3481 // seek to end of shape group container
3482 rShGrHeader
.SeekToEndOfRecord( rDffStrm
);
3485 void XclImpDffManager::ProcessSolverContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rSolverHeader
)
3487 // solver container wants to read the solver container header again
3488 rSolverHeader
.SeekToBegOfRecord( rDffStrm
);
3489 // read the entire solver container
3490 rDffStrm
>> maSolverCont
;
3491 // seek to end of solver container
3492 rSolverHeader
.SeekToEndOfRecord( rDffStrm
);
3495 void XclImpDffManager::ProcessShContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rShHeader
)
3497 rShHeader
.SeekToBegOfRecord( rDffStrm
);
3499 const XclImpDrawObjBase
* pDrawObj
= 0;
3500 /* The call to ImportObj() creates and returns a new SdrObject for the
3501 processed shape. We take ownership of the returned object here. If the
3502 shape is a group object, all embedded objects are created recursively,
3503 and the returned group object contains them all. ImportObj() calls the
3504 virtual functions ProcessClientAnchor2() and ProcessObj() and writes
3505 the pointer to the related draw object data (OBJ record) into pDrawObj. */
3506 SdrObjectPtr
xSdrObj( ImportObj( rDffStrm
, &pDrawObj
, aDummy
, aDummy
, 0, 0 ) );
3507 if( pDrawObj
&& xSdrObj
.is() )
3508 InsertSdrObject( GetSdrPage( pDrawObj
->GetScTab() ), *pDrawObj
, xSdrObj
.release() );
3509 rShHeader
.SeekToEndOfRecord( rDffStrm
);
3512 void XclImpDffManager::InsertSdrObject( SdrObjList
* pObjList
, const XclImpDrawObjBase
& rDrawObj
, SdrObject
* pSdrObj
)
3514 /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
3515 states to skip insertion, or missing draw page), the object is
3516 automatically deleted. */
3517 SdrObjectPtr
xSdrObj( pSdrObj
);
3518 if( pObjList
&& xSdrObj
.is() && rDrawObj
.IsInsertSdrObj() )
3519 pObjList
->NbcInsertObject( xSdrObj
.release() );
3520 // SdrObject still here? Insertion failed, remove data from shape ID map.
3522 maSolverCont
.RemoveSdrObjectInfo( *xSdrObj
);
3525 void XclImpDffManager::SetCurrentForm( SCTAB nScTab
)
3527 if( nScTab
!= mnCurrFormScTab
)
3530 mnCurrFormScTab
= nScTab
;
3532 SdrPage
* pSdrPage
= GetSdrPage( nScTab
);
3533 if( GetDocShell() && pSdrPage
) try
3535 Reference
< XFormsSupplier
> xFormsSupplier( pSdrPage
->getUnoPage(), UNO_QUERY_THROW
);
3536 Reference
< XNameContainer
> xFormsNC
= xFormsSupplier
->getForms();
3539 // find or create the Standard form used to insert the imported controls
3540 OUString aFormName
= CREATE_OUSTRING( "Standard" );
3541 if( xFormsNC
->hasByName( aFormName
) )
3543 xFormsNC
->getByName( aFormName
) >>= mxCurrForm
;
3547 mxCurrForm
.set( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW
);
3548 xFormsNC
->insertByName( aFormName
, Any( mxCurrForm
) );
3558 void XclImpDffManager::UpdateUsedArea( const XclImpDrawObjBase
& rDrawObj
)
3560 ScRange aScObjArea
= rDrawObj
.GetUsedArea();
3561 if( aScObjArea
.IsValid() )
3563 ScRange
* pScTabArea
= 0;
3564 ScRangeMap::iterator aIt
= maUsedAreaMap
.find( rDrawObj
.GetScTab() );
3565 if( aIt
== maUsedAreaMap
.end() )
3567 pScTabArea
= &maUsedAreaMap
[ rDrawObj
.GetScTab() ];
3568 pScTabArea
->SetInvalid();
3571 pScTabArea
= &aIt
->second
;
3574 pScTabArea
->ExtendTo( aScObjArea
);
3578 // The object manager =========================================================
3580 XclImpObjectManager::XclImpObjectManager( const XclImpRoot
& rRoot
) :
3583 maDefObjNames
[ EXC_OBJTYPE_GROUP
] = CREATE_STRING( "Group" );
3584 maDefObjNames
[ EXC_OBJTYPE_LINE
] = ScGlobal::GetRscString( STR_SHAPE_LINE
);
3585 maDefObjNames
[ EXC_OBJTYPE_RECTANGLE
] = ScGlobal::GetRscString( STR_SHAPE_RECTANGLE
);
3586 maDefObjNames
[ EXC_OBJTYPE_OVAL
] = ScGlobal::GetRscString( STR_SHAPE_OVAL
);
3587 maDefObjNames
[ EXC_OBJTYPE_ARC
] = CREATE_STRING( "Arc" );
3588 maDefObjNames
[ EXC_OBJTYPE_CHART
] = CREATE_STRING( "Chart" );
3589 maDefObjNames
[ EXC_OBJTYPE_TEXT
] = CREATE_STRING( "Text" );
3590 maDefObjNames
[ EXC_OBJTYPE_BUTTON
] = ScGlobal::GetRscString( STR_FORM_BUTTON
);
3591 maDefObjNames
[ EXC_OBJTYPE_PICTURE
] = CREATE_STRING( "Picture" );
3592 maDefObjNames
[ EXC_OBJTYPE_POLYGON
] = CREATE_STRING( "Freeform" );
3593 maDefObjNames
[ EXC_OBJTYPE_CHECKBOX
] = ScGlobal::GetRscString( STR_FORM_CHECKBOX
);
3594 maDefObjNames
[ EXC_OBJTYPE_OPTIONBUTTON
] = ScGlobal::GetRscString( STR_FORM_OPTIONBUTTON
);
3595 maDefObjNames
[ EXC_OBJTYPE_EDIT
] = CREATE_STRING( "Edit Box" );
3596 maDefObjNames
[ EXC_OBJTYPE_LABEL
] = ScGlobal::GetRscString( STR_FORM_LABEL
);
3597 maDefObjNames
[ EXC_OBJTYPE_DIALOG
] = CREATE_STRING( "Dialog Frame" );
3598 maDefObjNames
[ EXC_OBJTYPE_SPIN
] = ScGlobal::GetRscString( STR_FORM_SPINNER
);
3599 maDefObjNames
[ EXC_OBJTYPE_SCROLLBAR
] = ScGlobal::GetRscString( STR_FORM_SCROLLBAR
);
3600 maDefObjNames
[ EXC_OBJTYPE_LISTBOX
] = ScGlobal::GetRscString( STR_FORM_LISTBOX
);
3601 maDefObjNames
[ EXC_OBJTYPE_GROUPBOX
] = ScGlobal::GetRscString( STR_FORM_GROUPBOX
);
3602 maDefObjNames
[ EXC_OBJTYPE_DROPDOWN
] = ScGlobal::GetRscString( STR_FORM_DROPDOWN
);
3603 maDefObjNames
[ EXC_OBJTYPE_NOTE
] = CREATE_STRING( "Comment" );
3604 maDefObjNames
[ EXC_OBJTYPE_DRAWING
] = ScGlobal::GetRscString( STR_SHAPE_AUTOSHAPE
);
3607 XclImpObjectManager::~XclImpObjectManager()
3611 // *** Read Excel records *** -------------------------------------------------
3613 Graphic
XclImpObjectManager::ReadImgData( XclImpStream
& rStrm
) // static helper
3616 sal_uInt16 nFormat
, nEnv
;
3617 sal_uInt32 nDataSize
;
3618 rStrm
>> nFormat
>> nEnv
>> nDataSize
;
3619 if( nDataSize
<= rStrm
.GetRecLeft() )
3623 case EXC_IMGDATA_WMF
: ReadWmf( aGraphic
, rStrm
); break;
3624 case EXC_IMGDATA_BMP
: ReadBmp( aGraphic
, rStrm
); break;
3625 default: DBG_ERRORFILE( "XclImpObjectManager::ReadImgData - unknown image format" );
3631 void XclImpObjectManager::ReadObj( XclImpStream
& rStrm
)
3633 XclImpDrawObjRef xDrawObj
;
3635 /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
3636 records. In this case, the OBJ records are in BIFF5 format. Do a sanity
3637 check here that there is no DFF data loaded before. */
3638 DBG_ASSERT( maDffStrm
.Tell() == 0, "XclImpObjectManager::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
3639 if( maDffStrm
.Tell() == 0 ) switch( GetBiff() )
3642 xDrawObj
= XclImpDrawObjBase::ReadObj3( rStrm
);
3645 xDrawObj
= XclImpDrawObjBase::ReadObj4( rStrm
);
3649 xDrawObj
= XclImpDrawObjBase::ReadObj5( rStrm
);
3657 // insert into maRawObjs or into the last open group object
3658 maRawObjs
.InsertGrouped( xDrawObj
);
3659 // to be able to find objects by ID
3660 maObjMapId
[ xDrawObj
->GetObjId() ] = xDrawObj
;
3664 void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream
& rStrm
)
3666 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8
);
3667 // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
3668 rStrm
.ResetRecord( true, EXC_ID_MSODRAWINGGROUP
);
3669 ReadDffRecord( rStrm
);
3672 void XclImpObjectManager::ReadMsoDrawing( XclImpStream
& rStrm
)
3674 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8
);
3675 // disable internal CONTINUE handling
3676 rStrm
.ResetRecord( false );
3677 /* #i60510# real life: MSODRAWINGSELECTION record may contain garbage -
3678 this makes it impossible to process the DFF stream in one run.
3679 Store stream start position for every sheet separately, will be used
3680 to seek the stream to these positions later, when processing the next
3682 size_t nTabIdx
= static_cast< size_t >( GetCurrScTab() );
3683 if( nTabIdx
>= maTabStrmPos
.size() )
3685 maTabStrmPos
.resize( nTabIdx
, STREAM_SEEK_TO_END
);
3686 maTabStrmPos
.push_back( maDffStrm
.Tell() );
3688 // read leading MSODRAWING record
3689 ReadDffRecord( rStrm
);
3691 // read following drawing records, but do not start following unrelated record
3693 while( bLoop
) switch( rStrm
.GetNextRecId() )
3695 case EXC_ID_MSODRAWING
:
3696 case EXC_ID_MSODRAWINGSEL
:
3698 rStrm
.StartNextRecord();
3699 ReadDffRecord( rStrm
);
3702 rStrm
.StartNextRecord();
3706 rStrm
.StartNextRecord();
3713 // re-enable internal CONTINUE handling
3714 rStrm
.ResetRecord( true );
3717 void XclImpObjectManager::ReadNote( XclImpStream
& rStrm
)
3735 void XclImpObjectManager::ReadTabChart( XclImpStream
& rStrm
)
3737 DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5
);
3738 ScfRef
< XclImpChartObj
> xChartObj( new XclImpChartObj( GetRoot(), true ) );
3739 xChartObj
->ReadChartSubStream( rStrm
);
3740 // insert the chart as raw object without connected DFF data
3741 maRawObjs
.push_back( xChartObj
);
3744 // *** Drawing objects *** ----------------------------------------------------
3746 XclImpDrawObjRef
XclImpObjectManager::FindDrawObj( const DffRecordHeader
& rHeader
) const
3748 /* maObjMap stores objects by position of the client data (OBJ record) in
3749 the DFF stream, which is always behind shape start position of the
3750 passed header. The function upper_bound() finds the first element in
3751 the map whose key is greater than the start position of the header. Its
3752 end position is used to test whether the found object is really related
3754 XclImpDrawObjRef xDrawObj
;
3755 XclImpObjMap::const_iterator aIt
= maObjMap
.upper_bound( rHeader
.GetRecBegFilePos() );
3756 if( (aIt
!= maObjMap
.end()) && (aIt
->first
<= rHeader
.GetRecEndFilePos()) )
3757 xDrawObj
= aIt
->second
;
3761 XclImpDrawObjRef
XclImpObjectManager::FindDrawObj( const XclObjId
& rObjId
) const
3763 XclImpDrawObjRef xDrawObj
;
3764 XclImpObjMapById::const_iterator aIt
= maObjMapId
.find( rObjId
);
3765 if( aIt
!= maObjMapId
.end() )
3766 xDrawObj
= aIt
->second
;
3770 const XclImpObjTextData
* XclImpObjectManager::FindTextData( const DffRecordHeader
& rHeader
) const
3772 /* maTextMap stores textbox data by position of the client data (TXO
3773 record) in the DFF stream, which is always behind shape start position
3774 of the passed header. The function upper_bound() finds the first
3775 element in the map whose key is greater than the start position of the
3776 header. Its end position is used to test whether the found object is
3777 really related to the shape. */
3778 XclImpObjTextMap::const_iterator aIt
= maTextMap
.upper_bound( rHeader
.GetRecBegFilePos() );
3779 if( (aIt
!= maTextMap
.end()) && (aIt
->first
<= rHeader
.GetRecEndFilePos()) )
3780 return aIt
->second
.get();
3784 void XclImpObjectManager::SetSkipObj( SCTAB nScTab
, sal_uInt16 nObjId
)
3786 maSkipObjs
.push_back( XclObjId( nScTab
, nObjId
) );
3789 // *** Drawing object conversion *** ------------------------------------------
3791 XclImpDffManager
& XclImpObjectManager::GetDffManager()
3794 mxDffManager
.reset( new XclImpDffManager( GetRoot(), *this, maDffStrm
) );
3795 return *mxDffManager
;
3798 void XclImpObjectManager::ConvertObjects()
3800 RTL_LOGFILE_CONTEXT_AUTHOR( aLog
, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" );
3802 // do nothing if the document does not contain a drawing layer
3803 if( GetDoc().GetDrawLayer() )
3805 // process list of identifiers of objects to be skipped
3806 for( XclObjIdVec::const_iterator aVIt
= maSkipObjs
.begin(), aVEnd
= maSkipObjs
.end(); aVIt
!= aVEnd
; ++aVIt
)
3807 if( XclImpDrawObjBase
* pDrawObj
= FindDrawObj( *aVIt
).get() )
3808 pDrawObj
->SetProcessSdrObj( false );
3810 // get progress bar size for all valid objects
3811 sal_Size nProgressSize
= GetProgressSize();
3812 if( nProgressSize
> 0 )
3814 XclImpDffManager
& rDffManager
= GetDffManager();
3815 rDffManager
.StartProgressBar( nProgressSize
);
3816 // process drawing objects without DFF data
3817 for( XclImpDrawObjVector::const_iterator aVIt
= maRawObjs
.begin(), aVEnd
= maRawObjs
.end(); aVIt
!= aVEnd
; ++aVIt
)
3818 rDffManager
.ProcessObject( GetSdrPage( (*aVIt
)->GetScTab() ), **aVIt
);
3819 // process the global DFF container, contains pictures
3820 if( !maTabStrmPos
.empty() && (maTabStrmPos
.front() > 0) )
3821 rDffManager
.ProcessDrawingGroup( maDffStrm
);
3822 // process the sheet records, this inserts the objects into the drawing layer
3823 for( StreamPosVec::const_iterator aPIt
= maTabStrmPos
.begin(), aPEnd
= maTabStrmPos
.end(); aPIt
!= aPEnd
; ++aPIt
)
3824 if( *aPIt
!= STREAM_SEEK_TO_END
)
3825 rDffManager
.ProcessDrawing( maDffStrm
, *aPIt
);
3830 String
XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase
& rDrawObj
) const
3833 DefObjNameMap::const_iterator aIt
= maDefObjNames
.find( rDrawObj
.GetObjType() );
3834 if( aIt
!= maDefObjNames
.end() )
3835 aDefName
.Append( aIt
->second
);
3836 return aDefName
.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj
.GetObjId().mnObjId
) );
3839 ScRange
XclImpObjectManager::GetUsedArea( SCTAB nScTab
) const
3841 ScRange
aScUsedArea( ScAddress::INITIALIZE_INVALID
);
3842 if( mxDffManager
.is() )
3843 aScUsedArea
= mxDffManager
->GetUsedArea( nScTab
);
3847 // private --------------------------------------------------------------------
3849 void XclImpObjectManager::ReadWmf( Graphic
& rGraphic
, XclImpStream
& rStrm
) // static helper
3851 // extract graphic data from IMGDATA and following CONTINUE records
3853 SvMemoryStream aMemStrm
;
3854 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
3855 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
3856 // import the graphic from memory stream
3857 GDIMetaFile aGDIMetaFile
;
3858 if( ::ReadWindowMetafile( aMemStrm
, aGDIMetaFile
, 0 ) )
3859 rGraphic
= aGDIMetaFile
;
3862 void XclImpObjectManager::ReadBmp( Graphic
& rGraphic
, XclImpStream
& rStrm
) // static helper
3864 // extract graphic data from IMGDATA and following CONTINUE records
3865 SvMemoryStream aMemStrm
;
3867 /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
3868 DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
3869 pixel depth = 32 bit. After that, 3 unused bytes are added before the
3870 actual pixel data. This does even confuse Excel 5 and later, which
3871 cannot read the image data correctly. */
3872 if( rStrm
.GetRoot().GetBiff() <= EXC_BIFF4
)
3874 rStrm
.PushPosition();
3875 sal_uInt32 nHdrSize
;
3876 sal_uInt16 nWidth
, nHeight
, nPlanes
, nDepth
;
3877 rStrm
>> nHdrSize
>> nWidth
>> nHeight
>> nPlanes
>> nDepth
;
3878 if( (nHdrSize
== 12) && (nPlanes
== 1) && (nDepth
== 32) )
3881 aMemStrm
.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
3882 aMemStrm
<< nHdrSize
<< nWidth
<< nHeight
<< nPlanes
<< nDepth
;
3883 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
3885 rStrm
.PopPosition();
3888 // no special handling above -> just copy the remaining record data
3889 if( aMemStrm
.Tell() == 0 )
3890 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
3892 // import the graphic from memory stream
3893 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
3895 if( aBitmap
.Read( aMemStrm
, FALSE
) ) // read DIB without file header
3899 void XclImpObjectManager::ReadDffRecord( XclImpStream
& rStrm
)
3901 maDffStrm
.Seek( STREAM_SEEK_TO_END
);
3902 rStrm
.CopyRecordToStream( maDffStrm
);
3905 void XclImpObjectManager::ReadObj8( XclImpStream
& rStrm
)
3907 XclImpDrawObjRef xDrawObj
= XclImpDrawObjBase::ReadObj8( rStrm
);
3908 // store the new object in the internal containers
3909 maObjMap
[ maDffStrm
.Tell() ] = xDrawObj
;
3910 maObjMapId
[ xDrawObj
->GetObjId() ] = xDrawObj
;
3913 void XclImpObjectManager::ReadTxo( XclImpStream
& rStrm
)
3915 XclImpObjTextRef
xTextData( new XclImpObjTextData
);
3916 maTextMap
[ maDffStrm
.Tell() ] = xTextData
;
3918 // 1) read the TXO record
3919 xTextData
->maData
.ReadTxo8( rStrm
);
3921 // 2) first CONTINUE with string
3922 xTextData
->mxString
.reset();
3924 if( xTextData
->maData
.mnTextLen
> 0 )
3926 bValid
= (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord();
3927 DBG_ASSERT( bValid
, "XclImpObjectManager::ReadTxo - missing CONTINUE record" );
3929 xTextData
->mxString
.reset( new XclImpString( rStrm
.ReadUniString( xTextData
->maData
.mnTextLen
) ) );
3932 // 3) second CONTINUE with formatting runs
3933 if( xTextData
->maData
.mnFormatSize
> 0 )
3935 bValid
= (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord();
3936 DBG_ASSERT( bValid
, "XclImpObjectManager::ReadTxo - missing CONTINUE record" );
3938 xTextData
->ReadFormats( rStrm
);
3942 void XclImpObjectManager::ReadNote3( XclImpStream
& rStrm
)
3945 sal_uInt16 nTotalLen
;
3946 rStrm
>> aXclPos
>> nTotalLen
;
3948 SCTAB nScTab
= GetCurrScTab();
3949 ScAddress
aScNotePos( ScAddress::UNINITIALIZED
);
3950 if( GetAddressConverter().ConvertAddress( aScNotePos
, aXclPos
, nScTab
, true ) )
3952 sal_uInt16 nPartLen
= ::std::min( nTotalLen
, static_cast< sal_uInt16
>( rStrm
.GetRecLeft() ) );
3953 String aNoteText
= rStrm
.ReadRawByteString( nPartLen
);
3954 nTotalLen
= nTotalLen
- nPartLen
;
3955 while( (nTotalLen
> 0) && (rStrm
.GetNextRecId() == EXC_ID_NOTE
) && rStrm
.StartNextRecord() )
3957 rStrm
>> aXclPos
>> nPartLen
;
3958 DBG_ASSERT( aXclPos
.mnRow
== 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
3959 if( aXclPos
.mnRow
== 0xFFFF )
3961 DBG_ASSERT( nPartLen
<= nTotalLen
, "XclImpObjectManager::ReadNote3 - string too long" );
3962 aNoteText
.Append( rStrm
.ReadRawByteString( nPartLen
) );
3963 nTotalLen
= nTotalLen
- ::std::min( nTotalLen
, nPartLen
);
3967 // seems to be a new note, record already started -> load the note
3968 rStrm
.Seek( EXC_REC_SEEK_TO_BEGIN
);
3973 ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos
, aNoteText
, false, false );
3977 void XclImpObjectManager::ReadNote8( XclImpStream
& rStrm
)
3980 sal_uInt16 nFlags
, nObjId
;
3981 rStrm
>> aXclPos
>> nFlags
>> nObjId
;
3983 SCTAB nScTab
= GetCurrScTab();
3984 ScAddress
aScNotePos( ScAddress::UNINITIALIZED
);
3985 if( GetAddressConverter().ConvertAddress( aScNotePos
, aXclPos
, nScTab
, true ) )
3986 if( nObjId
!= EXC_OBJ_INVALID_ID
)
3987 if( XclImpNoteObj
* pNoteObj
= dynamic_cast< XclImpNoteObj
* >( FindDrawObj( XclObjId( nScTab
, nObjId
) ).get() ) )
3988 pNoteObj
->SetNoteData( aScNotePos
, nFlags
);
3991 sal_Size
XclImpObjectManager::GetProgressSize() const
3993 sal_Size nProgressSize
= maRawObjs
.GetProgressSize();
3994 for( XclImpObjMap::const_iterator aMIt
= maObjMap
.begin(), aMEnd
= maObjMap
.end(); aMIt
!= aMEnd
; ++aMIt
)
3995 nProgressSize
+= aMIt
->second
->GetProgressSize();
3996 return nProgressSize
;
3999 // DFF property set helper ====================================================
4001 XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot
& rRoot
) :
4002 XclImpRoot( rRoot
),
4003 maDffManager( rRoot
, maDummyStrm
)
4007 void XclImpDffPropSet::Read( XclImpStream
& rStrm
)
4009 sal_uInt32 nPropSetSize
;
4011 rStrm
.PushPosition();
4013 rStrm
>> nPropSetSize
;
4014 rStrm
.PopPosition();
4016 mxMemStrm
.reset( new SvMemoryStream
);
4017 rStrm
.CopyToStream( *mxMemStrm
, 8 + nPropSetSize
);
4018 mxMemStrm
->Seek( STREAM_SEEK_TO_BEGIN
);
4019 maDffManager
.ReadPropSet( *mxMemStrm
, 0 );
4022 sal_uInt32
XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId
, sal_uInt32 nDefault
) const
4024 return maDffManager
.GetPropertyValue( nPropId
, nDefault
);
4027 void XclImpDffPropSet::FillToItemSet( SfxItemSet
& rItemSet
) const
4029 if( mxMemStrm
.get() )
4030 maDffManager
.ApplyAttributes( *mxMemStrm
, rItemSet
);
4033 XclImpStream
& operator>>( XclImpStream
& rStrm
, XclImpDffPropSet
& rPropSet
)
4035 rPropSet
.Read( rStrm
);
4039 // ============================================================================