update ooo310-m15
[ooovba.git] / sc / source / filter / excel / xiescher.cxx
blob5eb246e35744fcdb3675d59d1c93e121c17ae74d
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 // ============================================================================
156 namespace {
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 >
161 class TSdrObjectPtr
163 public:
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; }
182 private:
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 ); }
188 private:
189 SdrObjType* mpObj;
192 typedef TSdrObjectPtr< SdrObject > SdrObjectPtr;
194 } // namespace
196 // Drawing objects ============================================================
198 XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) :
199 XclImpRoot( rRoot ),
200 maObjId( rRoot.GetCurrScTab(), EXC_OBJ_INVALID_ID ),
201 mnObjType( EXC_OBJTYPE_UNKNOWN ),
202 mnDffShapeId( 0 ),
203 mnDffFlags( 0 ),
204 mbHidden( false ),
205 mbVisible( true ),
206 mbPrintable( true ),
207 mbAreaObj( false ),
208 mbAutoMargin( true ),
209 mbSimpleMacro( true ),
210 mbProcessSdr( true ),
211 mbInsertSdr( true ),
212 mbCustomDff( false )
216 XclImpDrawObjBase::~XclImpDrawObjBase()
220 XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( XclImpStream& rStrm )
222 const XclImpRoot& rRoot = rStrm.GetRoot();
223 XclImpDrawObjRef xDrawObj;
225 if( rStrm.GetRecLeft() >= 30 )
227 sal_uInt16 nObjType;
228 rStrm.Ignore( 4 );
229 rStrm >> nObjType;
230 switch( nObjType )
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;
241 default:
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 );
249 return xDrawObj;
252 XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( XclImpStream& rStrm )
254 const XclImpRoot& rRoot = rStrm.GetRoot();
255 XclImpDrawObjRef xDrawObj;
257 if( rStrm.GetRecLeft() >= 30 )
259 sal_uInt16 nObjType;
260 rStrm.Ignore( 4 );
261 rStrm >> nObjType;
262 switch( nObjType )
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;
274 default:
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 );
282 return xDrawObj;
285 XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( XclImpStream& rStrm )
287 const XclImpRoot& rRoot = rStrm.GetRoot();
288 XclImpDrawObjRef xDrawObj;
290 if( rStrm.GetRecLeft() >= 34 )
292 sal_uInt16 nObjType;
293 rStrm.Ignore( 4 );
294 rStrm >> nObjType;
295 switch( nObjType )
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;
317 default:
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 );
325 return xDrawObj;
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) )
340 switch( nObjType )
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 );
348 break;
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 ) );
357 break;
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;
375 default:
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 );
384 return xDrawObj;
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
410 not match. */
411 if ( sName.Len() == 0 )
412 sName = ( (maObjName.Len() > 0) ? maObjName : GetObjectManager().GetDefaultObjName( *this ) );
413 return sName;
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
419 return mbAreaObj ?
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 );
427 if( mxAnchor.is() )
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 );
439 return aScUsedArea;
442 Rectangle XclImpDrawObjBase::GetAnchorRect() const
444 Rectangle aAnchorRect;
445 if( mxAnchor.is() )
446 aAnchorRect = mxAnchor->GetRect( GetDoc(), MAP_100TH_MM );
447 return aAnchorRect;
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() );
462 else
464 xSdrObj.reset( DoCreateSdrObj( rAnchorRect, rProgress ) );
465 if( xSdrObj.is() )
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
483 if( mbAutoMargin )
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 )
511 maObjName.Erase();
512 if( nNameLen > 0 )
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 )
523 maMacroName.Erase();
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 )
531 maMacroName.Erase();
532 rStrm.Ignore( nMacroSize );
535 void XclImpDrawObjBase::ReadMacro5( XclImpStream& rStrm, sal_uInt16 nMacroSize )
537 maMacroName.Erase();
538 rStrm.Ignore( nMacroSize );
541 void XclImpDrawObjBase::ReadMacro8( XclImpStream& rStrm )
543 maMacroName.Erase();
544 if( rStrm.GetRecLeft() > 6 )
546 // macro is stored in a tNameXR token containing a link to a defined name
547 sal_uInt16 nFmlaSize;
548 rStrm >> nFmlaSize;
549 rStrm.Ignore( 4 );
550 DBG_ASSERT( nFmlaSize == 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" );
551 if( nFmlaSize == 7 )
553 sal_uInt8 nTokenId;
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 );
581 else
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 )
594 default:
595 case EXC_OBJ_LINE_SOLID:
596 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
597 break;
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 ) ) );
601 break;
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 ) ) );
605 break;
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 ) ) );
609 break;
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 ) ) );
613 break;
614 case EXC_OBJ_LINE_MEDTRANS:
615 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
616 rSdrObj.SetMergedItem( XLineTransparenceItem( 50 ) );
617 break;
618 case EXC_OBJ_LINE_DARKTRANS:
619 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
620 rSdrObj.SetMergedItem( XLineTransparenceItem( 25 ) );
621 break;
622 case EXC_OBJ_LINE_LIGHTTRANS:
623 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
624 rSdrObj.SetMergedItem( XLineTransparenceItem( 75 ) );
625 break;
626 case EXC_OBJ_LINE_NONE:
627 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_NONE ) );
628 break;
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 ) );
645 else
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 ) );
654 else
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 );
685 Bitmap aBitmap;
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 );
724 return aColor;
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 );
742 return aColor;
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
763 return 1;
766 SdrObject* XclImpDrawObjBase::DoCreateSdrObj( const Rectangle&, ScfProgressBar& rProgress ) const
768 rProgress.Progress( GetProgressSize() );
769 return 0;
772 void XclImpDrawObjBase::DoProcessSdrObj( SdrObject& /*rSdrObj*/ ) const
774 // trace if object is not printable
775 if( !IsPrintable() )
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)
785 rStrm.Seek( 4 );
786 rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize;
787 rStrm.Ignore( 2 );
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)
801 rStrm.Seek( 4 );
802 rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize;
803 rStrm.Ignore( 2 );
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)
818 rStrm.Seek( 4 );
819 rStrm >> mnObjType >> maObjId.mnObjId >> nObjFlags >> aAnchor >> nMacroSize;
820 rStrm.Ignore( 2 );
821 rStrm >> nNameLen;
822 rStrm.Ignore( 2 );
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 )
833 // back to beginning
834 rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
836 bool bLoop = true;
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() ) );
845 switch( nSubRecId )
847 case EXC_ID_OBJCMO:
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 );
855 break;
856 case EXC_ID_OBJMACRO:
857 ReadMacro8( rStrm );
858 break;
859 case EXC_ID_OBJEND:
860 bLoop = false;
861 break;
862 default:
863 DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
866 rStrm.PopPosition();
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;
884 rStrm.Ignore( 4 );
885 rStrm >> 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 )
902 if( !empty() )
903 if( XclImpGroupObj* pGroupObj = dynamic_cast< XclImpGroupObj* >( back().get() ) )
904 if( pGroupObj->TryInsert( xDrawObj ) )
905 return;
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) )
936 return false;
937 // insert into own list or into nested group
938 maChildren.InsertGrouped( xDrawObj );
939 return true;
942 void XclImpGroupObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
944 rStrm.Ignore( 4 );
945 rStrm >> mnFirstUngrouped;
946 rStrm.Ignore( 16 );
947 ReadMacro3( rStrm, nMacroSize );
950 void XclImpGroupObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
952 rStrm.Ignore( 4 );
953 rStrm >> mnFirstUngrouped;
954 rStrm.Ignore( 16 );
955 ReadMacro4( rStrm, nMacroSize );
958 void XclImpGroupObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
960 rStrm.Ignore( 4 );
961 rStrm >> mnFirstUngrouped;
962 rStrm.Ignore( 16 );
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 ),
986 mnArrows( 0 ),
987 mnStartPoint( EXC_OBJ_LINE_TL )
989 SetAreaObj( false );
992 void XclImpLineObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
994 rStrm >> maLineData >> mnArrows >> mnStartPoint;
995 rStrm.Ignore( 1 );
996 ReadMacro3( rStrm, nMacroSize );
999 void XclImpLineObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1001 rStrm >> maLineData >> mnArrows >> mnStartPoint;
1002 rStrm.Ignore( 1 );
1003 ReadMacro4( rStrm, nMacroSize );
1006 void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1008 rStrm >> maLineData >> mnArrows >> mnStartPoint;
1009 rStrm.Ignore( 1 );
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 )
1019 default:
1020 case EXC_OBJ_LINE_TL:
1021 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
1022 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
1023 break;
1024 case EXC_OBJ_LINE_TR:
1025 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
1026 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
1027 break;
1028 case EXC_OBJ_LINE_BR:
1029 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
1030 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
1031 break;
1032 case EXC_OBJ_LINE_BL:
1033 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
1034 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
1035 break;
1037 SdrObjectPtr xSdrObj( new SdrPathObj( OBJ_LINE, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) );
1038 ConvertLineStyle( *xSdrObj, maLineData );
1040 // line ends
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) )
1074 if( bFilled )
1076 aArrowPoly.append( EXC_ARROW_POINT( 0, 100 ) );
1077 aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
1078 aArrowPoly.append( EXC_ARROW_POINT( 100, 100 ) );
1080 else
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 );
1094 if( bLineStart )
1096 xSdrObj->SetMergedItem( XLineStartItem( EMPTY_STRING, aArrowPolyPoly ) );
1097 xSdrObj->SetMergedItem( XLineStartWidthItem( nWidth ) );
1098 xSdrObj->SetMergedItem( XLineStartCenterItem( FALSE ) );
1100 if( bLineEnd )
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 ),
1115 mnFrameFlags( 0 )
1117 SetAreaObj( true );
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;
1186 rStrm.Ignore( 1 );
1187 ReadMacro3( rStrm, nMacroSize );
1190 void XclImpArcObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1192 rStrm >> maFillData >> maLineData >> mnQuadrant;
1193 rStrm.Ignore( 1 );
1194 ReadMacro4( rStrm, nMacroSize );
1197 void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1199 rStrm >> maFillData >> maLineData >> mnQuadrant;
1200 rStrm.Ignore( 1 );
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;
1209 long nEndAngle = 0;
1210 switch( mnQuadrant )
1212 default:
1213 case EXC_OBJ_ARC_TR:
1214 nStartAngle = 0;
1215 nEndAngle = 9000;
1216 aNewRect.Left() -= rAnchorRect.GetWidth();
1217 aNewRect.Bottom() += rAnchorRect.GetHeight();
1218 break;
1219 case EXC_OBJ_ARC_TL:
1220 nStartAngle = 9000;
1221 nEndAngle = 18000;
1222 aNewRect.Right() += rAnchorRect.GetWidth();
1223 aNewRect.Bottom() += rAnchorRect.GetHeight();
1224 break;
1225 case EXC_OBJ_ARC_BL:
1226 nStartAngle = 18000;
1227 nEndAngle = 27000;
1228 aNewRect.Right() += rAnchorRect.GetWidth();
1229 aNewRect.Top() -= rAnchorRect.GetHeight();
1230 break;
1231 case EXC_OBJ_ARC_BR:
1232 nStartAngle = 27000;
1233 nEndAngle = 0;
1234 aNewRect.Left() -= rAnchorRect.GetWidth();
1235 aNewRect.Top() -= rAnchorRect.GetHeight();
1236 break;
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 ),
1250 mnPolyFlags( 0 ),
1251 mnPointCount( 0 )
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 )
1263 sal_uInt16 nX, nY;
1264 rStrm >> nX >> nY;
1265 maCoords.push_back( Point( nX, nY ) );
1270 void XclImpPolygonObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1272 ReadFrameData( rStrm );
1273 rStrm >> mnPolyFlags;
1274 rStrm.Ignore( 10 );
1275 rStrm >> mnPointCount;
1276 rStrm.Ignore( 8 );
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;
1285 rStrm.Ignore( 10 );
1286 rStrm >> mnPointCount;
1287 rStrm.Ignore( 8 );
1288 ReadName5( rStrm, nNameLen );
1289 ReadMacro5( rStrm, nMacroSize );
1290 ReadCoordList( rStrm );
1293 namespace {
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 ) );
1302 } // namespace
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 )
1329 mxString.reset();
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 )
1340 if( mxString.is() )
1341 mxString->ReadObjFormats( rStrm, maData.mnFormatSize );
1342 else
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
1399 // set text data
1400 if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) )
1402 if( maTextData.mxString.is() )
1404 if( maTextData.mxString->IsRich() )
1406 // rich text
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 );
1414 else
1416 // plain text
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 ),
1470 mbOwnTab( bOwnTab )
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;
1481 rStrm.Seek( 2 );
1482 rStrm >> 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 );
1488 if( mbOwnTab )
1489 FinalizeTabChart();
1491 else
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 );
1501 rStrm.Ignore( 18 );
1502 ReadMacro3( rStrm, nMacroSize );
1503 #if 0
1504 ReadChartSubStream( rStrm );
1505 #endif
1506 // set frame format from OBJ record, it is used if chart itself is transparent
1507 if( mxChart.is() )
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 );
1515 rStrm.Ignore( 18 );
1516 ReadMacro4( rStrm, nMacroSize );
1517 #if 0
1518 ReadChartSubStream( rStrm );
1519 #endif
1520 // set frame format from OBJ record, it is used if chart itself is transparent
1521 if( mxChart.is() )
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 );
1529 rStrm.Ignore( 18 );
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
1534 if( mxChart.is() )
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 );
1587 if( xPers.is() )
1588 xPers->storeOwn();
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 )
1619 nWidth -= 2000;
1620 nHeight -= 1000;
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 ),
1634 mnNoteFlags( 0 )
1636 SetSimpleMacro( false );
1637 // caption object will be created manually
1638 SetInsertSdrObj( false );
1641 void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags )
1643 maScPos = rScPos;
1644 mnNoteFlags = nNoteFlags;
1647 void XclImpNoteObj::DoProcessSdrObj( SdrObject& rSdrObj ) const
1649 SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj );
1650 if( pTextObj && maScPos.IsValid() )
1652 if( ScPostIt* pNote = GetDoc().GetOrCreateNote( maScPos ) )
1654 if( SdrCaptionObj* pCaption = pNote->GetCaption() )
1656 // create formatted text
1657 XclImpTextObj::DoProcessSdrObj( *pCaption );
1658 // set textbox rectangle from imported object
1659 pCaption->NbcSetLogicRect( pTextObj->GetLogicRect() );
1660 // copy all items from imported object (resets shadow items)
1661 pNote->SetCaptionItems( pTextObj->GetMergedItemSet() );
1662 // move caption to correct layer (visible/hidden)
1663 pNote->ShowCaption( ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ) );
1669 // ----------------------------------------------------------------------------
1671 XclImpControlHelper::XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode ) :
1672 mrRoot( rRoot ),
1673 meBindMode( eBindMode )
1677 XclImpControlHelper::~XclImpControlHelper()
1681 SdrObject* XclImpControlHelper::CreateSdrObjectFromShape(
1682 const Reference< XShape >& rxShape, const Rectangle& rAnchorRect ) const
1684 mxShape = rxShape;
1685 SdrObjectPtr xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape ) );
1686 if( xSdrObj.is() )
1688 xSdrObj->NbcSetSnapRect( rAnchorRect );
1689 // #i30543# insert into control layer
1690 xSdrObj->NbcSetLayer( SC_LAYER_CONTROLS );
1692 return xSdrObj.release();
1695 void XclImpControlHelper::ApplySheetLinkProps() const
1698 Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
1699 if( !xCtrlModel.is() )
1700 return;
1701 ScfPropertySet aPropSet( xCtrlModel );
1703 // sheet links
1704 if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
1706 Reference< XMultiServiceFactory > xFactory( pDocShell->GetModel(), UNO_QUERY );
1707 if( xFactory.is() )
1709 // cell link
1710 if( mxCellLink.is() ) try
1712 Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY_THROW );
1714 // create argument sequence for createInstanceWithArguments()
1715 CellAddress aApiAddress;
1716 ScUnoConversion::FillApiAddress( aApiAddress, *mxCellLink );
1718 NamedValue aValue;
1719 aValue.Name = CREATE_OUSTRING( SC_UNONAME_BOUNDCELL );
1720 aValue.Value <<= aApiAddress;
1722 Sequence< Any > aArgs( 1 );
1723 aArgs[ 0 ] <<= aValue;
1725 // create the CellValueBinding instance and set at the control model
1726 OUString aServiceName;
1727 switch( meBindMode )
1729 case EXC_CTRL_BINDCONTENT: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_VALBIND ); break;
1730 case EXC_CTRL_BINDPOSITION: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_LISTCELLBIND ); break;
1732 Reference< XValueBinding > xBinding(
1733 xFactory->createInstanceWithArguments( aServiceName, aArgs ), UNO_QUERY_THROW );
1734 xBindable->setValueBinding( xBinding );
1736 catch( const Exception& )
1740 // source range
1741 if( mxSrcRange.is() ) try
1743 Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY_THROW );
1745 // create argument sequence for createInstanceWithArguments()
1746 CellRangeAddress aApiRange;
1747 ScUnoConversion::FillApiRange( aApiRange, *mxSrcRange );
1749 NamedValue aValue;
1750 aValue.Name = CREATE_OUSTRING( SC_UNONAME_CELLRANGE );
1751 aValue.Value <<= aApiRange;
1753 Sequence< Any > aArgs( 1 );
1754 aArgs[ 0 ] <<= aValue;
1756 // create the EntrySource instance and set at the control model
1757 Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
1758 CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ), aArgs ), UNO_QUERY_THROW );
1759 xEntrySink->setListEntrySource( xEntrySource );
1761 catch( const Exception& )
1768 void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) const
1770 Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
1771 if( !xCtrlModel.is() )
1772 return;
1774 ApplySheetLinkProps();
1776 ScfPropertySet aPropSet( xCtrlModel );
1778 // #118053# #i51348# set object name at control model
1779 aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() );
1781 // control visible and printable?
1782 aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );
1783 aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() );
1786 // virtual call for type specific processing
1787 DoProcessControl( aPropSet );
1790 void XclImpControlHelper::ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize )
1792 ScRangeList aScRanges;
1793 ReadRangeList( aScRanges, rStrm, bWithBoundSize );
1794 // Use first cell of first range
1795 if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
1796 mxCellLink.reset( new ScAddress( pScRange->aStart ) );
1799 void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize )
1801 ScRangeList aScRanges;
1802 ReadRangeList( aScRanges, rStrm, bWithBoundSize );
1803 // Use first range
1804 if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
1805 mxSrcRange.reset( new ScRange( *pScRange ) );
1808 void XclImpControlHelper::DoProcessControl( ScfPropertySet& ) const
1812 void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm )
1814 XclTokenArray aXclTokArr;
1815 aXclTokArr.ReadSize( rStrm );
1816 rStrm.Ignore( 4 );
1817 aXclTokArr.ReadArray( rStrm );
1818 mrRoot.GetFormulaCompiler().CreateRangeList( rScRanges, EXC_FMLATYPE_CONTROL, aXclTokArr, rStrm );
1821 void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize )
1823 if( bWithBoundSize )
1825 sal_uInt16 nSize;
1826 rStrm >> nSize;
1827 if( nSize > 0 )
1829 rStrm.PushPosition();
1830 ReadRangeList( rScRanges, rStrm );
1831 rStrm.PopPosition();
1832 rStrm.Ignore( nSize );
1835 else
1837 ReadRangeList( rScRanges, rStrm );
1841 // ----------------------------------------------------------------------------
1843 XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot& rRoot ) :
1844 XclImpTextObj( rRoot ),
1845 XclImpControlHelper( rRoot, EXC_CTRL_BINDPOSITION )
1847 SetSimpleMacro( false );
1848 SetCustomDffObj( true );
1851 namespace {
1853 void lclExtractColor( sal_uInt8& rnColorIdx, const DffPropSet& rDffPropSet, sal_uInt32 nPropId )
1855 if( rDffPropSet.IsProperty( nPropId ) )
1857 sal_uInt32 nColor = rDffPropSet.GetPropertyValue( nPropId );
1858 if( (nColor & 0xFF000000) == 0x08000000 )
1859 rnColorIdx = ::extract_value< sal_uInt8 >( nColor, 0, 8 );
1863 } // namespace
1865 void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet )
1867 maFillData.mnPattern = rDffPropSet.GetPropertyBool( DFF_Prop_fFilled ) ? EXC_PATT_SOLID : EXC_PATT_NONE;
1868 lclExtractColor( maFillData.mnBackColorIdx, rDffPropSet, DFF_Prop_fillBackColor );
1869 lclExtractColor( maFillData.mnPattColorIdx, rDffPropSet, DFF_Prop_fillColor );
1870 ::set_flag( maFillData.mnAuto, EXC_OBJ_LINE_AUTO, false );
1872 maLineData.mnStyle = rDffPropSet.GetPropertyBool( DFF_Prop_fLine ) ? EXC_OBJ_LINE_SOLID : EXC_OBJ_LINE_NONE;
1873 lclExtractColor( maLineData.mnColorIdx, rDffPropSet, DFF_Prop_lineColor );
1874 ::set_flag( maLineData.mnAuto, EXC_OBJ_FILL_AUTO, false );
1877 bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const
1879 return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() );
1882 void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const
1884 if( maTextData.mxString.is() )
1886 const XclFormatRunVec& rFormatRuns = maTextData.mxString->GetFormats();
1887 if( rFormatRuns.empty() )
1888 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
1889 else
1890 GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, rFormatRuns.front().mnFontIdx );
1894 void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const
1896 if( maTextData.mxString.is() )
1898 String aLabel = maTextData.mxString->GetText();
1899 if( maTextData.maData.mnShortcut > 0 )
1901 xub_StrLen nPos = aLabel.Search( static_cast< sal_Unicode >( maTextData.maData.mnShortcut ) );
1902 if( nPos != STRING_NOTFOUND )
1903 aLabel.Insert( '~', nPos );
1905 rPropSet.SetStringProperty( CREATE_OUSTRING( "Label" ), aLabel );
1907 ConvertFont( rPropSet );
1910 SdrObject* XclImpTbxObjBase::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const
1912 SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) );
1913 rProgress.Progress();
1914 return xSdrObj.release();
1917 void XclImpTbxObjBase::DoProcessSdrObj( SdrObject& /*rSdrObj*/ ) const
1919 // do not call DoProcessSdrObj() from base class (to skip text processing)
1920 ProcessControl( *this );
1923 // ----------------------------------------------------------------------------
1925 XclImpButtonObj::XclImpButtonObj( const XclImpRoot& rRoot ) :
1926 XclImpTbxObjBase( rRoot )
1930 void XclImpButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
1932 // label and text formatting
1933 ConvertLabel( rPropSet );
1935 /* Horizontal text alignment. For unknown reason, the property type is a
1936 simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
1937 sal_Int16 nHorAlign = 1;
1938 switch( maTextData.maData.GetHorAlign() )
1940 case EXC_OBJ_HOR_LEFT: nHorAlign = 0; break;
1941 case EXC_OBJ_HOR_CENTER: nHorAlign = 1; break;
1942 case EXC_OBJ_HOR_RIGHT: nHorAlign = 2; break;
1944 rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), nHorAlign );
1946 // vertical text alignment
1947 namespace csss = ::com::sun::star::style;
1948 csss::VerticalAlignment eVerAlign = csss::VerticalAlignment_MIDDLE;
1949 switch( maTextData.maData.GetVerAlign() )
1951 case EXC_OBJ_VER_TOP: eVerAlign = csss::VerticalAlignment_TOP; break;
1952 case EXC_OBJ_VER_CENTER: eVerAlign = csss::VerticalAlignment_MIDDLE; break;
1953 case EXC_OBJ_VER_BOTTOM: eVerAlign = csss::VerticalAlignment_BOTTOM; break;
1955 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), eVerAlign );
1957 // always wrap text automatically
1958 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
1960 // default button
1961 bool bDefButton = ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_DEFAULT );
1962 rPropSet.SetBoolProperty( CREATE_OUSTRING( "DefaultButton" ), bDefButton );
1964 // button type (flags cannot be combined in OOo)
1965 namespace cssa = ::com::sun::star::awt;
1966 cssa::PushButtonType eButtonType = cssa::PushButtonType_STANDARD;
1967 if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CLOSE ) )
1968 eButtonType = cssa::PushButtonType_OK;
1969 else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CANCEL ) )
1970 eButtonType = cssa::PushButtonType_CANCEL;
1971 else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_HELP ) )
1972 eButtonType = cssa::PushButtonType_HELP;
1973 // property type is short, not enum
1974 rPropSet.SetProperty( CREATE_OUSTRING( "PushButtonType" ), sal_Int16( eButtonType ) );
1977 OUString XclImpButtonObj::DoGetServiceName() const
1979 return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" );
1982 XclTbxEventType XclImpButtonObj::DoGetEventType() const
1984 return EXC_TBX_EVENT_ACTION;
1987 // ----------------------------------------------------------------------------
1989 XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot& rRoot ) :
1990 XclImpTbxObjBase( rRoot ),
1991 mnState( EXC_OBJ_CHECKBOX_UNCHECKED ),
1992 mnCheckBoxFlags( 0 )
1996 void XclImpCheckBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
1998 ReadFrameData( rStrm );
1999 rStrm.Ignore( 10 );
2000 rStrm >> maTextData.maData.mnFlags;
2001 rStrm.Ignore( 20 );
2002 ReadName5( rStrm, nNameLen );
2003 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2004 ReadCellLinkFormula( rStrm, true );
2005 rStrm >> maTextData.maData.mnTextLen;
2006 maTextData.ReadByteString( rStrm );
2007 rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
2010 void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2012 switch( nSubRecId )
2014 case EXC_ID_OBJCBLS:
2015 // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
2016 rStrm >> mnState;
2017 rStrm.Ignore( 4 );
2018 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
2019 break;
2020 case EXC_ID_OBJCBLSFMLA:
2021 ReadCellLinkFormula( rStrm, false );
2022 break;
2023 default:
2024 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2028 void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2030 // label and text formatting
2031 ConvertLabel( rPropSet );
2033 // state
2034 bool bSupportsTristate = GetObjType() == EXC_OBJTYPE_CHECKBOX;
2035 sal_Int16 nApiState = 0;
2036 switch( mnState )
2038 case EXC_OBJ_CHECKBOX_UNCHECKED: nApiState = 0; break;
2039 case EXC_OBJ_CHECKBOX_CHECKED: nApiState = 1; break;
2040 case EXC_OBJ_CHECKBOX_TRISTATE: nApiState = bSupportsTristate ? 2 : 1; break;
2042 if( bSupportsTristate )
2043 rPropSet.SetBoolProperty( CREATE_OUSTRING( "TriState" ), nApiState == 2 );
2044 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultState" ), nApiState );
2046 // box style
2047 namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2048 sal_Int16 nEffect = ::get_flagvalue( mnCheckBoxFlags, EXC_OBJ_CHECKBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2049 rPropSet.SetProperty( CREATE_OUSTRING( "VisualEffect" ), nEffect );
2051 // do not wrap text automatically
2052 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), false );
2054 // #i40279# always centered vertically
2055 namespace csss = ::com::sun::star::style;
2056 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_MIDDLE );
2058 // background color
2059 if( maFillData.IsFilled() )
2061 sal_Int32 nColor = static_cast< sal_Int32 >( GetSolidFillColor( maFillData ).GetColor() );
2062 rPropSet.SetProperty( CREATE_OUSTRING( "BackgroundColor" ), nColor );
2066 OUString XclImpCheckBoxObj::DoGetServiceName() const
2068 return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" );
2071 XclTbxEventType XclImpCheckBoxObj::DoGetEventType() const
2073 return EXC_TBX_EVENT_ACTION;
2076 // ----------------------------------------------------------------------------
2078 XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot& rRoot ) :
2079 XclImpCheckBoxObj( rRoot ),
2080 mnNextInGroup( 0 ),
2081 mnFirstInGroup( 1 )
2085 void XclImpOptionButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2087 ReadFrameData( rStrm );
2088 rStrm.Ignore( 10 );
2089 rStrm >> maTextData.maData.mnFlags;
2090 rStrm.Ignore( 32 );
2091 ReadName5( rStrm, nNameLen );
2092 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2093 ReadCellLinkFormula( rStrm, true );
2094 rStrm >> maTextData.maData.mnTextLen;
2095 maTextData.ReadByteString( rStrm );
2096 rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA;
2097 rStrm >> mnCheckBoxFlags >> mnNextInGroup >> mnFirstInGroup;
2100 void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2102 switch( nSubRecId )
2104 case EXC_ID_OBJRBODATA:
2105 rStrm >> mnNextInGroup >> mnFirstInGroup;
2106 break;
2107 default:
2108 XclImpCheckBoxObj::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2112 void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2114 XclImpCheckBoxObj::DoProcessControl( rPropSet );
2115 // TODO: grouping
2116 XclImpOptionButtonObj* pTbxObj = dynamic_cast< XclImpOptionButtonObj* >( GetObjectManager().FindDrawObj( XclObjId( GetScTab(), mnNextInGroup ) ).get() );
2117 if ( ( pTbxObj && pTbxObj->mnFirstInGroup ) )
2119 // Group has terminated
2120 // traverse each RadioButton in group and
2121 // a) apply the groupname
2122 // b) propagate the linked cell from the lead radiobutton
2123 // c) apply the correct Ref value
2124 XclImpOptionButtonObj* pLeader = pTbxObj;
2126 sal_Int32 nRefVal = 1;
2127 OSL_TRACE( "0x%x start group ", pLeader->GetObjId().mnObjId );
2131 Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( pTbxObj->mxShape );
2132 if ( xCtrlModel.is() )
2134 ScfPropertySet aProps( xCtrlModel );
2135 rtl::OUString sGroupName = rtl::OUString::valueOf( static_cast< sal_Int32 >( pLeader->GetDffShapeId() ) );
2137 aProps.SetStringProperty( CREATE_OUSTRING( "GroupName" ), sGroupName );
2138 aProps.SetStringProperty( CREATE_OUSTRING( "RefValue" ), rtl::OUString::valueOf( nRefVal++ ) );
2139 if ( pLeader->HasCellLink() && !pTbxObj->HasCellLink() )
2141 // propagate cell link info
2142 pTbxObj->mxCellLink.reset( new ScAddress( *pLeader->mxCellLink.get() ) );
2143 pTbxObj->ApplySheetLinkProps();
2145 pTbxObj = dynamic_cast< XclImpOptionButtonObj* >( GetObjectManager().FindDrawObj( XclObjId( GetScTab(), pTbxObj->mnNextInGroup ) ).get() );
2147 else
2148 pTbxObj = NULL;
2149 } while ( pTbxObj && !( pTbxObj->mnFirstInGroup == 1 ) );
2151 else
2153 // not the leader? try and find it
2157 OUString XclImpOptionButtonObj::DoGetServiceName() const
2159 return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
2162 XclTbxEventType XclImpOptionButtonObj::DoGetEventType() const
2164 return EXC_TBX_EVENT_ACTION;
2167 // ----------------------------------------------------------------------------
2169 XclImpLabelObj::XclImpLabelObj( const XclImpRoot& rRoot ) :
2170 XclImpTbxObjBase( rRoot )
2174 void XclImpLabelObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2176 // label and text formatting
2177 ConvertLabel( rPropSet );
2179 // text alignment (always top/left aligned)
2180 rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), sal_Int16( 0 ) );
2181 namespace csss = ::com::sun::star::style;
2182 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_TOP );
2184 // always wrap text automatically
2185 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
2188 OUString XclImpLabelObj::DoGetServiceName() const
2190 return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" );
2193 XclTbxEventType XclImpLabelObj::DoGetEventType() const
2195 return EXC_TBX_EVENT_MOUSE;
2198 // ----------------------------------------------------------------------------
2200 XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot& rRoot ) :
2201 XclImpTbxObjBase( rRoot ),
2202 mnGroupBoxFlags( 0 )
2206 void XclImpGroupBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2208 ReadFrameData( rStrm );
2209 rStrm.Ignore( 10 );
2210 rStrm >> maTextData.maData.mnFlags;
2211 rStrm.Ignore( 26 );
2212 ReadName5( rStrm, nNameLen );
2213 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2214 rStrm >> maTextData.maData.mnTextLen;
2215 maTextData.ReadByteString( rStrm );
2216 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
2219 void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2221 switch( nSubRecId )
2223 case EXC_ID_OBJGBODATA:
2224 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
2225 break;
2226 default:
2227 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2231 void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2233 // label and text formatting
2234 ConvertLabel( rPropSet );
2237 OUString XclImpGroupBoxObj::DoGetServiceName() const
2239 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2242 XclTbxEventType XclImpGroupBoxObj::DoGetEventType() const
2244 return EXC_TBX_EVENT_MOUSE;
2247 // ----------------------------------------------------------------------------
2249 XclImpDialogObj::XclImpDialogObj( const XclImpRoot& rRoot ) :
2250 XclImpTbxObjBase( rRoot )
2254 void XclImpDialogObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2256 // label and text formatting
2257 ConvertLabel( rPropSet );
2260 OUString XclImpDialogObj::DoGetServiceName() const
2262 // dialog frame faked by a groupbox
2263 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2266 XclTbxEventType XclImpDialogObj::DoGetEventType() const
2268 return EXC_TBX_EVENT_MOUSE;
2271 // ----------------------------------------------------------------------------
2273 XclImpEditObj::XclImpEditObj( const XclImpRoot& rRoot ) :
2274 XclImpTbxObjBase( rRoot ),
2275 mnContentType( EXC_OBJ_EDIT_TEXT ),
2276 mnMultiLine( 0 ),
2277 mnScrollBar( 0 ),
2278 mnListBoxObjId( 0 )
2282 bool XclImpEditObj::IsNumeric() const
2284 return (mnContentType == EXC_OBJ_EDIT_INTEGER) || (mnContentType == EXC_OBJ_EDIT_DOUBLE);
2287 void XclImpEditObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2289 ReadFrameData( rStrm );
2290 rStrm.Ignore( 10 );
2291 rStrm >> maTextData.maData.mnFlags;
2292 rStrm.Ignore( 14 );
2293 ReadName5( rStrm, nNameLen );
2294 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2295 rStrm >> maTextData.maData.mnTextLen;
2296 maTextData.ReadByteString( rStrm );
2297 rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
2300 void XclImpEditObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2302 switch( nSubRecId )
2304 case EXC_ID_OBJEDODATA:
2305 rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
2306 break;
2307 default:
2308 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2312 void XclImpEditObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2314 if( maTextData.mxString.is() )
2316 OUString aText = maTextData.mxString->GetText();
2317 if( IsNumeric() )
2319 // TODO: OUString::toDouble() does not handle local decimal separator
2320 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultValue" ), aText.toDouble() );
2321 rPropSet.SetBoolProperty( CREATE_OUSTRING( "Spin" ), mnScrollBar != 0 );
2323 else
2325 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultText" ), aText );
2326 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), mnMultiLine != 0 );
2327 rPropSet.SetBoolProperty( CREATE_OUSTRING( "VScroll" ), mnScrollBar != 0 );
2330 ConvertFont( rPropSet );
2333 OUString XclImpEditObj::DoGetServiceName() const
2335 return IsNumeric() ?
2336 CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ) :
2337 CREATE_OUSTRING( "com.sun.star.form.component.TextField" );
2340 XclTbxEventType XclImpEditObj::DoGetEventType() const
2342 return EXC_TBX_EVENT_TEXT;
2345 // ----------------------------------------------------------------------------
2347 XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot& rRoot ) :
2348 XclImpTbxObjBase( rRoot ),
2349 mnValue( 0 ),
2350 mnMin( 0 ),
2351 mnMax( 100 ),
2352 mnStep( 1 ),
2353 mnPageStep( 10 ),
2354 mnOrient( 0 ),
2355 mnThumbWidth( 1 ),
2356 mnScrollFlags( 0 )
2360 void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream& rStrm )
2362 rStrm.Ignore( 4 );
2363 rStrm >> mnValue >> mnMin >> mnMax >> mnStep >> mnPageStep >> mnOrient >> mnThumbWidth >> mnScrollFlags;
2366 void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2368 switch( nSubRecId )
2370 case EXC_ID_OBJSBS:
2371 ReadSbs( rStrm );
2372 break;
2373 case EXC_ID_OBJSBSFMLA:
2374 ReadCellLinkFormula( rStrm, false );
2375 break;
2376 default:
2377 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2381 // ----------------------------------------------------------------------------
2383 XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot& rRoot ) :
2384 XclImpTbxObjScrollableBase( rRoot )
2388 void XclImpSpinButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2390 ReadFrameData( rStrm );
2391 ReadSbs( rStrm );
2392 ReadName5( rStrm, nNameLen );
2393 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2394 ReadCellLinkFormula( rStrm, true );
2397 void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2399 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2400 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
2401 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultSpinValue" ), mnValue );
2402 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMin" ), mnMin );
2403 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMax" ), mnMax );
2404 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinIncrement" ), mnStep );
2406 // Excel spin buttons always vertical
2407 rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), ::com::sun::star::awt::ScrollBarOrientation::VERTICAL );
2410 OUString XclImpSpinButtonObj::DoGetServiceName() const
2412 return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
2415 XclTbxEventType XclImpSpinButtonObj::DoGetEventType() const
2417 return EXC_TBX_EVENT_VALUE;
2420 // ----------------------------------------------------------------------------
2422 XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot& rRoot ) :
2423 XclImpTbxObjScrollableBase( rRoot )
2427 void XclImpScrollBarObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2429 ReadFrameData( rStrm );
2430 ReadSbs( rStrm );
2431 ReadName5( rStrm, nNameLen );
2432 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2433 ReadCellLinkFormula( rStrm, true );
2436 void XclImpScrollBarObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2438 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2439 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
2440 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultScrollValue" ), mnValue );
2441 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMin" ), mnMin );
2442 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMax" ), mnMax );
2443 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "LineIncrement" ), mnStep );
2444 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BlockIncrement" ), mnPageStep );
2445 rPropSet.SetProperty( CREATE_OUSTRING( "VisibleSize" ), ::std::min< sal_Int32 >( mnPageStep, 1 ) );
2447 namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
2448 sal_Int32 nApiOrient = ::get_flagvalue( mnOrient, EXC_OBJ_SCROLLBAR_HOR, AwtScrollOrient::HORIZONTAL, AwtScrollOrient::VERTICAL );
2449 rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), nApiOrient );
2452 OUString XclImpScrollBarObj::DoGetServiceName() const
2454 return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
2457 XclTbxEventType XclImpScrollBarObj::DoGetEventType() const
2459 return EXC_TBX_EVENT_VALUE;
2462 // ----------------------------------------------------------------------------
2464 XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot& rRoot ) :
2465 XclImpTbxObjScrollableBase( rRoot ),
2466 mnEntryCount( 0 ),
2467 mnSelEntry( 0 ),
2468 mnListFlags( 0 ),
2469 mnEditObjId( 0 ),
2470 mbHasDefFontIdx( false )
2474 void XclImpTbxObjListBase::ReadLbsData( XclImpStream& rStrm )
2476 ReadSourceRangeFormula( rStrm, true );
2477 rStrm >> mnEntryCount >> mnSelEntry >> mnListFlags >> mnEditObjId;
2480 void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet& rPropSet ) const
2482 // border style
2483 namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2484 sal_Int16 nApiBorder = ::get_flagvalue( mnListFlags, EXC_OBJ_LISTBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2485 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), nApiBorder );
2487 // font formatting
2488 if( mbHasDefFontIdx )
2489 GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, maTextData.maData.mnDefFontIdx );
2490 else
2491 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
2494 // ----------------------------------------------------------------------------
2496 XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot& rRoot ) :
2497 XclImpTbxObjListBase( rRoot )
2501 void XclImpListBoxObj::ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft )
2503 sal_Size nRecEnd = rStrm.GetRecPos() + nRecLeft;
2504 ReadLbsData( rStrm );
2505 DBG_ASSERT( (rStrm.GetRecPos() == nRecEnd) || (rStrm.GetRecPos() + mnEntryCount == nRecEnd),
2506 "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
2507 while( rStrm.IsValid() && (rStrm.GetRecPos() < nRecEnd) )
2508 maSelection.push_back( rStrm.ReaduInt8() );
2511 void XclImpListBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2513 ReadFrameData( rStrm );
2514 ReadSbs( rStrm );
2515 rStrm.Ignore( 18 );
2516 rStrm >> maTextData.maData.mnDefFontIdx;
2517 rStrm.Ignore( 4 );
2518 ReadName5( rStrm, nNameLen );
2519 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2520 ReadCellLinkFormula( rStrm, true );
2521 ReadFullLbsData( rStrm, rStrm.GetRecLeft() );
2522 mbHasDefFontIdx = true;
2525 void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2527 switch( nSubRecId )
2529 case EXC_ID_OBJLBSDATA:
2530 ReadFullLbsData( rStrm, nSubRecSize );
2531 break;
2532 default:
2533 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2537 void XclImpListBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2539 // listbox formatting
2540 SetBoxFormatting( rPropSet );
2542 // selection type
2543 sal_uInt8 nSelType = ::extract_value< sal_uInt8 >( mnListFlags, 4, 2 );
2544 bool bMultiSel = nSelType != EXC_OBJ_LISTBOX_SINGLE;
2545 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiSelection" ), bMultiSel );
2547 // selection (do not set, if listbox is linked to a cell)
2548 if( !HasCellLink() )
2550 ScfInt16Vec aSelVec;
2552 // multi selection: API expects sequence of list entry indexes
2553 if( bMultiSel )
2554 for( ScfUInt8Vec::const_iterator aBeg = maSelection.begin(), aIt = aBeg, aEnd = maSelection.end(); aIt != aEnd; ++aIt )
2555 if( *aIt != 0 )
2556 aSelVec.push_back( static_cast< sal_Int16 >( aIt - aBeg ) );
2557 // single selection: mnSelEntry is one-based, API expects zero-based
2558 else if( mnSelEntry > 0 )
2559 aSelVec.push_back( static_cast< sal_Int16 >( mnSelEntry - 1 ) );
2561 if( !aSelVec.empty() )
2563 Sequence< sal_Int16 > aSelSeq( &aSelVec.front(), static_cast< sal_Int32 >( aSelVec.size() ) );
2564 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
2569 OUString XclImpListBoxObj::DoGetServiceName() const
2571 return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2574 XclTbxEventType XclImpListBoxObj::DoGetEventType() const
2576 return EXC_TBX_EVENT_CHANGE;
2579 // ----------------------------------------------------------------------------
2581 XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot& rRoot ) :
2582 XclImpTbxObjListBase( rRoot ),
2583 mnLeft( 0 ),
2584 mnTop( 0 ),
2585 mnRight( 0 ),
2586 mnBottom( 0 ),
2587 mnDropDownFlags( 0 ),
2588 mnLineCount( 0 ),
2589 mnMinWidth( 0 )
2593 sal_uInt16 XclImpDropDownObj::GetDropDownType() const
2595 return ::extract_value< sal_uInt8 >( mnDropDownFlags, 0, 2 );
2598 void XclImpDropDownObj::ReadFullLbsData( XclImpStream& rStrm )
2600 ReadLbsData( rStrm );
2601 rStrm >> mnDropDownFlags >> mnLineCount >> mnMinWidth >> maTextData.maData.mnTextLen;
2602 maTextData.ReadByteString( rStrm );
2603 // dropdowns of auto-filters have 'simple' style, they don't have a text area
2604 if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE )
2605 SetProcessSdrObj( false );
2608 void XclImpDropDownObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2610 ReadFrameData( rStrm );
2611 ReadSbs( rStrm );
2612 rStrm.Ignore( 18 );
2613 rStrm >> maTextData.maData.mnDefFontIdx;
2614 rStrm.Ignore( 14 );
2615 rStrm >> mnLeft >> mnTop >> mnRight >> mnBottom;
2616 rStrm.Ignore( 4 );
2617 ReadName5( rStrm, nNameLen );
2618 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2619 ReadCellLinkFormula( rStrm, true );
2620 ReadFullLbsData( rStrm );
2621 mbHasDefFontIdx = true;
2624 void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2626 switch( nSubRecId )
2628 case EXC_ID_OBJLBSDATA:
2629 ReadFullLbsData( rStrm );
2630 break;
2631 default:
2632 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2636 void XclImpDropDownObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2638 // dropdown listbox formatting
2639 SetBoxFormatting( rPropSet );
2640 // enable dropdown button
2641 rPropSet.SetBoolProperty( CREATE_OUSTRING( "Dropdown" ), true );
2642 // dropdown line count
2643 rPropSet.SetProperty( CREATE_OUSTRING( "LineCount" ), mnLineCount );
2645 if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX )
2647 // text of editable combobox
2648 if( maTextData.mxString.is() )
2649 rPropSet.SetStringProperty( CREATE_OUSTRING( "DefaultText" ), maTextData.mxString->GetText() );
2651 else
2653 // selection (do not set, if dropdown is linked to a cell)
2654 if( !HasCellLink() && (mnSelEntry > 0) )
2656 Sequence< sal_Int16 > aSelSeq( 1 );
2657 aSelSeq[ 0 ] = mnSelEntry - 1;
2658 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
2663 OUString XclImpDropDownObj::DoGetServiceName() const
2665 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ?
2666 CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ) :
2667 CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2670 XclTbxEventType XclImpDropDownObj::DoGetEventType() const
2672 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ? EXC_TBX_EVENT_TEXT : EXC_TBX_EVENT_CHANGE;
2675 // ----------------------------------------------------------------------------
2677 XclImpPictureObj::XclImpPictureObj( const XclImpRoot& rRoot ) :
2678 XclImpRectObj( rRoot ),
2679 XclImpControlHelper( rRoot, EXC_CTRL_BINDCONTENT ),
2680 mnStorageId( 0 ),
2681 mnCtlsStrmPos( 0 ),
2682 mnCtlsStrmSize( 0 ),
2683 mbEmbedded( false ),
2684 mbLinked( false ),
2685 mbSymbol( false ),
2686 mbControl( false ),
2687 mbUseCtlsStrm( false )
2689 SetAreaObj( true );
2690 SetSimpleMacro( false );
2691 SetCustomDffObj( true );
2694 String XclImpPictureObj::GetOleStorageName() const
2696 String aStrgName;
2697 if( (mbEmbedded || mbLinked) && !mbControl && (mnStorageId > 0) )
2699 aStrgName = mbEmbedded ? EXC_STORAGE_OLE_EMBEDDED : EXC_STORAGE_OLE_LINKED;
2700 static const sal_Char spcHexChars[] = "0123456789ABCDEF";
2701 for( sal_uInt8 nIndex = 32; nIndex > 0; nIndex -= 4 )
2702 aStrgName.Append( sal_Unicode( spcHexChars[ ::extract_value< sal_uInt8 >( mnStorageId, nIndex - 4, 4 ) ] ) );
2704 return aStrgName;
2707 void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2709 sal_uInt16 nLinkSize;
2710 ReadFrameData( rStrm );
2711 rStrm.Ignore( 6 );
2712 rStrm >> nLinkSize;
2713 rStrm.Ignore( 2 );
2714 ReadFlags3( rStrm );
2715 ReadMacro3( rStrm, nMacroSize );
2716 ReadPictFmla( rStrm, nLinkSize );
2718 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2719 maGraphic = XclImpObjectManager::ReadImgData( rStrm );
2722 void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2724 sal_uInt16 nLinkSize;
2725 ReadFrameData( rStrm );
2726 rStrm.Ignore( 6 );
2727 rStrm >> nLinkSize;
2728 rStrm.Ignore( 2 );
2729 ReadFlags3( rStrm );
2730 ReadMacro4( rStrm, nMacroSize );
2731 ReadPictFmla( rStrm, nLinkSize );
2733 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2734 maGraphic = XclImpObjectManager::ReadImgData( rStrm );
2737 void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
2739 sal_uInt16 nLinkSize;
2740 ReadFrameData( rStrm );
2741 rStrm.Ignore( 6 );
2742 rStrm >> nLinkSize;
2743 rStrm.Ignore( 2 );
2744 ReadFlags3( rStrm );
2745 rStrm.Ignore( 4 );
2746 ReadName5( rStrm, nNameLen );
2747 ReadMacro5( rStrm, nMacroSize );
2748 ReadPictFmla( rStrm, nLinkSize );
2750 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2752 // page background is stored as hidden picture with name "__BkgndObj"
2753 if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) )
2754 GetPageSettings().ReadImgData( rStrm );
2755 else
2756 maGraphic = XclImpObjectManager::ReadImgData( rStrm );
2760 void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2762 switch( nSubRecId )
2764 case EXC_ID_OBJFLAGS:
2765 ReadFlags8( rStrm );
2766 break;
2767 case EXC_ID_OBJPICTFMLA:
2768 ReadPictFmla( rStrm, rStrm.ReaduInt16() );
2769 break;
2770 default:
2771 XclImpDrawObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2775 SdrObject* XclImpPictureObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const
2777 // try to create an OLE object or form control
2778 SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) );
2780 // no OLE - create a plain picture from IMGDATA record data
2781 if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) )
2783 xSdrObj.reset( new SdrGrafObj( maGraphic, rAnchorRect ) );
2784 ConvertRectStyle( *xSdrObj );
2787 rProgress.Progress();
2788 return xSdrObj.release();
2791 void XclImpPictureObj::DoProcessSdrObj( SdrObject& rSdrObj ) const
2793 if( IsOcxControl() )
2795 // do not call XclImpRectObj::DoProcessSdrObj(), it would trace missing "printable" feature
2796 ProcessControl( *this );
2798 else if( mbEmbedded || mbLinked )
2800 // trace missing "printable" feature
2801 XclImpRectObj::DoProcessSdrObj( rSdrObj );
2803 SfxObjectShell* pDocShell = GetDocShell();
2804 SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj );
2805 if( pOleSdrObj && pDocShell )
2807 comphelper::EmbeddedObjectContainer& rEmbObjCont = pDocShell->GetEmbeddedObjectContainer();
2808 Reference< XEmbeddedObject > xEmbObj = pOleSdrObj->GetObjRef();
2809 OUString aOldName( pOleSdrObj->GetPersistName() );
2811 /* The object persistence should be already in the storage, but
2812 the object still might not be inserted into the container. */
2813 if( rEmbObjCont.HasEmbeddedObject( aOldName ) )
2815 if( !rEmbObjCont.HasEmbeddedObject( xEmbObj ) )
2816 // filter code is allowed to call the following method
2817 rEmbObjCont.AddEmbeddedObject( xEmbObj, aOldName );
2819 else
2821 /* If the object is still not in container it must be inserted
2822 there, the name must be generated in this case. */
2823 OUString aNewName;
2824 rEmbObjCont.InsertEmbeddedObject( xEmbObj, aNewName );
2825 if( aOldName != aNewName )
2826 // #95381# SetPersistName, not SetName
2827 pOleSdrObj->SetPersistName( aNewName );
2833 void XclImpPictureObj::ReadFlags3( XclImpStream& rStrm )
2835 sal_uInt16 nFlags;
2836 rStrm >> nFlags;
2837 mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
2840 void XclImpPictureObj::ReadFlags8( XclImpStream& rStrm )
2842 sal_uInt16 nFlags;
2843 rStrm >> nFlags;
2844 mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
2845 mbControl = ::get_flag( nFlags, EXC_OBJ_PIC_CONTROL );
2846 mbUseCtlsStrm = ::get_flag( nFlags, EXC_OBJ_PIC_CTLSSTREAM );
2847 DBG_ASSERT( mbControl || !mbUseCtlsStrm, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
2848 SetProcessSdrObj( mbControl || !mbUseCtlsStrm );
2851 void XclImpPictureObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize )
2853 sal_Size nLinkEnd = rStrm.GetRecPos() + nLinkSize;
2854 if( nLinkSize >= 6 )
2856 sal_uInt16 nFmlaSize;
2857 rStrm >> nFmlaSize;
2858 DBG_ASSERT( nFmlaSize > 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
2859 // BIFF3/BIFF4 do not support storages, nothing to do here
2860 if( (nFmlaSize > 0) && (GetBiff() >= EXC_BIFF5) )
2862 rStrm.Ignore( 4 );
2863 sal_uInt8 nToken;
2864 rStrm >> nToken;
2866 // different processing for linked vs. embedded OLE objects
2867 if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
2869 mbLinked = true;
2870 switch( GetBiff() )
2872 case EXC_BIFF5:
2874 sal_Int16 nRefIdx;
2875 sal_uInt16 nNameIdx;
2876 rStrm >> nRefIdx;
2877 rStrm.Ignore( 8 );
2878 rStrm >> nNameIdx;
2879 rStrm.Ignore( 12 );
2880 const ExtName* pExtName = GetOldRoot().pExtNameBuff->GetNameByIndex( nRefIdx, nNameIdx );
2881 if( pExtName && pExtName->IsOLE() )
2882 mnStorageId = pExtName->nStorageId;
2884 break;
2885 case EXC_BIFF8:
2887 sal_uInt16 nXti, nExtName;
2888 rStrm >> nXti >> nExtName;
2889 const XclImpExtName* pExtName = GetLinkManager().GetExternName( nXti, nExtName );
2890 if( pExtName && (pExtName->GetType() == xlExtOLE) )
2891 mnStorageId = pExtName->GetStorageId();
2893 break;
2894 default:
2895 DBG_ERROR_BIFF();
2898 else if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL, EXC_TOKCLASS_NONE ) )
2900 mbEmbedded = true;
2901 DBG_ASSERT( nFmlaSize == 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
2902 rStrm.Ignore( nFmlaSize - 1 ); // token ID already read
2903 if( nFmlaSize & 1 )
2904 rStrm.Ignore( 1 ); // padding byte
2906 // a class name may follow inside the picture link
2907 if( rStrm.GetRecPos() + 2 <= nLinkEnd )
2909 sal_uInt16 nLen;
2910 rStrm >> nLen;
2911 if( nLen > 0 )
2912 maClassName = (GetBiff() == EXC_BIFF8) ? rStrm.ReadUniString( nLen ) : rStrm.ReadRawByteString( nLen );
2915 // else: ignore other formulas, e.g. pictures linked to cell ranges
2919 // seek behind picture link data
2920 rStrm.Seek( nLinkEnd );
2922 // read additional data for embedded OLE objects following the picture link
2923 if( IsOcxControl() )
2925 // #i26521# form controls to be ignored
2926 if( maClassName.EqualsAscii( "Forms.HTML:Hidden.1" ) )
2928 SetProcessSdrObj( false );
2929 return;
2932 if( rStrm.GetRecLeft() <= 8 ) return;
2934 // position and size of control data in 'Ctls' stream
2935 mnCtlsStrmPos = static_cast< sal_Size >( rStrm.ReaduInt32() );
2936 mnCtlsStrmSize = static_cast< sal_Size >( rStrm.ReaduInt32() );
2938 if( rStrm.GetRecLeft() <= 8 ) return;
2940 // additional string (16-bit characters), e.g. for progress bar control
2941 sal_uInt32 nAddStrSize;
2942 rStrm >> nAddStrSize;
2943 DBG_ASSERT( rStrm.GetRecLeft() >= nAddStrSize + 4, "XclImpPictureObj::ReadPictFmla - missing data" );
2944 if( rStrm.GetRecLeft() >= nAddStrSize + 4 )
2946 rStrm.Ignore( nAddStrSize );
2947 // cell link and source range
2948 ReadCellLinkFormula( rStrm, true );
2949 ReadSourceRangeFormula( rStrm, true );
2952 else if( mbEmbedded && (rStrm.GetRecLeft() >= 4) )
2954 rStrm >> mnStorageId;
2958 // DFF stream conversion ======================================================
2960 void XclImpSolverContainer::ReadSolverContainer( SvStream& rDffStrm )
2962 rDffStrm >> *this;
2965 void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags )
2967 if( nDffShapeId > 0 )
2969 maSdrInfoMap[ nDffShapeId ].Set( &rSdrObj, nDffFlags );
2970 maSdrObjMap[ &rSdrObj ] = nDffShapeId;
2974 void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject& rSdrObj )
2976 // remove info of passed object from the maps
2977 XclImpSdrObjMap::iterator aIt = maSdrObjMap.find( &rSdrObj );
2978 if( aIt != maSdrObjMap.end() )
2980 maSdrInfoMap.erase( aIt->second );
2981 maSdrObjMap.erase( aIt );
2984 // remove info of all child objects of a group object
2985 if( SdrObjGroup* pGroupObj = dynamic_cast< SdrObjGroup* >( &rSdrObj ) )
2987 if( SdrObjList* pSubList = pGroupObj->GetSubList() )
2989 // iterate flat over the list because this function already works recursively
2990 SdrObjListIter aObjIt( *pSubList, IM_FLAT );
2991 for( SdrObject* pChildObj = aObjIt.Next(); pChildObj; pChildObj = aObjIt.Next() )
2992 RemoveSdrObjectInfo( *pChildObj );
2997 void XclImpSolverContainer::UpdateConnectorRules()
2999 for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
3001 UpdateConnection( pRule->nShapeA, pRule->pAObj, &pRule->nSpFlagsA );
3002 UpdateConnection( pRule->nShapeB, pRule->pBObj, &pRule->nSpFlagsB );
3003 UpdateConnection( pRule->nShapeC, pRule->pCObj );
3007 void XclImpSolverContainer::RemoveConnectorRules()
3009 // base class from SVX uses plain untyped tools/List
3010 for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
3011 delete pRule;
3012 aCList.Clear();
3014 maSdrInfoMap.clear();
3015 maSdrObjMap.clear();
3018 SvxMSDffConnectorRule* XclImpSolverContainer::GetFirstRule()
3020 return static_cast< SvxMSDffConnectorRule* >( aCList.First() );
3023 SvxMSDffConnectorRule* XclImpSolverContainer::GetNextRule()
3025 return static_cast< SvxMSDffConnectorRule* >( aCList.Next() );
3028 void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags )
3030 XclImpSdrInfoMap::const_iterator aIt = maSdrInfoMap.find( nDffShapeId );
3031 if( aIt != maSdrInfoMap.end() )
3033 rpSdrObj = aIt->second.mpSdrObj;
3034 if( pnDffFlags )
3035 *pnDffFlags = aIt->second.mnDffFlags;
3039 // ----------------------------------------------------------------------------
3041 XclImpSimpleDffManager::XclImpSimpleDffManager( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
3042 SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, 0, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, 24, 0, &rRoot.GetTracer().GetBaseTracer() ),
3043 XclImpRoot( rRoot )
3045 SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_EXCEL | SVXMSDFF_SETTINGS_IMPORT_IAS );
3048 XclImpSimpleDffManager::~XclImpSimpleDffManager()
3052 FASTBOOL XclImpSimpleDffManager::GetColorFromPalette( USHORT nIndex, Color& rColor ) const
3054 ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) );
3056 if( nColor == COL_AUTO )
3057 return FALSE;
3059 rColor.SetColor( nColor );
3060 return TRUE;
3063 // ----------------------------------------------------------------------------
3065 XclImpDffManager::XclImpDffManager(
3066 const XclImpRoot& rRoot, XclImpObjectManager& rObjManager, SvStream& rDffStrm ) :
3067 XclImpSimpleDffManager( rRoot, rDffStrm ),
3068 SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ),
3069 mrObjManager( rObjManager ),
3070 mnOleImpFlags( 0 ),
3071 mnLastCtrlIndex( -1 ),
3072 mnCurrFormScTab( -1 )
3074 if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
3076 if( pFilterOpt->IsMathType2Math() )
3077 mnOleImpFlags |= OLE_MATHTYPE_2_STARMATH;
3078 if( pFilterOpt->IsWinWord2Writer() )
3079 mnOleImpFlags |= OLE_WINWORD_2_STARWRITER;
3080 if( pFilterOpt->IsPowerPoint2Impress() )
3081 mnOleImpFlags |= OLE_POWERPOINT_2_STARIMPRESS;
3084 // try to open the 'Ctls' storage stream containing OCX control properties
3085 mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
3087 // default text margin (convert EMU to drawing layer units)
3088 mnDefTextMargin = EXC_OBJ_TEXT_MARGIN;
3089 ScaleEmu( mnDefTextMargin );
3092 XclImpDffManager::~XclImpDffManager()
3096 String XclImpObjectManager::GetOleNameOverride( const XclObjId& nObjId )
3098 String sOleName;
3099 String sCodeName = GetExtDocOptions().GetCodeName( nObjId.mnScTab );
3101 CodeNameToCntrlObjIdInfo::iterator it = maOleCtrlNameOverride.find( sCodeName );
3102 if ( it != maOleCtrlNameOverride.end() )
3104 CntrlObjIdToName::iterator it_id = it->second.find( nObjId.mnObjId );
3105 if ( it_id != it->second.end() )
3107 sOleName = it_id->second;
3110 return sOleName;
3113 void XclImpDffManager::StartProgressBar( sal_Size nProgressSize )
3115 mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) );
3116 mxProgress->AddSegment( nProgressSize );
3117 mxProgress->Activate();
3120 void XclImpDffManager::ProcessObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj )
3122 Rectangle aAnchorRect = rDrawObj.GetAnchorRect();
3123 if( rDrawObj.IsProcessSdrObj() && rDrawObj.IsValidSize( aAnchorRect ) )
3125 // CreateSdrObject() recursively creates embedded child objects
3126 SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( aAnchorRect, *mxProgress, false ) );
3127 if( xSdrObj.is() )
3128 rDrawObj.ProcessSdrObject( *xSdrObj );
3129 // call InsertSdrObject() also, if SdrObject is missing
3130 InsertSdrObject( pObjList, rDrawObj, xSdrObj.release() );
3131 UpdateUsedArea( rDrawObj );
3135 void XclImpDffManager::ProcessDrawingGroup( SvStream& rDffStrm )
3137 rDffStrm.Seek( STREAM_SEEK_TO_BEGIN );
3138 DffRecordHeader aHeader;
3139 rDffStrm >> aHeader;
3140 if( aHeader.nRecType == DFF_msofbtDggContainer )
3141 ProcessDggContainer( rDffStrm, aHeader );
3142 else
3144 DBG_ERRORFILE( "XclImpDffManager::ProcessDrawingGroup - unexpected record" );
3148 void XclImpDffManager::ProcessDrawing( SvStream& rDffStrm, sal_Size nStrmPos )
3150 rDffStrm.Seek( nStrmPos );
3151 DffRecordHeader aHeader;
3152 rDffStrm >> aHeader;
3153 if( aHeader.nRecType == DFF_msofbtDgContainer )
3154 ProcessDgContainer( rDffStrm, aHeader );
3155 else
3157 DBG_ERRORFILE( "XclImpDffManager::ProcessDrawing - unexpected record" );
3161 SdrObject* XclImpDffManager::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect )
3163 SdrObjectPtr xSdrObj;
3165 OUString aServiceName = rTbxObj.GetServiceName();
3166 if( aServiceName.getLength() > 0 ) try
3168 // create the form control from scratch
3169 Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW );
3170 // set current controls form, needed in virtual function InsertControl()
3171 SetCurrentForm( rTbxObj.GetScTab() );
3172 // try to insert the control into the form
3173 ::com::sun::star::awt::Size aDummySize;
3174 Reference< XShape > xShape;
3175 if( mxCurrForm.is() && InsertControl( xFormComp, aDummySize, &xShape, TRUE ) )
3177 xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
3178 // try to attach a macro to the control
3179 ScriptEventDescriptor aDescriptor;
3180 if( (mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) )
3182 Reference< XEventAttacherManager > xEventMgr( mxCurrForm, UNO_QUERY_THROW );
3183 xEventMgr->registerScriptEvent( mnLastCtrlIndex, aDescriptor );
3187 catch( Exception& )
3191 return xSdrObj.release();
3194 SdrObject* XclImpDffManager::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect )
3196 SdrObjectPtr xSdrObj;
3198 if( rPicObj.IsOcxControl() )
3200 if( mxCtlsStrm.Is() ) try
3202 /* set current controls form, needed in virtual function InsertControl()
3203 called from ReadOCXExcelKludgeStream() */
3204 SetCurrentForm( rPicObj.GetScTab() );
3205 // seek to stream position of the extra data for this control
3206 mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() );
3207 // read from mxCtlsStrm into xShape, insert the control model into the form
3208 Reference< XShape > xShape;
3209 if( mxCurrForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, TRUE ) )
3210 xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
3212 catch( Exception& )
3216 else
3218 SfxObjectShell* pDocShell = GetDocShell();
3219 SotStorageRef xSrcStrg = GetRootStorage();
3220 String aStrgName = rPicObj.GetOleStorageName();
3221 if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) )
3223 // first try to resolve graphic from DFF storage
3224 Graphic aGraphic;
3225 Rectangle aVisArea;
3226 if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) )
3228 // if not found, use graphic from object (imported from IMGDATA record)
3229 aGraphic = rPicObj.GetGraphic();
3230 aVisArea = rPicObj.GetVisArea();
3232 if( aGraphic.GetType() != GRAPHIC_NONE )
3234 ErrCode nError = ERRCODE_NONE;
3235 namespace cssea = ::com::sun::star::embed::Aspects;
3236 sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT;
3237 xSdrObj.reset( CreateSdrOLEFromStorage(
3238 aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic,
3239 rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) );
3244 return xSdrObj.release();
3247 ScRange XclImpDffManager::GetUsedArea( SCTAB nScTab ) const
3249 ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID );
3250 ScRangeMap::const_iterator aIt = maUsedAreaMap.find( nScTab );
3251 if( aIt != maUsedAreaMap.end() )
3252 aScUsedArea = aIt->second;
3253 return aScUsedArea;
3256 // virtual functions ----------------------------------------------------------
3258 void XclImpDffManager::ProcessClientAnchor2( SvStream& rDffStrm,
3259 DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData )
3261 // find the OBJ record data related to the processed shape
3262 if( XclImpDrawObjBase* pDrawObj = mrObjManager.FindDrawObj( rObjData.rSpHd ).get() )
3264 DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffManager::ProcessClientAnchor2 - no client anchor record" );
3265 XclObjAnchor aAnchor( pDrawObj->GetScTab() );
3266 rHeader.SeekToContent( rDffStrm );
3267 rDffStrm.SeekRel( 2 ); // flags
3268 rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records
3269 pDrawObj->SetAnchor( aAnchor );
3270 rObjData.aChildAnchor = pDrawObj->GetAnchorRect();
3271 rObjData.bChildAnchor = sal_True;
3275 SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm,
3276 DffObjData& rDffObjData, void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj )
3278 /* pOldSdrObj passes a generated SdrObject. This function owns this object
3279 and can modify it. The function has either to return it back to caller
3280 or to delete it by itself. */
3281 SdrObjectPtr xSdrObj( pOldSdrObj );
3283 // find the OBJ record data related to the processed shape
3284 XclImpDrawObjRef xDrawObj = mrObjManager.FindDrawObj( rDffObjData.rSpHd );
3285 const Rectangle& rAnchorRect = rDffObjData.aChildAnchor;
3287 // #102378# Do not process the global page group shape (flag SP_FPATRIARCH)
3288 bool bGlobalPageGroup = ::get_flag< sal_uInt32 >( rDffObjData.nSpFlags, SP_FPATRIARCH );
3289 if( !xDrawObj || !xDrawObj->IsProcessSdrObj() || bGlobalPageGroup )
3290 return 0; // simply return, xSdrObj will be destroyed
3292 /* Pass pointer to top-level object back to caller. If the processed
3293 object is embedded in a group, the pointer is already set to the
3294 top-level parent object. */
3295 XclImpDrawObjBase** ppTopLevelObj = reinterpret_cast< XclImpDrawObjBase** >( pClientData );
3296 bool bIsTopLevel = !ppTopLevelObj || !*ppTopLevelObj;
3297 if( ppTopLevelObj && bIsTopLevel )
3298 *ppTopLevelObj = xDrawObj.get();
3300 // #119010# connectors don't have to be area objects
3301 if( dynamic_cast< SdrEdgeObj* >( xSdrObj.get() ) )
3302 xDrawObj->SetAreaObj( false );
3304 /* Check for valid size for all objects. Needed to ignore lots of invisible
3305 phantom objects from deleted rows or columns (for performance reasons).
3306 #i30816# Include objects embedded in groups.
3307 #i58780# Ignore group shapes, size is not initialized. */
3308 bool bEmbeddedGroup = !bIsTopLevel && dynamic_cast< SdrObjGroup* >( xSdrObj.get() );
3309 if( !bEmbeddedGroup && !xDrawObj->IsValidSize( rAnchorRect ) )
3310 return 0; // simply return, xSdrObj will be destroyed
3312 // set shape information from DFF stream
3313 String aObjName = GetPropertyString( DFF_Prop_wzName, rDffStrm );
3314 String aHyperlink = ReadHlinkProperty( rDffStrm );
3315 bool bVisible = !GetPropertyBool( DFF_Prop_fHidden );
3316 bool bAutoMargin = GetPropertyBool( DFF_Prop_AutoTextMargin );
3317 xDrawObj->SetDffData( rDffObjData, aObjName, aHyperlink, bVisible, bAutoMargin );
3319 /* Connect textbox data (string, alignment, text orientation) to object.
3320 #98132# don't ask for a text-ID, DFF export doesn't set one. */
3321 if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) )
3322 if( const XclImpObjTextData* pTextData = mrObjManager.FindTextData( rDffObjData.rSpHd ) )
3323 pTextObj->SetTextData( *pTextData );
3325 // copy line and fill formatting of TBX form controls from DFF properties
3326 if( XclImpTbxObjBase* pTbxObj = dynamic_cast< XclImpTbxObjBase* >( xDrawObj.get() ) )
3327 pTbxObj->SetDffProperties( *this );
3329 // try to create a custom SdrObject that overwrites the passed object
3330 SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( rAnchorRect, *mxProgress, true ) );
3331 if( xNewSdrObj.is() )
3332 xSdrObj.reset( xNewSdrObj.release() );
3334 // process the SdrObject
3335 if( xSdrObj.is() )
3337 // filled without color -> set system window color
3338 if( GetPropertyBool( DFF_Prop_fFilled ) && !IsProperty( DFF_Prop_fillColor ) )
3339 xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) );
3341 // additional processing on the SdrObject
3342 xDrawObj->ProcessSdrObject( *xSdrObj );
3344 // add the area used by this object to the internal map of used areas
3345 UpdateUsedArea( *xDrawObj );
3347 /* If the SdrObject will not be inserted into the draw page, delete it
3348 here. Happens e.g. for notes: The ProcessSdrObject() call above has
3349 inserted the note into the document, and the SdrObject is not
3350 needed anymore. */
3351 if( !xDrawObj->IsInsertSdrObj() )
3352 xSdrObj.reset();
3355 /* Store the relation between shape ID and SdrObject for connectors. Must
3356 be done here (and not in InsertSdrObject() function), otherwise all
3357 SdrObjects embedded in groups would be lost. */
3358 if( xSdrObj.is() )
3359 maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() );
3361 return xSdrObj.release();
3364 ULONG XclImpDffManager::Calc_nBLIPPos( ULONG /*nOrgVal*/, ULONG nStreamPos ) const
3366 return nStreamPos + 4;
3369 sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxFormComp,
3370 const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape,
3371 BOOL /*bFloatingCtrl*/ )
3373 if( GetDocShell() ) try
3375 Reference< XIndexContainer > xFormIC( mxCurrForm, UNO_QUERY_THROW );
3376 Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW );
3378 // create the control shape
3379 Reference< XShape > xShape( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ) ), UNO_QUERY_THROW );
3380 Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY_THROW );
3382 // insert the new control into the form
3383 sal_Int32 nNewIndex = xFormIC->getCount();
3384 xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) );
3385 // on success: store new index of the control for later use (macro events)
3386 mnLastCtrlIndex = nNewIndex;
3388 // set control model at control shape and pass back shape to caller
3389 xCtrlShape->setControl( xCtrlModel );
3390 if( pxShape ) *pxShape = xShape;
3391 return sal_True;
3393 catch( Exception& )
3395 DBG_ERRORFILE( "XclImpDffManager::InsertControl - cannot create form control" );
3398 return sal_False;
3401 // private --------------------------------------------------------------------
3403 String XclImpDffManager::ReadHlinkProperty( SvStream& rDffStrm ) const
3405 /* Reads hyperlink data from a complex DFF property. Contents of this
3406 property are equal to the HLINK record, import of this record is
3407 implemented in class XclImpHyperlink. This function has to create an
3408 instance of the XclImpStream class to be able to reuse the
3409 functionality of XclImpHyperlink. */
3410 String aString;
3411 sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
3412 if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rDffStrm ) )
3414 // create a faked BIFF record that can be read by XclImpStream class
3415 SvMemoryStream aMemStream;
3416 aMemStream << sal_uInt16( 0 ) << static_cast< sal_uInt16 >( nBufferSize );
3418 // copy from DFF stream to memory stream
3419 ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
3420 sal_uInt8* pnData = &aBuffer.front();
3421 if( rDffStrm.Read( pnData, nBufferSize ) == nBufferSize )
3423 aMemStream.Write( pnData, nBufferSize );
3425 // create BIFF import stream to be able to use XclImpHyperlink class
3426 XclImpStream aXclStrm( aMemStream, GetRoot() );
3427 if( aXclStrm.StartNextRecord() )
3428 aString = XclImpHyperlink::ReadEmbeddedData( aXclStrm );
3431 return aString;
3434 void XclImpDffManager::ProcessDggContainer( SvStream& rDffStrm, const DffRecordHeader& rDggHeader )
3436 // seek to end of drawing group container
3437 rDggHeader.SeekToEndOfRecord( rDffStrm );
3440 void XclImpDffManager::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader )
3442 sal_Size nEndPos = rDgHeader.GetRecEndFilePos();
3443 while( rDffStrm.Tell() < nEndPos )
3445 DffRecordHeader aHeader;
3446 rDffStrm >> aHeader;
3447 switch( aHeader.nRecType )
3449 case DFF_msofbtSolverContainer:
3450 ProcessSolverContainer( rDffStrm, aHeader );
3451 break;
3452 case DFF_msofbtSpgrContainer:
3453 ProcessShGrContainer( rDffStrm, aHeader );
3454 break;
3455 default:
3456 aHeader.SeekToEndOfRecord( rDffStrm );
3459 // seek to end of drawing page container
3460 rDgHeader.SeekToEndOfRecord( rDffStrm );
3462 // #i12638# #i37900# connector rules
3463 maSolverCont.UpdateConnectorRules();
3464 SolveSolver( maSolverCont );
3465 maSolverCont.RemoveConnectorRules();
3468 void XclImpDffManager::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader )
3470 sal_Size nEndPos = rShGrHeader.GetRecEndFilePos();
3471 while( rDffStrm.Tell() < nEndPos )
3473 DffRecordHeader aHeader;
3474 rDffStrm >> aHeader;
3475 switch( aHeader.nRecType )
3477 case DFF_msofbtSpgrContainer:
3478 case DFF_msofbtSpContainer:
3479 ProcessShContainer( rDffStrm, aHeader );
3480 break;
3481 default:
3482 aHeader.SeekToEndOfRecord( rDffStrm );
3485 // seek to end of shape group container
3486 rShGrHeader.SeekToEndOfRecord( rDffStrm );
3489 void XclImpDffManager::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader )
3491 // solver container wants to read the solver container header again
3492 rSolverHeader.SeekToBegOfRecord( rDffStrm );
3493 // read the entire solver container
3494 rDffStrm >> maSolverCont;
3495 // seek to end of solver container
3496 rSolverHeader.SeekToEndOfRecord( rDffStrm );
3499 void XclImpDffManager::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader )
3501 rShHeader.SeekToBegOfRecord( rDffStrm );
3502 Rectangle aDummy;
3503 const XclImpDrawObjBase* pDrawObj = 0;
3504 /* The call to ImportObj() creates and returns a new SdrObject for the
3505 processed shape. We take ownership of the returned object here. If the
3506 shape is a group object, all embedded objects are created recursively,
3507 and the returned group object contains them all. ImportObj() calls the
3508 virtual functions ProcessClientAnchor2() and ProcessObj() and writes
3509 the pointer to the related draw object data (OBJ record) into pDrawObj. */
3510 SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy, 0, 0 ) );
3511 if( pDrawObj && xSdrObj.is() )
3512 InsertSdrObject( GetSdrPage( pDrawObj->GetScTab() ), *pDrawObj, xSdrObj.release() );
3513 rShHeader.SeekToEndOfRecord( rDffStrm );
3516 void XclImpDffManager::InsertSdrObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj )
3518 /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
3519 states to skip insertion, or missing draw page), the object is
3520 automatically deleted. */
3521 SdrObjectPtr xSdrObj( pSdrObj );
3522 if( pObjList && xSdrObj.is() && rDrawObj.IsInsertSdrObj() )
3523 pObjList->NbcInsertObject( xSdrObj.release() );
3524 // SdrObject still here? Insertion failed, remove data from shape ID map.
3525 if( xSdrObj.is() )
3526 maSolverCont.RemoveSdrObjectInfo( *xSdrObj );
3529 void XclImpDffManager::SetCurrentForm( SCTAB nScTab )
3531 if( nScTab != mnCurrFormScTab )
3533 mxCurrForm.clear();
3534 mnCurrFormScTab = nScTab;
3536 SdrPage* pSdrPage = GetSdrPage( nScTab );
3537 if( GetDocShell() && pSdrPage ) try
3539 Reference< XFormsSupplier > xFormsSupplier( pSdrPage->getUnoPage(), UNO_QUERY_THROW );
3540 Reference< XNameContainer > xFormsNC = xFormsSupplier->getForms();
3541 if( xFormsNC.is() )
3543 // find or create the Standard form used to insert the imported controls
3544 OUString aFormName = CREATE_OUSTRING( "Standard" );
3545 if( xFormsNC->hasByName( aFormName ) )
3547 xFormsNC->getByName( aFormName ) >>= mxCurrForm;
3549 else
3551 mxCurrForm.set( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW );
3552 xFormsNC->insertByName( aFormName, Any( mxCurrForm ) );
3556 catch( Exception& )
3562 void XclImpDffManager::UpdateUsedArea( const XclImpDrawObjBase& rDrawObj )
3564 ScRange aScObjArea = rDrawObj.GetUsedArea();
3565 if( aScObjArea.IsValid() )
3567 ScRange* pScTabArea = 0;
3568 ScRangeMap::iterator aIt = maUsedAreaMap.find( rDrawObj.GetScTab() );
3569 if( aIt == maUsedAreaMap.end() )
3571 pScTabArea = &maUsedAreaMap[ rDrawObj.GetScTab() ];
3572 pScTabArea->SetInvalid();
3574 else
3575 pScTabArea = &aIt->second;
3577 if( pScTabArea )
3578 pScTabArea->ExtendTo( aScObjArea );
3582 // The object manager =========================================================
3584 XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) :
3585 XclImpRoot( rRoot )
3587 maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" );
3588 maDefObjNames[ EXC_OBJTYPE_LINE ] = ScGlobal::GetRscString( STR_SHAPE_LINE );
3589 maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = ScGlobal::GetRscString( STR_SHAPE_RECTANGLE );
3590 maDefObjNames[ EXC_OBJTYPE_OVAL ] = ScGlobal::GetRscString( STR_SHAPE_OVAL );
3591 maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" );
3592 maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" );
3593 maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" );
3594 maDefObjNames[ EXC_OBJTYPE_BUTTON ] = ScGlobal::GetRscString( STR_FORM_BUTTON );
3595 maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" );
3596 maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" );
3597 maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = ScGlobal::GetRscString( STR_FORM_CHECKBOX );
3598 maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = ScGlobal::GetRscString( STR_FORM_OPTIONBUTTON );
3599 maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" );
3600 maDefObjNames[ EXC_OBJTYPE_LABEL ] = ScGlobal::GetRscString( STR_FORM_LABEL );
3601 maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" );
3602 maDefObjNames[ EXC_OBJTYPE_SPIN ] = ScGlobal::GetRscString( STR_FORM_SPINNER );
3603 maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = ScGlobal::GetRscString( STR_FORM_SCROLLBAR );
3604 maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = ScGlobal::GetRscString( STR_FORM_LISTBOX );
3605 maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = ScGlobal::GetRscString( STR_FORM_GROUPBOX );
3606 maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = ScGlobal::GetRscString( STR_FORM_DROPDOWN );
3607 maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" );
3608 maDefObjNames[ EXC_OBJTYPE_DRAWING ] = ScGlobal::GetRscString( STR_SHAPE_AUTOSHAPE );
3611 XclImpObjectManager::~XclImpObjectManager()
3615 // *** Read Excel records *** -------------------------------------------------
3617 Graphic XclImpObjectManager::ReadImgData( XclImpStream& rStrm ) // static helper
3619 Graphic aGraphic;
3620 sal_uInt16 nFormat, nEnv;
3621 sal_uInt32 nDataSize;
3622 rStrm >> nFormat >> nEnv >> nDataSize;
3623 if( nDataSize <= rStrm.GetRecLeft() )
3625 switch( nFormat )
3627 case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rStrm ); break;
3628 case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rStrm ); break;
3629 default: DBG_ERRORFILE( "XclImpObjectManager::ReadImgData - unknown image format" );
3632 return aGraphic;
3635 void XclImpObjectManager::ReadObj( XclImpStream& rStrm )
3637 XclImpDrawObjRef xDrawObj;
3639 /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
3640 records. In this case, the OBJ records are in BIFF5 format. Do a sanity
3641 check here that there is no DFF data loaded before. */
3642 DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpObjectManager::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
3643 if( maDffStrm.Tell() == 0 ) switch( GetBiff() )
3645 case EXC_BIFF3:
3646 xDrawObj = XclImpDrawObjBase::ReadObj3( rStrm );
3647 break;
3648 case EXC_BIFF4:
3649 xDrawObj = XclImpDrawObjBase::ReadObj4( rStrm );
3650 break;
3651 case EXC_BIFF5:
3652 case EXC_BIFF8:
3653 xDrawObj = XclImpDrawObjBase::ReadObj5( rStrm );
3654 break;
3655 default:
3656 DBG_ERROR_BIFF();
3659 if( xDrawObj.is() )
3661 // insert into maRawObjs or into the last open group object
3662 maRawObjs.InsertGrouped( xDrawObj );
3663 // to be able to find objects by ID
3664 maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
3668 void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm )
3670 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
3671 // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
3672 rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP );
3673 ReadDffRecord( rStrm );
3676 void XclImpObjectManager::ReadMsoDrawing( XclImpStream& rStrm )
3678 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
3679 // disable internal CONTINUE handling
3680 rStrm.ResetRecord( false );
3681 /* #i60510# real life: MSODRAWINGSELECTION record may contain garbage -
3682 this makes it impossible to process the DFF stream in one run.
3683 Store stream start position for every sheet separately, will be used
3684 to seek the stream to these positions later, when processing the next
3685 sheet. */
3686 size_t nTabIdx = static_cast< size_t >( GetCurrScTab() );
3687 if( nTabIdx >= maTabStrmPos.size() )
3689 maTabStrmPos.resize( nTabIdx, STREAM_SEEK_TO_END );
3690 maTabStrmPos.push_back( maDffStrm.Tell() );
3692 // read leading MSODRAWING record
3693 ReadDffRecord( rStrm );
3695 // read following drawing records, but do not start following unrelated record
3696 bool bLoop = true;
3697 while( bLoop ) switch( rStrm.GetNextRecId() )
3699 case EXC_ID_MSODRAWING:
3700 case EXC_ID_MSODRAWINGSEL:
3701 case EXC_ID_CONT:
3702 rStrm.StartNextRecord();
3703 ReadDffRecord( rStrm );
3704 break;
3705 case EXC_ID_OBJ:
3706 rStrm.StartNextRecord();
3707 ReadObj8( rStrm );
3708 break;
3709 case EXC_ID_TXO:
3710 rStrm.StartNextRecord();
3711 ReadTxo( rStrm );
3712 break;
3713 default:
3714 bLoop = false;
3717 // re-enable internal CONTINUE handling
3718 rStrm.ResetRecord( true );
3721 void XclImpObjectManager::ReadNote( XclImpStream& rStrm )
3723 switch( GetBiff() )
3725 case EXC_BIFF2:
3726 case EXC_BIFF3:
3727 case EXC_BIFF4:
3728 case EXC_BIFF5:
3729 ReadNote3( rStrm );
3730 break;
3731 case EXC_BIFF8:
3732 ReadNote8( rStrm );
3733 break;
3734 default:
3735 DBG_ERROR_BIFF();
3739 void XclImpObjectManager::ReadTabChart( XclImpStream& rStrm )
3741 DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 );
3742 ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) );
3743 xChartObj->ReadChartSubStream( rStrm );
3744 // insert the chart as raw object without connected DFF data
3745 maRawObjs.push_back( xChartObj );
3748 // *** Drawing objects *** ----------------------------------------------------
3750 XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const DffRecordHeader& rHeader ) const
3752 /* maObjMap stores objects by position of the client data (OBJ record) in
3753 the DFF stream, which is always behind shape start position of the
3754 passed header. The function upper_bound() finds the first element in
3755 the map whose key is greater than the start position of the header. Its
3756 end position is used to test whether the found object is really related
3757 to the shape. */
3758 XclImpDrawObjRef xDrawObj;
3759 XclImpObjMap::const_iterator aIt = maObjMap.upper_bound( rHeader.GetRecBegFilePos() );
3760 if( (aIt != maObjMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
3761 xDrawObj = aIt->second;
3762 return xDrawObj;
3765 XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const XclObjId& rObjId ) const
3767 XclImpDrawObjRef xDrawObj;
3768 XclImpObjMapById::const_iterator aIt = maObjMapId.find( rObjId );
3769 if( aIt != maObjMapId.end() )
3770 xDrawObj = aIt->second;
3771 return xDrawObj;
3774 const XclImpObjTextData* XclImpObjectManager::FindTextData( const DffRecordHeader& rHeader ) const
3776 /* maTextMap stores textbox data by position of the client data (TXO
3777 record) in the DFF stream, which is always behind shape start position
3778 of the passed header. The function upper_bound() finds the first
3779 element in the map whose key is greater than the start position of the
3780 header. Its end position is used to test whether the found object is
3781 really related to the shape. */
3782 XclImpObjTextMap::const_iterator aIt = maTextMap.upper_bound( rHeader.GetRecBegFilePos() );
3783 if( (aIt != maTextMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
3784 return aIt->second.get();
3785 return 0;
3788 void XclImpObjectManager::SetSkipObj( SCTAB nScTab, sal_uInt16 nObjId )
3790 maSkipObjs.push_back( XclObjId( nScTab, nObjId ) );
3793 // *** Drawing object conversion *** ------------------------------------------
3795 XclImpDffManager& XclImpObjectManager::GetDffManager()
3797 if( !mxDffManager )
3798 mxDffManager.reset( new XclImpDffManager( GetRoot(), *this, maDffStrm ) );
3799 return *mxDffManager;
3802 void XclImpObjectManager::ConvertObjects()
3804 RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" );
3806 // do nothing if the document does not contain a drawing layer
3807 if( GetDoc().GetDrawLayer() )
3809 // process list of identifiers of objects to be skipped
3810 for( XclObjIdVec::const_iterator aVIt = maSkipObjs.begin(), aVEnd = maSkipObjs.end(); aVIt != aVEnd; ++aVIt )
3811 if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aVIt ).get() )
3812 pDrawObj->SetProcessSdrObj( false );
3814 // get progress bar size for all valid objects
3815 sal_Size nProgressSize = GetProgressSize();
3816 if( nProgressSize > 0 )
3818 XclImpDffManager& rDffManager = GetDffManager();
3819 rDffManager.StartProgressBar( nProgressSize );
3820 // process drawing objects without DFF data
3821 for( XclImpDrawObjVector::const_iterator aVIt = maRawObjs.begin(), aVEnd = maRawObjs.end(); aVIt != aVEnd; ++aVIt )
3822 rDffManager.ProcessObject( GetSdrPage( (*aVIt)->GetScTab() ), **aVIt );
3823 // process the global DFF container, contains pictures
3824 if( !maTabStrmPos.empty() && (maTabStrmPos.front() > 0) )
3825 rDffManager.ProcessDrawingGroup( maDffStrm );
3826 // process the sheet records, this inserts the objects into the drawing layer
3827 for( StreamPosVec::const_iterator aPIt = maTabStrmPos.begin(), aPEnd = maTabStrmPos.end(); aPIt != aPEnd; ++aPIt )
3828 if( *aPIt != STREAM_SEEK_TO_END )
3829 rDffManager.ProcessDrawing( maDffStrm, *aPIt );
3834 String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const
3836 String aDefName;
3837 DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() );
3838 if( aIt != maDefObjNames.end() )
3839 aDefName.Append( aIt->second );
3840 return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId().mnObjId ) );
3843 ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const
3845 ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID );
3846 if( mxDffManager.is() )
3847 aScUsedArea = mxDffManager->GetUsedArea( nScTab );
3848 return aScUsedArea;
3851 // private --------------------------------------------------------------------
3853 void XclImpObjectManager::ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ) // static helper
3855 // extract graphic data from IMGDATA and following CONTINUE records
3856 rStrm.Ignore( 8 );
3857 SvMemoryStream aMemStrm;
3858 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3859 aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
3860 // import the graphic from memory stream
3861 GDIMetaFile aGDIMetaFile;
3862 if( ::ReadWindowMetafile( aMemStrm, aGDIMetaFile, 0 ) )
3863 rGraphic = aGDIMetaFile;
3866 void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // static helper
3868 // extract graphic data from IMGDATA and following CONTINUE records
3869 SvMemoryStream aMemStrm;
3871 /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
3872 DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
3873 pixel depth = 32 bit. After that, 3 unused bytes are added before the
3874 actual pixel data. This does even confuse Excel 5 and later, which
3875 cannot read the image data correctly. */
3876 if( rStrm.GetRoot().GetBiff() <= EXC_BIFF4 )
3878 rStrm.PushPosition();
3879 sal_uInt32 nHdrSize;
3880 sal_uInt16 nWidth, nHeight, nPlanes, nDepth;
3881 rStrm >> nHdrSize >> nWidth >> nHeight >> nPlanes >> nDepth;
3882 if( (nHdrSize == 12) && (nPlanes == 1) && (nDepth == 32) )
3884 rStrm.Ignore( 3 );
3885 aMemStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3886 aMemStrm << nHdrSize << nWidth << nHeight << nPlanes << nDepth;
3887 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3889 rStrm.PopPosition();
3892 // no special handling above -> just copy the remaining record data
3893 if( aMemStrm.Tell() == 0 )
3894 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3896 // import the graphic from memory stream
3897 aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
3898 Bitmap aBitmap;
3899 if( aBitmap.Read( aMemStrm, FALSE ) ) // read DIB without file header
3900 rGraphic = aBitmap;
3903 void XclImpObjectManager::ReadDffRecord( XclImpStream& rStrm )
3905 maDffStrm.Seek( STREAM_SEEK_TO_END );
3906 rStrm.CopyRecordToStream( maDffStrm );
3909 void XclImpObjectManager::ReadObj8( XclImpStream& rStrm )
3911 XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( rStrm );
3912 // store the new object in the internal containers
3913 maObjMap[ maDffStrm.Tell() ] = xDrawObj;
3914 maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
3917 void XclImpObjectManager::ReadTxo( XclImpStream& rStrm )
3919 XclImpObjTextRef xTextData( new XclImpObjTextData );
3920 maTextMap[ maDffStrm.Tell() ] = xTextData;
3922 // 1) read the TXO record
3923 xTextData->maData.ReadTxo8( rStrm );
3925 // 2) first CONTINUE with string
3926 xTextData->mxString.reset();
3927 bool bValid = true;
3928 if( xTextData->maData.mnTextLen > 0 )
3930 bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
3931 DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" );
3932 if( bValid )
3933 xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) );
3936 // 3) second CONTINUE with formatting runs
3937 if( xTextData->maData.mnFormatSize > 0 )
3939 bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
3940 DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" );
3941 if( bValid )
3942 xTextData->ReadFormats( rStrm );
3946 void XclImpObjectManager::ReadNote3( XclImpStream& rStrm )
3948 XclAddress aXclPos;
3949 sal_uInt16 nTotalLen;
3950 rStrm >> aXclPos >> nTotalLen;
3952 SCTAB nScTab = GetCurrScTab();
3953 ScAddress aScNotePos( ScAddress::UNINITIALIZED );
3954 if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) )
3956 sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) );
3957 String aNoteText = rStrm.ReadRawByteString( nPartLen );
3958 nTotalLen = nTotalLen - nPartLen;
3959 while( (nTotalLen > 0) && (rStrm.GetNextRecId() == EXC_ID_NOTE) && rStrm.StartNextRecord() )
3961 rStrm >> aXclPos >> nPartLen;
3962 DBG_ASSERT( aXclPos.mnRow == 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
3963 if( aXclPos.mnRow == 0xFFFF )
3965 DBG_ASSERT( nPartLen <= nTotalLen, "XclImpObjectManager::ReadNote3 - string too long" );
3966 aNoteText.Append( rStrm.ReadRawByteString( nPartLen ) );
3967 nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen );
3969 else
3971 // seems to be a new note, record already started -> load the note
3972 rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
3973 ReadNote( rStrm );
3974 nTotalLen = 0;
3977 ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false );
3981 void XclImpObjectManager::ReadNote8( XclImpStream& rStrm )
3983 XclAddress aXclPos;
3984 sal_uInt16 nFlags, nObjId;
3985 rStrm >> aXclPos >> nFlags >> nObjId;
3987 SCTAB nScTab = GetCurrScTab();
3988 ScAddress aScNotePos( ScAddress::UNINITIALIZED );
3989 if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) )
3990 if( nObjId != EXC_OBJ_INVALID_ID )
3991 if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( XclObjId( nScTab, nObjId ) ).get() ) )
3992 pNoteObj->SetNoteData( aScNotePos, nFlags );
3995 sal_Size XclImpObjectManager::GetProgressSize() const
3997 sal_Size nProgressSize = maRawObjs.GetProgressSize();
3998 for( XclImpObjMap::const_iterator aMIt = maObjMap.begin(), aMEnd = maObjMap.end(); aMIt != aMEnd; ++aMIt )
3999 nProgressSize += aMIt->second->GetProgressSize();
4000 return nProgressSize;
4003 // DFF property set helper ====================================================
4005 XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot& rRoot ) :
4006 XclImpRoot( rRoot ),
4007 maDffManager( rRoot, maDummyStrm )
4011 void XclImpDffPropSet::Read( XclImpStream& rStrm )
4013 sal_uInt32 nPropSetSize;
4015 rStrm.PushPosition();
4016 rStrm.Ignore( 4 );
4017 rStrm >> nPropSetSize;
4018 rStrm.PopPosition();
4020 mxMemStrm.reset( new SvMemoryStream );
4021 rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize );
4022 mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN );
4023 maDffManager.ReadPropSet( *mxMemStrm, 0 );
4026 sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const
4028 return maDffManager.GetPropertyValue( nPropId, nDefault );
4031 void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const
4033 if( mxMemStrm.get() )
4034 maDffManager.ApplyAttributes( *mxMemStrm, rItemSet );
4037 XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet )
4039 rPropSet.Read( rStrm );
4040 return rStrm;
4043 // ============================================================================