update dev300-m58
[ooovba.git] / sc / source / filter / excel / xiescher.cxx
blobf61aaccb880d54c86c1135b6197eb2b097afbfe1
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 // create formatted text
1650 XclImpTextObj::DoProcessSdrObj( rSdrObj );
1651 OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject();
1652 if( maScPos.IsValid() && pOutlinerObj )
1654 // create cell note with all data from drawing object
1655 ScNoteUtil::CreateNoteFromObjectData(
1656 GetDoc(), maScPos,
1657 rSdrObj.GetMergedItemSet().Clone(), // new object on heap expected
1658 new OutlinerParaObject( *pOutlinerObj ), // new object on heap expected
1659 rSdrObj.GetLogicRect(),
1660 ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ),
1661 false );
1665 // ----------------------------------------------------------------------------
1667 XclImpControlHelper::XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode ) :
1668 mrRoot( rRoot ),
1669 meBindMode( eBindMode )
1673 XclImpControlHelper::~XclImpControlHelper()
1677 SdrObject* XclImpControlHelper::CreateSdrObjectFromShape(
1678 const Reference< XShape >& rxShape, const Rectangle& rAnchorRect ) const
1680 mxShape = rxShape;
1681 SdrObjectPtr xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape ) );
1682 if( xSdrObj.is() )
1684 xSdrObj->NbcSetSnapRect( rAnchorRect );
1685 // #i30543# insert into control layer
1686 xSdrObj->NbcSetLayer( SC_LAYER_CONTROLS );
1688 return xSdrObj.release();
1691 void XclImpControlHelper::ApplySheetLinkProps() const
1694 Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
1695 if( !xCtrlModel.is() )
1696 return;
1697 ScfPropertySet aPropSet( xCtrlModel );
1699 // sheet links
1700 if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
1702 Reference< XMultiServiceFactory > xFactory( pDocShell->GetModel(), UNO_QUERY );
1703 if( xFactory.is() )
1705 // cell link
1706 if( mxCellLink.is() ) try
1708 Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY_THROW );
1710 // create argument sequence for createInstanceWithArguments()
1711 CellAddress aApiAddress;
1712 ScUnoConversion::FillApiAddress( aApiAddress, *mxCellLink );
1714 NamedValue aValue;
1715 aValue.Name = CREATE_OUSTRING( SC_UNONAME_BOUNDCELL );
1716 aValue.Value <<= aApiAddress;
1718 Sequence< Any > aArgs( 1 );
1719 aArgs[ 0 ] <<= aValue;
1721 // create the CellValueBinding instance and set at the control model
1722 OUString aServiceName;
1723 switch( meBindMode )
1725 case EXC_CTRL_BINDCONTENT: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_VALBIND ); break;
1726 case EXC_CTRL_BINDPOSITION: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_LISTCELLBIND ); break;
1728 Reference< XValueBinding > xBinding(
1729 xFactory->createInstanceWithArguments( aServiceName, aArgs ), UNO_QUERY_THROW );
1730 xBindable->setValueBinding( xBinding );
1732 catch( const Exception& )
1736 // source range
1737 if( mxSrcRange.is() ) try
1739 Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY_THROW );
1741 // create argument sequence for createInstanceWithArguments()
1742 CellRangeAddress aApiRange;
1743 ScUnoConversion::FillApiRange( aApiRange, *mxSrcRange );
1745 NamedValue aValue;
1746 aValue.Name = CREATE_OUSTRING( SC_UNONAME_CELLRANGE );
1747 aValue.Value <<= aApiRange;
1749 Sequence< Any > aArgs( 1 );
1750 aArgs[ 0 ] <<= aValue;
1752 // create the EntrySource instance and set at the control model
1753 Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
1754 CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ), aArgs ), UNO_QUERY_THROW );
1755 xEntrySink->setListEntrySource( xEntrySource );
1757 catch( const Exception& )
1764 void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) const
1766 Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
1767 if( !xCtrlModel.is() )
1768 return;
1770 ApplySheetLinkProps();
1772 ScfPropertySet aPropSet( xCtrlModel );
1774 // #118053# #i51348# set object name at control model
1775 aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() );
1777 // control visible and printable?
1778 aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );
1779 aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() );
1782 // virtual call for type specific processing
1783 DoProcessControl( aPropSet );
1786 void XclImpControlHelper::ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize )
1788 ScRangeList aScRanges;
1789 ReadRangeList( aScRanges, rStrm, bWithBoundSize );
1790 // Use first cell of first range
1791 if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
1792 mxCellLink.reset( new ScAddress( pScRange->aStart ) );
1795 void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize )
1797 ScRangeList aScRanges;
1798 ReadRangeList( aScRanges, rStrm, bWithBoundSize );
1799 // Use first range
1800 if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
1801 mxSrcRange.reset( new ScRange( *pScRange ) );
1804 void XclImpControlHelper::DoProcessControl( ScfPropertySet& ) const
1808 void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm )
1810 XclTokenArray aXclTokArr;
1811 aXclTokArr.ReadSize( rStrm );
1812 rStrm.Ignore( 4 );
1813 aXclTokArr.ReadArray( rStrm );
1814 mrRoot.GetFormulaCompiler().CreateRangeList( rScRanges, EXC_FMLATYPE_CONTROL, aXclTokArr, rStrm );
1817 void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize )
1819 if( bWithBoundSize )
1821 sal_uInt16 nSize;
1822 rStrm >> nSize;
1823 if( nSize > 0 )
1825 rStrm.PushPosition();
1826 ReadRangeList( rScRanges, rStrm );
1827 rStrm.PopPosition();
1828 rStrm.Ignore( nSize );
1831 else
1833 ReadRangeList( rScRanges, rStrm );
1837 // ----------------------------------------------------------------------------
1839 XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot& rRoot ) :
1840 XclImpTextObj( rRoot ),
1841 XclImpControlHelper( rRoot, EXC_CTRL_BINDPOSITION )
1843 SetSimpleMacro( false );
1844 SetCustomDffObj( true );
1847 namespace {
1849 void lclExtractColor( sal_uInt8& rnColorIdx, const DffPropSet& rDffPropSet, sal_uInt32 nPropId )
1851 if( rDffPropSet.IsProperty( nPropId ) )
1853 sal_uInt32 nColor = rDffPropSet.GetPropertyValue( nPropId );
1854 if( (nColor & 0xFF000000) == 0x08000000 )
1855 rnColorIdx = ::extract_value< sal_uInt8 >( nColor, 0, 8 );
1859 } // namespace
1861 void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet )
1863 maFillData.mnPattern = rDffPropSet.GetPropertyBool( DFF_Prop_fFilled ) ? EXC_PATT_SOLID : EXC_PATT_NONE;
1864 lclExtractColor( maFillData.mnBackColorIdx, rDffPropSet, DFF_Prop_fillBackColor );
1865 lclExtractColor( maFillData.mnPattColorIdx, rDffPropSet, DFF_Prop_fillColor );
1866 ::set_flag( maFillData.mnAuto, EXC_OBJ_LINE_AUTO, false );
1868 maLineData.mnStyle = rDffPropSet.GetPropertyBool( DFF_Prop_fLine ) ? EXC_OBJ_LINE_SOLID : EXC_OBJ_LINE_NONE;
1869 lclExtractColor( maLineData.mnColorIdx, rDffPropSet, DFF_Prop_lineColor );
1870 ::set_flag( maLineData.mnAuto, EXC_OBJ_FILL_AUTO, false );
1873 bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const
1875 return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() );
1878 void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const
1880 if( maTextData.mxString.is() )
1882 const XclFormatRunVec& rFormatRuns = maTextData.mxString->GetFormats();
1883 if( rFormatRuns.empty() )
1884 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
1885 else
1886 GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, rFormatRuns.front().mnFontIdx );
1890 void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const
1892 if( maTextData.mxString.is() )
1894 String aLabel = maTextData.mxString->GetText();
1895 if( maTextData.maData.mnShortcut > 0 )
1897 xub_StrLen nPos = aLabel.Search( static_cast< sal_Unicode >( maTextData.maData.mnShortcut ) );
1898 if( nPos != STRING_NOTFOUND )
1899 aLabel.Insert( '~', nPos );
1901 rPropSet.SetStringProperty( CREATE_OUSTRING( "Label" ), aLabel );
1903 ConvertFont( rPropSet );
1906 SdrObject* XclImpTbxObjBase::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const
1908 SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) );
1909 rProgress.Progress();
1910 return xSdrObj.release();
1913 void XclImpTbxObjBase::DoProcessSdrObj( SdrObject& /*rSdrObj*/ ) const
1915 // do not call DoProcessSdrObj() from base class (to skip text processing)
1916 ProcessControl( *this );
1919 // ----------------------------------------------------------------------------
1921 XclImpButtonObj::XclImpButtonObj( const XclImpRoot& rRoot ) :
1922 XclImpTbxObjBase( rRoot )
1926 void XclImpButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
1928 // label and text formatting
1929 ConvertLabel( rPropSet );
1931 /* Horizontal text alignment. For unknown reason, the property type is a
1932 simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
1933 sal_Int16 nHorAlign = 1;
1934 switch( maTextData.maData.GetHorAlign() )
1936 case EXC_OBJ_HOR_LEFT: nHorAlign = 0; break;
1937 case EXC_OBJ_HOR_CENTER: nHorAlign = 1; break;
1938 case EXC_OBJ_HOR_RIGHT: nHorAlign = 2; break;
1940 rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), nHorAlign );
1942 // vertical text alignment
1943 namespace csss = ::com::sun::star::style;
1944 csss::VerticalAlignment eVerAlign = csss::VerticalAlignment_MIDDLE;
1945 switch( maTextData.maData.GetVerAlign() )
1947 case EXC_OBJ_VER_TOP: eVerAlign = csss::VerticalAlignment_TOP; break;
1948 case EXC_OBJ_VER_CENTER: eVerAlign = csss::VerticalAlignment_MIDDLE; break;
1949 case EXC_OBJ_VER_BOTTOM: eVerAlign = csss::VerticalAlignment_BOTTOM; break;
1951 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), eVerAlign );
1953 // always wrap text automatically
1954 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
1956 // default button
1957 bool bDefButton = ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_DEFAULT );
1958 rPropSet.SetBoolProperty( CREATE_OUSTRING( "DefaultButton" ), bDefButton );
1960 // button type (flags cannot be combined in OOo)
1961 namespace cssa = ::com::sun::star::awt;
1962 cssa::PushButtonType eButtonType = cssa::PushButtonType_STANDARD;
1963 if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CLOSE ) )
1964 eButtonType = cssa::PushButtonType_OK;
1965 else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CANCEL ) )
1966 eButtonType = cssa::PushButtonType_CANCEL;
1967 else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_HELP ) )
1968 eButtonType = cssa::PushButtonType_HELP;
1969 // property type is short, not enum
1970 rPropSet.SetProperty( CREATE_OUSTRING( "PushButtonType" ), sal_Int16( eButtonType ) );
1973 OUString XclImpButtonObj::DoGetServiceName() const
1975 return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" );
1978 XclTbxEventType XclImpButtonObj::DoGetEventType() const
1980 return EXC_TBX_EVENT_ACTION;
1983 // ----------------------------------------------------------------------------
1985 XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot& rRoot ) :
1986 XclImpTbxObjBase( rRoot ),
1987 mnState( EXC_OBJ_CHECKBOX_UNCHECKED ),
1988 mnCheckBoxFlags( 0 )
1992 void XclImpCheckBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
1994 ReadFrameData( rStrm );
1995 rStrm.Ignore( 10 );
1996 rStrm >> maTextData.maData.mnFlags;
1997 rStrm.Ignore( 20 );
1998 ReadName5( rStrm, nNameLen );
1999 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2000 ReadCellLinkFormula( rStrm, true );
2001 rStrm >> maTextData.maData.mnTextLen;
2002 maTextData.ReadByteString( rStrm );
2003 rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
2006 void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2008 switch( nSubRecId )
2010 case EXC_ID_OBJCBLS:
2011 // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
2012 rStrm >> mnState;
2013 rStrm.Ignore( 4 );
2014 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
2015 break;
2016 case EXC_ID_OBJCBLSFMLA:
2017 ReadCellLinkFormula( rStrm, false );
2018 break;
2019 default:
2020 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2024 void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2026 // label and text formatting
2027 ConvertLabel( rPropSet );
2029 // state
2030 bool bSupportsTristate = GetObjType() == EXC_OBJTYPE_CHECKBOX;
2031 sal_Int16 nApiState = 0;
2032 switch( mnState )
2034 case EXC_OBJ_CHECKBOX_UNCHECKED: nApiState = 0; break;
2035 case EXC_OBJ_CHECKBOX_CHECKED: nApiState = 1; break;
2036 case EXC_OBJ_CHECKBOX_TRISTATE: nApiState = bSupportsTristate ? 2 : 1; break;
2038 if( bSupportsTristate )
2039 rPropSet.SetBoolProperty( CREATE_OUSTRING( "TriState" ), nApiState == 2 );
2040 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultState" ), nApiState );
2042 // box style
2043 namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2044 sal_Int16 nEffect = ::get_flagvalue( mnCheckBoxFlags, EXC_OBJ_CHECKBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2045 rPropSet.SetProperty( CREATE_OUSTRING( "VisualEffect" ), nEffect );
2047 // do not wrap text automatically
2048 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), false );
2050 // #i40279# always centered vertically
2051 namespace csss = ::com::sun::star::style;
2052 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_MIDDLE );
2054 // background color
2055 if( maFillData.IsFilled() )
2057 sal_Int32 nColor = static_cast< sal_Int32 >( GetSolidFillColor( maFillData ).GetColor() );
2058 rPropSet.SetProperty( CREATE_OUSTRING( "BackgroundColor" ), nColor );
2062 OUString XclImpCheckBoxObj::DoGetServiceName() const
2064 return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" );
2067 XclTbxEventType XclImpCheckBoxObj::DoGetEventType() const
2069 return EXC_TBX_EVENT_ACTION;
2072 // ----------------------------------------------------------------------------
2074 XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot& rRoot ) :
2075 XclImpCheckBoxObj( rRoot ),
2076 mnNextInGroup( 0 ),
2077 mnFirstInGroup( 1 )
2081 void XclImpOptionButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2083 ReadFrameData( rStrm );
2084 rStrm.Ignore( 10 );
2085 rStrm >> maTextData.maData.mnFlags;
2086 rStrm.Ignore( 32 );
2087 ReadName5( rStrm, nNameLen );
2088 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2089 ReadCellLinkFormula( rStrm, true );
2090 rStrm >> maTextData.maData.mnTextLen;
2091 maTextData.ReadByteString( rStrm );
2092 rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA;
2093 rStrm >> mnCheckBoxFlags >> mnNextInGroup >> mnFirstInGroup;
2096 void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2098 switch( nSubRecId )
2100 case EXC_ID_OBJRBODATA:
2101 rStrm >> mnNextInGroup >> mnFirstInGroup;
2102 break;
2103 default:
2104 XclImpCheckBoxObj::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2108 void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2110 XclImpCheckBoxObj::DoProcessControl( rPropSet );
2111 // TODO: grouping
2112 XclImpOptionButtonObj* pTbxObj = dynamic_cast< XclImpOptionButtonObj* >( GetObjectManager().FindDrawObj( XclObjId( GetScTab(), mnNextInGroup ) ).get() );
2113 if ( ( pTbxObj && pTbxObj->mnFirstInGroup ) )
2115 // Group has terminated
2116 // traverse each RadioButton in group and
2117 // a) apply the groupname
2118 // b) propagate the linked cell from the lead radiobutton
2119 // c) apply the correct Ref value
2120 XclImpOptionButtonObj* pLeader = pTbxObj;
2122 sal_Int32 nRefVal = 1;
2123 OSL_TRACE( "0x%x start group ", pLeader->GetObjId().mnObjId );
2127 Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( pTbxObj->mxShape );
2128 if ( xCtrlModel.is() )
2130 ScfPropertySet aProps( xCtrlModel );
2131 rtl::OUString sGroupName = rtl::OUString::valueOf( static_cast< sal_Int32 >( pLeader->GetDffShapeId() ) );
2133 aProps.SetStringProperty( CREATE_OUSTRING( "GroupName" ), sGroupName );
2134 aProps.SetStringProperty( CREATE_OUSTRING( "RefValue" ), rtl::OUString::valueOf( nRefVal++ ) );
2135 if ( pLeader->HasCellLink() && !pTbxObj->HasCellLink() )
2137 // propagate cell link info
2138 pTbxObj->mxCellLink.reset( new ScAddress( *pLeader->mxCellLink.get() ) );
2139 pTbxObj->ApplySheetLinkProps();
2141 pTbxObj = dynamic_cast< XclImpOptionButtonObj* >( GetObjectManager().FindDrawObj( XclObjId( GetScTab(), pTbxObj->mnNextInGroup ) ).get() );
2143 else
2144 pTbxObj = NULL;
2145 } while ( pTbxObj && !( pTbxObj->mnFirstInGroup == 1 ) );
2147 else
2149 // not the leader? try and find it
2153 OUString XclImpOptionButtonObj::DoGetServiceName() const
2155 return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
2158 XclTbxEventType XclImpOptionButtonObj::DoGetEventType() const
2160 return EXC_TBX_EVENT_ACTION;
2163 // ----------------------------------------------------------------------------
2165 XclImpLabelObj::XclImpLabelObj( const XclImpRoot& rRoot ) :
2166 XclImpTbxObjBase( rRoot )
2170 void XclImpLabelObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2172 // label and text formatting
2173 ConvertLabel( rPropSet );
2175 // text alignment (always top/left aligned)
2176 rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), sal_Int16( 0 ) );
2177 namespace csss = ::com::sun::star::style;
2178 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_TOP );
2180 // always wrap text automatically
2181 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
2184 OUString XclImpLabelObj::DoGetServiceName() const
2186 return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" );
2189 XclTbxEventType XclImpLabelObj::DoGetEventType() const
2191 return EXC_TBX_EVENT_MOUSE;
2194 // ----------------------------------------------------------------------------
2196 XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot& rRoot ) :
2197 XclImpTbxObjBase( rRoot ),
2198 mnGroupBoxFlags( 0 )
2202 void XclImpGroupBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2204 ReadFrameData( rStrm );
2205 rStrm.Ignore( 10 );
2206 rStrm >> maTextData.maData.mnFlags;
2207 rStrm.Ignore( 26 );
2208 ReadName5( rStrm, nNameLen );
2209 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2210 rStrm >> maTextData.maData.mnTextLen;
2211 maTextData.ReadByteString( rStrm );
2212 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
2215 void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2217 switch( nSubRecId )
2219 case EXC_ID_OBJGBODATA:
2220 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
2221 break;
2222 default:
2223 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2227 void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2229 // label and text formatting
2230 ConvertLabel( rPropSet );
2233 OUString XclImpGroupBoxObj::DoGetServiceName() const
2235 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2238 XclTbxEventType XclImpGroupBoxObj::DoGetEventType() const
2240 return EXC_TBX_EVENT_MOUSE;
2243 // ----------------------------------------------------------------------------
2245 XclImpDialogObj::XclImpDialogObj( const XclImpRoot& rRoot ) :
2246 XclImpTbxObjBase( rRoot )
2250 void XclImpDialogObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2252 // label and text formatting
2253 ConvertLabel( rPropSet );
2256 OUString XclImpDialogObj::DoGetServiceName() const
2258 // dialog frame faked by a groupbox
2259 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2262 XclTbxEventType XclImpDialogObj::DoGetEventType() const
2264 return EXC_TBX_EVENT_MOUSE;
2267 // ----------------------------------------------------------------------------
2269 XclImpEditObj::XclImpEditObj( const XclImpRoot& rRoot ) :
2270 XclImpTbxObjBase( rRoot ),
2271 mnContentType( EXC_OBJ_EDIT_TEXT ),
2272 mnMultiLine( 0 ),
2273 mnScrollBar( 0 ),
2274 mnListBoxObjId( 0 )
2278 bool XclImpEditObj::IsNumeric() const
2280 return (mnContentType == EXC_OBJ_EDIT_INTEGER) || (mnContentType == EXC_OBJ_EDIT_DOUBLE);
2283 void XclImpEditObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2285 ReadFrameData( rStrm );
2286 rStrm.Ignore( 10 );
2287 rStrm >> maTextData.maData.mnFlags;
2288 rStrm.Ignore( 14 );
2289 ReadName5( rStrm, nNameLen );
2290 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2291 rStrm >> maTextData.maData.mnTextLen;
2292 maTextData.ReadByteString( rStrm );
2293 rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
2296 void XclImpEditObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2298 switch( nSubRecId )
2300 case EXC_ID_OBJEDODATA:
2301 rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
2302 break;
2303 default:
2304 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2308 void XclImpEditObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2310 if( maTextData.mxString.is() )
2312 OUString aText = maTextData.mxString->GetText();
2313 if( IsNumeric() )
2315 // TODO: OUString::toDouble() does not handle local decimal separator
2316 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultValue" ), aText.toDouble() );
2317 rPropSet.SetBoolProperty( CREATE_OUSTRING( "Spin" ), mnScrollBar != 0 );
2319 else
2321 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultText" ), aText );
2322 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), mnMultiLine != 0 );
2323 rPropSet.SetBoolProperty( CREATE_OUSTRING( "VScroll" ), mnScrollBar != 0 );
2326 ConvertFont( rPropSet );
2329 OUString XclImpEditObj::DoGetServiceName() const
2331 return IsNumeric() ?
2332 CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ) :
2333 CREATE_OUSTRING( "com.sun.star.form.component.TextField" );
2336 XclTbxEventType XclImpEditObj::DoGetEventType() const
2338 return EXC_TBX_EVENT_TEXT;
2341 // ----------------------------------------------------------------------------
2343 XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot& rRoot ) :
2344 XclImpTbxObjBase( rRoot ),
2345 mnValue( 0 ),
2346 mnMin( 0 ),
2347 mnMax( 100 ),
2348 mnStep( 1 ),
2349 mnPageStep( 10 ),
2350 mnOrient( 0 ),
2351 mnThumbWidth( 1 ),
2352 mnScrollFlags( 0 )
2356 void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream& rStrm )
2358 rStrm.Ignore( 4 );
2359 rStrm >> mnValue >> mnMin >> mnMax >> mnStep >> mnPageStep >> mnOrient >> mnThumbWidth >> mnScrollFlags;
2362 void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2364 switch( nSubRecId )
2366 case EXC_ID_OBJSBS:
2367 ReadSbs( rStrm );
2368 break;
2369 case EXC_ID_OBJSBSFMLA:
2370 ReadCellLinkFormula( rStrm, false );
2371 break;
2372 default:
2373 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2377 // ----------------------------------------------------------------------------
2379 XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot& rRoot ) :
2380 XclImpTbxObjScrollableBase( rRoot )
2384 void XclImpSpinButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2386 ReadFrameData( rStrm );
2387 ReadSbs( rStrm );
2388 ReadName5( rStrm, nNameLen );
2389 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2390 ReadCellLinkFormula( rStrm, true );
2393 void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2395 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2396 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
2397 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultSpinValue" ), mnValue );
2398 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMin" ), mnMin );
2399 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMax" ), mnMax );
2400 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinIncrement" ), mnStep );
2402 // Excel spin buttons always vertical
2403 rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), ::com::sun::star::awt::ScrollBarOrientation::VERTICAL );
2406 OUString XclImpSpinButtonObj::DoGetServiceName() const
2408 return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
2411 XclTbxEventType XclImpSpinButtonObj::DoGetEventType() const
2413 return EXC_TBX_EVENT_VALUE;
2416 // ----------------------------------------------------------------------------
2418 XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot& rRoot ) :
2419 XclImpTbxObjScrollableBase( rRoot )
2423 void XclImpScrollBarObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2425 ReadFrameData( rStrm );
2426 ReadSbs( rStrm );
2427 ReadName5( rStrm, nNameLen );
2428 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2429 ReadCellLinkFormula( rStrm, true );
2432 void XclImpScrollBarObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2434 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2435 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
2436 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultScrollValue" ), mnValue );
2437 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMin" ), mnMin );
2438 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMax" ), mnMax );
2439 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "LineIncrement" ), mnStep );
2440 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BlockIncrement" ), mnPageStep );
2441 rPropSet.SetProperty( CREATE_OUSTRING( "VisibleSize" ), ::std::min< sal_Int32 >( mnPageStep, 1 ) );
2443 namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
2444 sal_Int32 nApiOrient = ::get_flagvalue( mnOrient, EXC_OBJ_SCROLLBAR_HOR, AwtScrollOrient::HORIZONTAL, AwtScrollOrient::VERTICAL );
2445 rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), nApiOrient );
2448 OUString XclImpScrollBarObj::DoGetServiceName() const
2450 return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
2453 XclTbxEventType XclImpScrollBarObj::DoGetEventType() const
2455 return EXC_TBX_EVENT_VALUE;
2458 // ----------------------------------------------------------------------------
2460 XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot& rRoot ) :
2461 XclImpTbxObjScrollableBase( rRoot ),
2462 mnEntryCount( 0 ),
2463 mnSelEntry( 0 ),
2464 mnListFlags( 0 ),
2465 mnEditObjId( 0 ),
2466 mbHasDefFontIdx( false )
2470 void XclImpTbxObjListBase::ReadLbsData( XclImpStream& rStrm )
2472 ReadSourceRangeFormula( rStrm, true );
2473 rStrm >> mnEntryCount >> mnSelEntry >> mnListFlags >> mnEditObjId;
2476 void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet& rPropSet ) const
2478 // border style
2479 namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2480 sal_Int16 nApiBorder = ::get_flagvalue( mnListFlags, EXC_OBJ_LISTBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2481 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), nApiBorder );
2483 // font formatting
2484 if( mbHasDefFontIdx )
2485 GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, maTextData.maData.mnDefFontIdx );
2486 else
2487 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
2490 // ----------------------------------------------------------------------------
2492 XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot& rRoot ) :
2493 XclImpTbxObjListBase( rRoot )
2497 void XclImpListBoxObj::ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft )
2499 sal_Size nRecEnd = rStrm.GetRecPos() + nRecLeft;
2500 ReadLbsData( rStrm );
2501 DBG_ASSERT( (rStrm.GetRecPos() == nRecEnd) || (rStrm.GetRecPos() + mnEntryCount == nRecEnd),
2502 "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
2503 while( rStrm.IsValid() && (rStrm.GetRecPos() < nRecEnd) )
2504 maSelection.push_back( rStrm.ReaduInt8() );
2507 void XclImpListBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2509 ReadFrameData( rStrm );
2510 ReadSbs( rStrm );
2511 rStrm.Ignore( 18 );
2512 rStrm >> maTextData.maData.mnDefFontIdx;
2513 rStrm.Ignore( 4 );
2514 ReadName5( rStrm, nNameLen );
2515 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2516 ReadCellLinkFormula( rStrm, true );
2517 ReadFullLbsData( rStrm, rStrm.GetRecLeft() );
2518 mbHasDefFontIdx = true;
2521 void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2523 switch( nSubRecId )
2525 case EXC_ID_OBJLBSDATA:
2526 ReadFullLbsData( rStrm, nSubRecSize );
2527 break;
2528 default:
2529 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2533 void XclImpListBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2535 // listbox formatting
2536 SetBoxFormatting( rPropSet );
2538 // selection type
2539 sal_uInt8 nSelType = ::extract_value< sal_uInt8 >( mnListFlags, 4, 2 );
2540 bool bMultiSel = nSelType != EXC_OBJ_LISTBOX_SINGLE;
2541 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiSelection" ), bMultiSel );
2543 // selection (do not set, if listbox is linked to a cell)
2544 if( !HasCellLink() )
2546 ScfInt16Vec aSelVec;
2548 // multi selection: API expects sequence of list entry indexes
2549 if( bMultiSel )
2550 for( ScfUInt8Vec::const_iterator aBeg = maSelection.begin(), aIt = aBeg, aEnd = maSelection.end(); aIt != aEnd; ++aIt )
2551 if( *aIt != 0 )
2552 aSelVec.push_back( static_cast< sal_Int16 >( aIt - aBeg ) );
2553 // single selection: mnSelEntry is one-based, API expects zero-based
2554 else if( mnSelEntry > 0 )
2555 aSelVec.push_back( static_cast< sal_Int16 >( mnSelEntry - 1 ) );
2557 if( !aSelVec.empty() )
2559 Sequence< sal_Int16 > aSelSeq( &aSelVec.front(), static_cast< sal_Int32 >( aSelVec.size() ) );
2560 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
2565 OUString XclImpListBoxObj::DoGetServiceName() const
2567 return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2570 XclTbxEventType XclImpListBoxObj::DoGetEventType() const
2572 return EXC_TBX_EVENT_CHANGE;
2575 // ----------------------------------------------------------------------------
2577 XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot& rRoot ) :
2578 XclImpTbxObjListBase( rRoot ),
2579 mnLeft( 0 ),
2580 mnTop( 0 ),
2581 mnRight( 0 ),
2582 mnBottom( 0 ),
2583 mnDropDownFlags( 0 ),
2584 mnLineCount( 0 ),
2585 mnMinWidth( 0 )
2589 sal_uInt16 XclImpDropDownObj::GetDropDownType() const
2591 return ::extract_value< sal_uInt8 >( mnDropDownFlags, 0, 2 );
2594 void XclImpDropDownObj::ReadFullLbsData( XclImpStream& rStrm )
2596 ReadLbsData( rStrm );
2597 rStrm >> mnDropDownFlags >> mnLineCount >> mnMinWidth >> maTextData.maData.mnTextLen;
2598 maTextData.ReadByteString( rStrm );
2599 // dropdowns of auto-filters have 'simple' style, they don't have a text area
2600 if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE )
2601 SetProcessSdrObj( false );
2604 void XclImpDropDownObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2606 ReadFrameData( rStrm );
2607 ReadSbs( rStrm );
2608 rStrm.Ignore( 18 );
2609 rStrm >> maTextData.maData.mnDefFontIdx;
2610 rStrm.Ignore( 14 );
2611 rStrm >> mnLeft >> mnTop >> mnRight >> mnBottom;
2612 rStrm.Ignore( 4 );
2613 ReadName5( rStrm, nNameLen );
2614 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2615 ReadCellLinkFormula( rStrm, true );
2616 ReadFullLbsData( rStrm );
2617 mbHasDefFontIdx = true;
2620 void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2622 switch( nSubRecId )
2624 case EXC_ID_OBJLBSDATA:
2625 ReadFullLbsData( rStrm );
2626 break;
2627 default:
2628 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2632 void XclImpDropDownObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2634 // dropdown listbox formatting
2635 SetBoxFormatting( rPropSet );
2636 // enable dropdown button
2637 rPropSet.SetBoolProperty( CREATE_OUSTRING( "Dropdown" ), true );
2638 // dropdown line count
2639 rPropSet.SetProperty( CREATE_OUSTRING( "LineCount" ), mnLineCount );
2641 if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX )
2643 // text of editable combobox
2644 if( maTextData.mxString.is() )
2645 rPropSet.SetStringProperty( CREATE_OUSTRING( "DefaultText" ), maTextData.mxString->GetText() );
2647 else
2649 // selection (do not set, if dropdown is linked to a cell)
2650 if( !HasCellLink() && (mnSelEntry > 0) )
2652 Sequence< sal_Int16 > aSelSeq( 1 );
2653 aSelSeq[ 0 ] = mnSelEntry - 1;
2654 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
2659 OUString XclImpDropDownObj::DoGetServiceName() const
2661 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ?
2662 CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ) :
2663 CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2666 XclTbxEventType XclImpDropDownObj::DoGetEventType() const
2668 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ? EXC_TBX_EVENT_TEXT : EXC_TBX_EVENT_CHANGE;
2671 // ----------------------------------------------------------------------------
2673 XclImpPictureObj::XclImpPictureObj( const XclImpRoot& rRoot ) :
2674 XclImpRectObj( rRoot ),
2675 XclImpControlHelper( rRoot, EXC_CTRL_BINDCONTENT ),
2676 mnStorageId( 0 ),
2677 mnCtlsStrmPos( 0 ),
2678 mnCtlsStrmSize( 0 ),
2679 mbEmbedded( false ),
2680 mbLinked( false ),
2681 mbSymbol( false ),
2682 mbControl( false ),
2683 mbUseCtlsStrm( false )
2685 SetAreaObj( true );
2686 SetSimpleMacro( false );
2687 SetCustomDffObj( true );
2690 String XclImpPictureObj::GetOleStorageName() const
2692 String aStrgName;
2693 if( (mbEmbedded || mbLinked) && !mbControl && (mnStorageId > 0) )
2695 aStrgName = mbEmbedded ? EXC_STORAGE_OLE_EMBEDDED : EXC_STORAGE_OLE_LINKED;
2696 static const sal_Char spcHexChars[] = "0123456789ABCDEF";
2697 for( sal_uInt8 nIndex = 32; nIndex > 0; nIndex -= 4 )
2698 aStrgName.Append( sal_Unicode( spcHexChars[ ::extract_value< sal_uInt8 >( mnStorageId, nIndex - 4, 4 ) ] ) );
2700 return aStrgName;
2703 void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2705 sal_uInt16 nLinkSize;
2706 ReadFrameData( rStrm );
2707 rStrm.Ignore( 6 );
2708 rStrm >> nLinkSize;
2709 rStrm.Ignore( 2 );
2710 ReadFlags3( rStrm );
2711 ReadMacro3( rStrm, nMacroSize );
2712 ReadPictFmla( rStrm, nLinkSize );
2714 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2715 maGraphic = XclImpObjectManager::ReadImgData( rStrm );
2718 void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2720 sal_uInt16 nLinkSize;
2721 ReadFrameData( rStrm );
2722 rStrm.Ignore( 6 );
2723 rStrm >> nLinkSize;
2724 rStrm.Ignore( 2 );
2725 ReadFlags3( rStrm );
2726 ReadMacro4( rStrm, nMacroSize );
2727 ReadPictFmla( rStrm, nLinkSize );
2729 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2730 maGraphic = XclImpObjectManager::ReadImgData( rStrm );
2733 void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
2735 sal_uInt16 nLinkSize;
2736 ReadFrameData( rStrm );
2737 rStrm.Ignore( 6 );
2738 rStrm >> nLinkSize;
2739 rStrm.Ignore( 2 );
2740 ReadFlags3( rStrm );
2741 rStrm.Ignore( 4 );
2742 ReadName5( rStrm, nNameLen );
2743 ReadMacro5( rStrm, nMacroSize );
2744 ReadPictFmla( rStrm, nLinkSize );
2746 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2748 // page background is stored as hidden picture with name "__BkgndObj"
2749 if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) )
2750 GetPageSettings().ReadImgData( rStrm );
2751 else
2752 maGraphic = XclImpObjectManager::ReadImgData( rStrm );
2756 void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2758 switch( nSubRecId )
2760 case EXC_ID_OBJFLAGS:
2761 ReadFlags8( rStrm );
2762 break;
2763 case EXC_ID_OBJPICTFMLA:
2764 ReadPictFmla( rStrm, rStrm.ReaduInt16() );
2765 break;
2766 default:
2767 XclImpDrawObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2771 SdrObject* XclImpPictureObj::DoCreateSdrObj( const Rectangle& rAnchorRect, ScfProgressBar& rProgress ) const
2773 // try to create an OLE object or form control
2774 SdrObjectPtr xSdrObj( GetObjectManager().GetDffManager().CreateSdrObject( *this, rAnchorRect ) );
2776 // no OLE - create a plain picture from IMGDATA record data
2777 if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) )
2779 xSdrObj.reset( new SdrGrafObj( maGraphic, rAnchorRect ) );
2780 ConvertRectStyle( *xSdrObj );
2783 rProgress.Progress();
2784 return xSdrObj.release();
2787 void XclImpPictureObj::DoProcessSdrObj( SdrObject& rSdrObj ) const
2789 if( IsOcxControl() )
2791 // do not call XclImpRectObj::DoProcessSdrObj(), it would trace missing "printable" feature
2792 ProcessControl( *this );
2794 else if( mbEmbedded || mbLinked )
2796 // trace missing "printable" feature
2797 XclImpRectObj::DoProcessSdrObj( rSdrObj );
2799 SfxObjectShell* pDocShell = GetDocShell();
2800 SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj );
2801 if( pOleSdrObj && pDocShell )
2803 comphelper::EmbeddedObjectContainer& rEmbObjCont = pDocShell->GetEmbeddedObjectContainer();
2804 Reference< XEmbeddedObject > xEmbObj = pOleSdrObj->GetObjRef();
2805 OUString aOldName( pOleSdrObj->GetPersistName() );
2807 /* The object persistence should be already in the storage, but
2808 the object still might not be inserted into the container. */
2809 if( rEmbObjCont.HasEmbeddedObject( aOldName ) )
2811 if( !rEmbObjCont.HasEmbeddedObject( xEmbObj ) )
2812 // filter code is allowed to call the following method
2813 rEmbObjCont.AddEmbeddedObject( xEmbObj, aOldName );
2815 else
2817 /* If the object is still not in container it must be inserted
2818 there, the name must be generated in this case. */
2819 OUString aNewName;
2820 rEmbObjCont.InsertEmbeddedObject( xEmbObj, aNewName );
2821 if( aOldName != aNewName )
2822 // #95381# SetPersistName, not SetName
2823 pOleSdrObj->SetPersistName( aNewName );
2829 void XclImpPictureObj::ReadFlags3( XclImpStream& rStrm )
2831 sal_uInt16 nFlags;
2832 rStrm >> nFlags;
2833 mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
2836 void XclImpPictureObj::ReadFlags8( XclImpStream& rStrm )
2838 sal_uInt16 nFlags;
2839 rStrm >> nFlags;
2840 mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
2841 mbControl = ::get_flag( nFlags, EXC_OBJ_PIC_CONTROL );
2842 mbUseCtlsStrm = ::get_flag( nFlags, EXC_OBJ_PIC_CTLSSTREAM );
2843 DBG_ASSERT( mbControl || !mbUseCtlsStrm, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
2844 SetProcessSdrObj( mbControl || !mbUseCtlsStrm );
2847 void XclImpPictureObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize )
2849 sal_Size nLinkEnd = rStrm.GetRecPos() + nLinkSize;
2850 if( nLinkSize >= 6 )
2852 sal_uInt16 nFmlaSize;
2853 rStrm >> nFmlaSize;
2854 DBG_ASSERT( nFmlaSize > 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
2855 // BIFF3/BIFF4 do not support storages, nothing to do here
2856 if( (nFmlaSize > 0) && (GetBiff() >= EXC_BIFF5) )
2858 rStrm.Ignore( 4 );
2859 sal_uInt8 nToken;
2860 rStrm >> nToken;
2862 // different processing for linked vs. embedded OLE objects
2863 if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
2865 mbLinked = true;
2866 switch( GetBiff() )
2868 case EXC_BIFF5:
2870 sal_Int16 nRefIdx;
2871 sal_uInt16 nNameIdx;
2872 rStrm >> nRefIdx;
2873 rStrm.Ignore( 8 );
2874 rStrm >> nNameIdx;
2875 rStrm.Ignore( 12 );
2876 const ExtName* pExtName = GetOldRoot().pExtNameBuff->GetNameByIndex( nRefIdx, nNameIdx );
2877 if( pExtName && pExtName->IsOLE() )
2878 mnStorageId = pExtName->nStorageId;
2880 break;
2881 case EXC_BIFF8:
2883 sal_uInt16 nXti, nExtName;
2884 rStrm >> nXti >> nExtName;
2885 const XclImpExtName* pExtName = GetLinkManager().GetExternName( nXti, nExtName );
2886 if( pExtName && (pExtName->GetType() == xlExtOLE) )
2887 mnStorageId = pExtName->GetStorageId();
2889 break;
2890 default:
2891 DBG_ERROR_BIFF();
2894 else if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL, EXC_TOKCLASS_NONE ) )
2896 mbEmbedded = true;
2897 DBG_ASSERT( nFmlaSize == 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
2898 rStrm.Ignore( nFmlaSize - 1 ); // token ID already read
2899 if( nFmlaSize & 1 )
2900 rStrm.Ignore( 1 ); // padding byte
2902 // a class name may follow inside the picture link
2903 if( rStrm.GetRecPos() + 2 <= nLinkEnd )
2905 sal_uInt16 nLen;
2906 rStrm >> nLen;
2907 if( nLen > 0 )
2908 maClassName = (GetBiff() == EXC_BIFF8) ? rStrm.ReadUniString( nLen ) : rStrm.ReadRawByteString( nLen );
2911 // else: ignore other formulas, e.g. pictures linked to cell ranges
2915 // seek behind picture link data
2916 rStrm.Seek( nLinkEnd );
2918 // read additional data for embedded OLE objects following the picture link
2919 if( IsOcxControl() )
2921 // #i26521# form controls to be ignored
2922 if( maClassName.EqualsAscii( "Forms.HTML:Hidden.1" ) )
2924 SetProcessSdrObj( false );
2925 return;
2928 if( rStrm.GetRecLeft() <= 8 ) return;
2930 // position and size of control data in 'Ctls' stream
2931 mnCtlsStrmPos = static_cast< sal_Size >( rStrm.ReaduInt32() );
2932 mnCtlsStrmSize = static_cast< sal_Size >( rStrm.ReaduInt32() );
2934 if( rStrm.GetRecLeft() <= 8 ) return;
2936 // additional string (16-bit characters), e.g. for progress bar control
2937 sal_uInt32 nAddStrSize;
2938 rStrm >> nAddStrSize;
2939 DBG_ASSERT( rStrm.GetRecLeft() >= nAddStrSize + 4, "XclImpPictureObj::ReadPictFmla - missing data" );
2940 if( rStrm.GetRecLeft() >= nAddStrSize + 4 )
2942 rStrm.Ignore( nAddStrSize );
2943 // cell link and source range
2944 ReadCellLinkFormula( rStrm, true );
2945 ReadSourceRangeFormula( rStrm, true );
2948 else if( mbEmbedded && (rStrm.GetRecLeft() >= 4) )
2950 rStrm >> mnStorageId;
2954 // DFF stream conversion ======================================================
2956 //UNUSED2009-05 void XclImpSolverContainer::ReadSolverContainer( SvStream& rDffStrm )
2957 //UNUSED2009-05 {
2958 //UNUSED2009-05 rDffStrm >> *this;
2959 //UNUSED2009-05 }
2961 void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags )
2963 if( nDffShapeId > 0 )
2965 maSdrInfoMap[ nDffShapeId ].Set( &rSdrObj, nDffFlags );
2966 maSdrObjMap[ &rSdrObj ] = nDffShapeId;
2970 void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject& rSdrObj )
2972 // remove info of passed object from the maps
2973 XclImpSdrObjMap::iterator aIt = maSdrObjMap.find( &rSdrObj );
2974 if( aIt != maSdrObjMap.end() )
2976 maSdrInfoMap.erase( aIt->second );
2977 maSdrObjMap.erase( aIt );
2980 // remove info of all child objects of a group object
2981 if( SdrObjGroup* pGroupObj = dynamic_cast< SdrObjGroup* >( &rSdrObj ) )
2983 if( SdrObjList* pSubList = pGroupObj->GetSubList() )
2985 // iterate flat over the list because this function already works recursively
2986 SdrObjListIter aObjIt( *pSubList, IM_FLAT );
2987 for( SdrObject* pChildObj = aObjIt.Next(); pChildObj; pChildObj = aObjIt.Next() )
2988 RemoveSdrObjectInfo( *pChildObj );
2993 void XclImpSolverContainer::UpdateConnectorRules()
2995 for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
2997 UpdateConnection( pRule->nShapeA, pRule->pAObj, &pRule->nSpFlagsA );
2998 UpdateConnection( pRule->nShapeB, pRule->pBObj, &pRule->nSpFlagsB );
2999 UpdateConnection( pRule->nShapeC, pRule->pCObj );
3003 void XclImpSolverContainer::RemoveConnectorRules()
3005 // base class from SVX uses plain untyped tools/List
3006 for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
3007 delete pRule;
3008 aCList.Clear();
3010 maSdrInfoMap.clear();
3011 maSdrObjMap.clear();
3014 SvxMSDffConnectorRule* XclImpSolverContainer::GetFirstRule()
3016 return static_cast< SvxMSDffConnectorRule* >( aCList.First() );
3019 SvxMSDffConnectorRule* XclImpSolverContainer::GetNextRule()
3021 return static_cast< SvxMSDffConnectorRule* >( aCList.Next() );
3024 void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags )
3026 XclImpSdrInfoMap::const_iterator aIt = maSdrInfoMap.find( nDffShapeId );
3027 if( aIt != maSdrInfoMap.end() )
3029 rpSdrObj = aIt->second.mpSdrObj;
3030 if( pnDffFlags )
3031 *pnDffFlags = aIt->second.mnDffFlags;
3035 // ----------------------------------------------------------------------------
3037 XclImpSimpleDffManager::XclImpSimpleDffManager( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
3038 SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, 0, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, 24, 0, &rRoot.GetTracer().GetBaseTracer() ),
3039 XclImpRoot( rRoot )
3041 SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_EXCEL );
3044 XclImpSimpleDffManager::~XclImpSimpleDffManager()
3048 FASTBOOL XclImpSimpleDffManager::GetColorFromPalette( USHORT nIndex, Color& rColor ) const
3050 ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) );
3052 if( nColor == COL_AUTO )
3053 return FALSE;
3055 rColor.SetColor( nColor );
3056 return TRUE;
3059 // ----------------------------------------------------------------------------
3061 XclImpDffManager::XclImpDffManager(
3062 const XclImpRoot& rRoot, XclImpObjectManager& rObjManager, SvStream& rDffStrm ) :
3063 XclImpSimpleDffManager( rRoot, rDffStrm ),
3064 SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ),
3065 mrObjManager( rObjManager ),
3066 mnOleImpFlags( 0 ),
3067 mnLastCtrlIndex( -1 ),
3068 mnCurrFormScTab( -1 )
3070 if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
3072 if( pFilterOpt->IsMathType2Math() )
3073 mnOleImpFlags |= OLE_MATHTYPE_2_STARMATH;
3074 if( pFilterOpt->IsWinWord2Writer() )
3075 mnOleImpFlags |= OLE_WINWORD_2_STARWRITER;
3076 if( pFilterOpt->IsPowerPoint2Impress() )
3077 mnOleImpFlags |= OLE_POWERPOINT_2_STARIMPRESS;
3080 // try to open the 'Ctls' storage stream containing OCX control properties
3081 mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
3083 // default text margin (convert EMU to drawing layer units)
3084 mnDefTextMargin = EXC_OBJ_TEXT_MARGIN;
3085 ScaleEmu( mnDefTextMargin );
3088 XclImpDffManager::~XclImpDffManager()
3092 String XclImpObjectManager::GetOleNameOverride( const XclObjId& nObjId )
3094 String sOleName;
3095 String sCodeName = GetExtDocOptions().GetCodeName( nObjId.mnScTab );
3097 CodeNameToCntrlObjIdInfo::iterator it = maOleCtrlNameOverride.find( sCodeName );
3098 if ( it != maOleCtrlNameOverride.end() )
3100 CntrlObjIdToName::iterator it_id = it->second.find( nObjId.mnObjId );
3101 if ( it_id != it->second.end() )
3103 sOleName = it_id->second;
3106 return sOleName;
3109 void XclImpDffManager::StartProgressBar( sal_Size nProgressSize )
3111 mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) );
3112 mxProgress->AddSegment( nProgressSize );
3113 mxProgress->Activate();
3116 void XclImpDffManager::ProcessObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj )
3118 Rectangle aAnchorRect = rDrawObj.GetAnchorRect();
3119 if( rDrawObj.IsProcessSdrObj() && rDrawObj.IsValidSize( aAnchorRect ) )
3121 // CreateSdrObject() recursively creates embedded child objects
3122 SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( aAnchorRect, *mxProgress, false ) );
3123 if( xSdrObj.is() )
3124 rDrawObj.ProcessSdrObject( *xSdrObj );
3125 // call InsertSdrObject() also, if SdrObject is missing
3126 InsertSdrObject( pObjList, rDrawObj, xSdrObj.release() );
3127 UpdateUsedArea( rDrawObj );
3131 void XclImpDffManager::ProcessDrawingGroup( SvStream& rDffStrm )
3133 rDffStrm.Seek( STREAM_SEEK_TO_BEGIN );
3134 DffRecordHeader aHeader;
3135 rDffStrm >> aHeader;
3136 if( aHeader.nRecType == DFF_msofbtDggContainer )
3137 ProcessDggContainer( rDffStrm, aHeader );
3138 else
3140 DBG_ERRORFILE( "XclImpDffManager::ProcessDrawingGroup - unexpected record" );
3144 void XclImpDffManager::ProcessDrawing( SvStream& rDffStrm, sal_Size nStrmPos )
3146 rDffStrm.Seek( nStrmPos );
3147 DffRecordHeader aHeader;
3148 rDffStrm >> aHeader;
3149 if( aHeader.nRecType == DFF_msofbtDgContainer )
3150 ProcessDgContainer( rDffStrm, aHeader );
3151 else
3153 DBG_ERRORFILE( "XclImpDffManager::ProcessDrawing - unexpected record" );
3157 SdrObject* XclImpDffManager::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect )
3159 SdrObjectPtr xSdrObj;
3161 OUString aServiceName = rTbxObj.GetServiceName();
3162 if( aServiceName.getLength() > 0 ) try
3164 // create the form control from scratch
3165 Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW );
3166 // set current controls form, needed in virtual function InsertControl()
3167 SetCurrentForm( rTbxObj.GetScTab() );
3168 // try to insert the control into the form
3169 ::com::sun::star::awt::Size aDummySize;
3170 Reference< XShape > xShape;
3171 if( mxCurrForm.is() && InsertControl( xFormComp, aDummySize, &xShape, TRUE ) )
3173 xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
3174 // try to attach a macro to the control
3175 ScriptEventDescriptor aDescriptor;
3176 if( (mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) )
3178 Reference< XEventAttacherManager > xEventMgr( mxCurrForm, UNO_QUERY_THROW );
3179 xEventMgr->registerScriptEvent( mnLastCtrlIndex, aDescriptor );
3183 catch( Exception& )
3187 return xSdrObj.release();
3190 SdrObject* XclImpDffManager::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect )
3192 SdrObjectPtr xSdrObj;
3194 if( rPicObj.IsOcxControl() )
3196 if( mxCtlsStrm.Is() ) try
3198 /* set current controls form, needed in virtual function InsertControl()
3199 called from ReadOCXExcelKludgeStream() */
3200 SetCurrentForm( rPicObj.GetScTab() );
3201 // seek to stream position of the extra data for this control
3202 mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() );
3203 // read from mxCtlsStrm into xShape, insert the control model into the form
3204 Reference< XShape > xShape;
3205 if( mxCurrForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, TRUE ) )
3206 xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
3208 catch( Exception& )
3212 else
3214 SfxObjectShell* pDocShell = GetDocShell();
3215 SotStorageRef xSrcStrg = GetRootStorage();
3216 String aStrgName = rPicObj.GetOleStorageName();
3217 if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) )
3219 // first try to resolve graphic from DFF storage
3220 Graphic aGraphic;
3221 Rectangle aVisArea;
3222 if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) )
3224 // if not found, use graphic from object (imported from IMGDATA record)
3225 aGraphic = rPicObj.GetGraphic();
3226 aVisArea = rPicObj.GetVisArea();
3228 if( aGraphic.GetType() != GRAPHIC_NONE )
3230 ErrCode nError = ERRCODE_NONE;
3231 namespace cssea = ::com::sun::star::embed::Aspects;
3232 sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT;
3233 xSdrObj.reset( CreateSdrOLEFromStorage(
3234 aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic,
3235 rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) );
3240 return xSdrObj.release();
3243 ScRange XclImpDffManager::GetUsedArea( SCTAB nScTab ) const
3245 ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID );
3246 ScRangeMap::const_iterator aIt = maUsedAreaMap.find( nScTab );
3247 if( aIt != maUsedAreaMap.end() )
3248 aScUsedArea = aIt->second;
3249 return aScUsedArea;
3252 // virtual functions ----------------------------------------------------------
3254 void XclImpDffManager::ProcessClientAnchor2( SvStream& rDffStrm,
3255 DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData )
3257 // find the OBJ record data related to the processed shape
3258 if( XclImpDrawObjBase* pDrawObj = mrObjManager.FindDrawObj( rObjData.rSpHd ).get() )
3260 DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffManager::ProcessClientAnchor2 - no client anchor record" );
3261 XclObjAnchor aAnchor( pDrawObj->GetScTab() );
3262 rHeader.SeekToContent( rDffStrm );
3263 rDffStrm.SeekRel( 2 ); // flags
3264 rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records
3265 pDrawObj->SetAnchor( aAnchor );
3266 rObjData.aChildAnchor = pDrawObj->GetAnchorRect();
3267 rObjData.bChildAnchor = sal_True;
3271 SdrObject* XclImpDffManager::ProcessObj( SvStream& rDffStrm,
3272 DffObjData& rDffObjData, void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj )
3274 /* pOldSdrObj passes a generated SdrObject. This function owns this object
3275 and can modify it. The function has either to return it back to caller
3276 or to delete it by itself. */
3277 SdrObjectPtr xSdrObj( pOldSdrObj );
3279 // find the OBJ record data related to the processed shape
3280 XclImpDrawObjRef xDrawObj = mrObjManager.FindDrawObj( rDffObjData.rSpHd );
3281 const Rectangle& rAnchorRect = rDffObjData.aChildAnchor;
3283 // #102378# Do not process the global page group shape (flag SP_FPATRIARCH)
3284 bool bGlobalPageGroup = ::get_flag< sal_uInt32 >( rDffObjData.nSpFlags, SP_FPATRIARCH );
3285 if( !xDrawObj || !xDrawObj->IsProcessSdrObj() || bGlobalPageGroup )
3286 return 0; // simply return, xSdrObj will be destroyed
3288 /* Pass pointer to top-level object back to caller. If the processed
3289 object is embedded in a group, the pointer is already set to the
3290 top-level parent object. */
3291 XclImpDrawObjBase** ppTopLevelObj = reinterpret_cast< XclImpDrawObjBase** >( pClientData );
3292 bool bIsTopLevel = !ppTopLevelObj || !*ppTopLevelObj;
3293 if( ppTopLevelObj && bIsTopLevel )
3294 *ppTopLevelObj = xDrawObj.get();
3296 // #119010# connectors don't have to be area objects
3297 if( dynamic_cast< SdrEdgeObj* >( xSdrObj.get() ) )
3298 xDrawObj->SetAreaObj( false );
3300 /* Check for valid size for all objects. Needed to ignore lots of invisible
3301 phantom objects from deleted rows or columns (for performance reasons).
3302 #i30816# Include objects embedded in groups.
3303 #i58780# Ignore group shapes, size is not initialized. */
3304 bool bEmbeddedGroup = !bIsTopLevel && dynamic_cast< SdrObjGroup* >( xSdrObj.get() );
3305 if( !bEmbeddedGroup && !xDrawObj->IsValidSize( rAnchorRect ) )
3306 return 0; // simply return, xSdrObj will be destroyed
3308 // set shape information from DFF stream
3309 String aObjName = GetPropertyString( DFF_Prop_wzName, rDffStrm );
3310 String aHyperlink = ReadHlinkProperty( rDffStrm );
3311 bool bVisible = !GetPropertyBool( DFF_Prop_fHidden );
3312 bool bAutoMargin = GetPropertyBool( DFF_Prop_AutoTextMargin );
3313 xDrawObj->SetDffData( rDffObjData, aObjName, aHyperlink, bVisible, bAutoMargin );
3315 /* Connect textbox data (string, alignment, text orientation) to object.
3316 #98132# don't ask for a text-ID, DFF export doesn't set one. */
3317 if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) )
3318 if( const XclImpObjTextData* pTextData = mrObjManager.FindTextData( rDffObjData.rSpHd ) )
3319 pTextObj->SetTextData( *pTextData );
3321 // copy line and fill formatting of TBX form controls from DFF properties
3322 if( XclImpTbxObjBase* pTbxObj = dynamic_cast< XclImpTbxObjBase* >( xDrawObj.get() ) )
3323 pTbxObj->SetDffProperties( *this );
3325 // try to create a custom SdrObject that overwrites the passed object
3326 SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( rAnchorRect, *mxProgress, true ) );
3327 if( xNewSdrObj.is() )
3328 xSdrObj.reset( xNewSdrObj.release() );
3330 // process the SdrObject
3331 if( xSdrObj.is() )
3333 // filled without color -> set system window color
3334 if( GetPropertyBool( DFF_Prop_fFilled ) && !IsProperty( DFF_Prop_fillColor ) )
3335 xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) );
3337 // additional processing on the SdrObject
3338 xDrawObj->ProcessSdrObject( *xSdrObj );
3340 // add the area used by this object to the internal map of used areas
3341 UpdateUsedArea( *xDrawObj );
3343 /* If the SdrObject will not be inserted into the draw page, delete it
3344 here. Happens e.g. for notes: The ProcessSdrObject() call above has
3345 inserted the note into the document, and the SdrObject is not
3346 needed anymore. */
3347 if( !xDrawObj->IsInsertSdrObj() )
3348 xSdrObj.reset();
3351 /* Store the relation between shape ID and SdrObject for connectors. Must
3352 be done here (and not in InsertSdrObject() function), otherwise all
3353 SdrObjects embedded in groups would be lost. */
3354 if( xSdrObj.is() )
3355 maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() );
3357 return xSdrObj.release();
3360 ULONG XclImpDffManager::Calc_nBLIPPos( ULONG /*nOrgVal*/, ULONG nStreamPos ) const
3362 return nStreamPos + 4;
3365 sal_Bool XclImpDffManager::InsertControl( const Reference< XFormComponent >& rxFormComp,
3366 const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape,
3367 BOOL /*bFloatingCtrl*/ )
3369 if( GetDocShell() ) try
3371 Reference< XIndexContainer > xFormIC( mxCurrForm, UNO_QUERY_THROW );
3372 Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW );
3374 // create the control shape
3375 Reference< XShape > xShape( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ) ), UNO_QUERY_THROW );
3376 Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY_THROW );
3378 // insert the new control into the form
3379 sal_Int32 nNewIndex = xFormIC->getCount();
3380 xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) );
3381 // on success: store new index of the control for later use (macro events)
3382 mnLastCtrlIndex = nNewIndex;
3384 // set control model at control shape and pass back shape to caller
3385 xCtrlShape->setControl( xCtrlModel );
3386 if( pxShape ) *pxShape = xShape;
3387 return sal_True;
3389 catch( Exception& )
3391 DBG_ERRORFILE( "XclImpDffManager::InsertControl - cannot create form control" );
3394 return sal_False;
3397 // private --------------------------------------------------------------------
3399 String XclImpDffManager::ReadHlinkProperty( SvStream& rDffStrm ) const
3401 /* Reads hyperlink data from a complex DFF property. Contents of this
3402 property are equal to the HLINK record, import of this record is
3403 implemented in class XclImpHyperlink. This function has to create an
3404 instance of the XclImpStream class to be able to reuse the
3405 functionality of XclImpHyperlink. */
3406 String aString;
3407 sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
3408 if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rDffStrm ) )
3410 // create a faked BIFF record that can be read by XclImpStream class
3411 SvMemoryStream aMemStream;
3412 aMemStream << sal_uInt16( 0 ) << static_cast< sal_uInt16 >( nBufferSize );
3414 // copy from DFF stream to memory stream
3415 ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
3416 sal_uInt8* pnData = &aBuffer.front();
3417 if( rDffStrm.Read( pnData, nBufferSize ) == nBufferSize )
3419 aMemStream.Write( pnData, nBufferSize );
3421 // create BIFF import stream to be able to use XclImpHyperlink class
3422 XclImpStream aXclStrm( aMemStream, GetRoot() );
3423 if( aXclStrm.StartNextRecord() )
3424 aString = XclImpHyperlink::ReadEmbeddedData( aXclStrm );
3427 return aString;
3430 void XclImpDffManager::ProcessDggContainer( SvStream& rDffStrm, const DffRecordHeader& rDggHeader )
3432 // seek to end of drawing group container
3433 rDggHeader.SeekToEndOfRecord( rDffStrm );
3436 void XclImpDffManager::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader )
3438 sal_Size nEndPos = rDgHeader.GetRecEndFilePos();
3439 while( rDffStrm.Tell() < nEndPos )
3441 DffRecordHeader aHeader;
3442 rDffStrm >> aHeader;
3443 switch( aHeader.nRecType )
3445 case DFF_msofbtSolverContainer:
3446 ProcessSolverContainer( rDffStrm, aHeader );
3447 break;
3448 case DFF_msofbtSpgrContainer:
3449 ProcessShGrContainer( rDffStrm, aHeader );
3450 break;
3451 default:
3452 aHeader.SeekToEndOfRecord( rDffStrm );
3455 // seek to end of drawing page container
3456 rDgHeader.SeekToEndOfRecord( rDffStrm );
3458 // #i12638# #i37900# connector rules
3459 maSolverCont.UpdateConnectorRules();
3460 SolveSolver( maSolverCont );
3461 maSolverCont.RemoveConnectorRules();
3464 void XclImpDffManager::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader )
3466 sal_Size nEndPos = rShGrHeader.GetRecEndFilePos();
3467 while( rDffStrm.Tell() < nEndPos )
3469 DffRecordHeader aHeader;
3470 rDffStrm >> aHeader;
3471 switch( aHeader.nRecType )
3473 case DFF_msofbtSpgrContainer:
3474 case DFF_msofbtSpContainer:
3475 ProcessShContainer( rDffStrm, aHeader );
3476 break;
3477 default:
3478 aHeader.SeekToEndOfRecord( rDffStrm );
3481 // seek to end of shape group container
3482 rShGrHeader.SeekToEndOfRecord( rDffStrm );
3485 void XclImpDffManager::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader )
3487 // solver container wants to read the solver container header again
3488 rSolverHeader.SeekToBegOfRecord( rDffStrm );
3489 // read the entire solver container
3490 rDffStrm >> maSolverCont;
3491 // seek to end of solver container
3492 rSolverHeader.SeekToEndOfRecord( rDffStrm );
3495 void XclImpDffManager::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader )
3497 rShHeader.SeekToBegOfRecord( rDffStrm );
3498 Rectangle aDummy;
3499 const XclImpDrawObjBase* pDrawObj = 0;
3500 /* The call to ImportObj() creates and returns a new SdrObject for the
3501 processed shape. We take ownership of the returned object here. If the
3502 shape is a group object, all embedded objects are created recursively,
3503 and the returned group object contains them all. ImportObj() calls the
3504 virtual functions ProcessClientAnchor2() and ProcessObj() and writes
3505 the pointer to the related draw object data (OBJ record) into pDrawObj. */
3506 SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy, 0, 0 ) );
3507 if( pDrawObj && xSdrObj.is() )
3508 InsertSdrObject( GetSdrPage( pDrawObj->GetScTab() ), *pDrawObj, xSdrObj.release() );
3509 rShHeader.SeekToEndOfRecord( rDffStrm );
3512 void XclImpDffManager::InsertSdrObject( SdrObjList* pObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj )
3514 /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
3515 states to skip insertion, or missing draw page), the object is
3516 automatically deleted. */
3517 SdrObjectPtr xSdrObj( pSdrObj );
3518 if( pObjList && xSdrObj.is() && rDrawObj.IsInsertSdrObj() )
3519 pObjList->NbcInsertObject( xSdrObj.release() );
3520 // SdrObject still here? Insertion failed, remove data from shape ID map.
3521 if( xSdrObj.is() )
3522 maSolverCont.RemoveSdrObjectInfo( *xSdrObj );
3525 void XclImpDffManager::SetCurrentForm( SCTAB nScTab )
3527 if( nScTab != mnCurrFormScTab )
3529 mxCurrForm.clear();
3530 mnCurrFormScTab = nScTab;
3532 SdrPage* pSdrPage = GetSdrPage( nScTab );
3533 if( GetDocShell() && pSdrPage ) try
3535 Reference< XFormsSupplier > xFormsSupplier( pSdrPage->getUnoPage(), UNO_QUERY_THROW );
3536 Reference< XNameContainer > xFormsNC = xFormsSupplier->getForms();
3537 if( xFormsNC.is() )
3539 // find or create the Standard form used to insert the imported controls
3540 OUString aFormName = CREATE_OUSTRING( "Standard" );
3541 if( xFormsNC->hasByName( aFormName ) )
3543 xFormsNC->getByName( aFormName ) >>= mxCurrForm;
3545 else
3547 mxCurrForm.set( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW );
3548 xFormsNC->insertByName( aFormName, Any( mxCurrForm ) );
3552 catch( Exception& )
3558 void XclImpDffManager::UpdateUsedArea( const XclImpDrawObjBase& rDrawObj )
3560 ScRange aScObjArea = rDrawObj.GetUsedArea();
3561 if( aScObjArea.IsValid() )
3563 ScRange* pScTabArea = 0;
3564 ScRangeMap::iterator aIt = maUsedAreaMap.find( rDrawObj.GetScTab() );
3565 if( aIt == maUsedAreaMap.end() )
3567 pScTabArea = &maUsedAreaMap[ rDrawObj.GetScTab() ];
3568 pScTabArea->SetInvalid();
3570 else
3571 pScTabArea = &aIt->second;
3573 if( pScTabArea )
3574 pScTabArea->ExtendTo( aScObjArea );
3578 // The object manager =========================================================
3580 XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) :
3581 XclImpRoot( rRoot )
3583 maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" );
3584 maDefObjNames[ EXC_OBJTYPE_LINE ] = ScGlobal::GetRscString( STR_SHAPE_LINE );
3585 maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = ScGlobal::GetRscString( STR_SHAPE_RECTANGLE );
3586 maDefObjNames[ EXC_OBJTYPE_OVAL ] = ScGlobal::GetRscString( STR_SHAPE_OVAL );
3587 maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" );
3588 maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" );
3589 maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" );
3590 maDefObjNames[ EXC_OBJTYPE_BUTTON ] = ScGlobal::GetRscString( STR_FORM_BUTTON );
3591 maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" );
3592 maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" );
3593 maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = ScGlobal::GetRscString( STR_FORM_CHECKBOX );
3594 maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = ScGlobal::GetRscString( STR_FORM_OPTIONBUTTON );
3595 maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" );
3596 maDefObjNames[ EXC_OBJTYPE_LABEL ] = ScGlobal::GetRscString( STR_FORM_LABEL );
3597 maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" );
3598 maDefObjNames[ EXC_OBJTYPE_SPIN ] = ScGlobal::GetRscString( STR_FORM_SPINNER );
3599 maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = ScGlobal::GetRscString( STR_FORM_SCROLLBAR );
3600 maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = ScGlobal::GetRscString( STR_FORM_LISTBOX );
3601 maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = ScGlobal::GetRscString( STR_FORM_GROUPBOX );
3602 maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = ScGlobal::GetRscString( STR_FORM_DROPDOWN );
3603 maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" );
3604 maDefObjNames[ EXC_OBJTYPE_DRAWING ] = ScGlobal::GetRscString( STR_SHAPE_AUTOSHAPE );
3607 XclImpObjectManager::~XclImpObjectManager()
3611 // *** Read Excel records *** -------------------------------------------------
3613 Graphic XclImpObjectManager::ReadImgData( XclImpStream& rStrm ) // static helper
3615 Graphic aGraphic;
3616 sal_uInt16 nFormat, nEnv;
3617 sal_uInt32 nDataSize;
3618 rStrm >> nFormat >> nEnv >> nDataSize;
3619 if( nDataSize <= rStrm.GetRecLeft() )
3621 switch( nFormat )
3623 case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rStrm ); break;
3624 case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rStrm ); break;
3625 default: DBG_ERRORFILE( "XclImpObjectManager::ReadImgData - unknown image format" );
3628 return aGraphic;
3631 void XclImpObjectManager::ReadObj( XclImpStream& rStrm )
3633 XclImpDrawObjRef xDrawObj;
3635 /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
3636 records. In this case, the OBJ records are in BIFF5 format. Do a sanity
3637 check here that there is no DFF data loaded before. */
3638 DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpObjectManager::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
3639 if( maDffStrm.Tell() == 0 ) switch( GetBiff() )
3641 case EXC_BIFF3:
3642 xDrawObj = XclImpDrawObjBase::ReadObj3( rStrm );
3643 break;
3644 case EXC_BIFF4:
3645 xDrawObj = XclImpDrawObjBase::ReadObj4( rStrm );
3646 break;
3647 case EXC_BIFF5:
3648 case EXC_BIFF8:
3649 xDrawObj = XclImpDrawObjBase::ReadObj5( rStrm );
3650 break;
3651 default:
3652 DBG_ERROR_BIFF();
3655 if( xDrawObj.is() )
3657 // insert into maRawObjs or into the last open group object
3658 maRawObjs.InsertGrouped( xDrawObj );
3659 // to be able to find objects by ID
3660 maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
3664 void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm )
3666 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
3667 // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
3668 rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP );
3669 ReadDffRecord( rStrm );
3672 void XclImpObjectManager::ReadMsoDrawing( XclImpStream& rStrm )
3674 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
3675 // disable internal CONTINUE handling
3676 rStrm.ResetRecord( false );
3677 /* #i60510# real life: MSODRAWINGSELECTION record may contain garbage -
3678 this makes it impossible to process the DFF stream in one run.
3679 Store stream start position for every sheet separately, will be used
3680 to seek the stream to these positions later, when processing the next
3681 sheet. */
3682 size_t nTabIdx = static_cast< size_t >( GetCurrScTab() );
3683 if( nTabIdx >= maTabStrmPos.size() )
3685 maTabStrmPos.resize( nTabIdx, STREAM_SEEK_TO_END );
3686 maTabStrmPos.push_back( maDffStrm.Tell() );
3688 // read leading MSODRAWING record
3689 ReadDffRecord( rStrm );
3691 // read following drawing records, but do not start following unrelated record
3692 bool bLoop = true;
3693 while( bLoop ) switch( rStrm.GetNextRecId() )
3695 case EXC_ID_MSODRAWING:
3696 case EXC_ID_MSODRAWINGSEL:
3697 case EXC_ID_CONT:
3698 rStrm.StartNextRecord();
3699 ReadDffRecord( rStrm );
3700 break;
3701 case EXC_ID_OBJ:
3702 rStrm.StartNextRecord();
3703 ReadObj8( rStrm );
3704 break;
3705 case EXC_ID_TXO:
3706 rStrm.StartNextRecord();
3707 ReadTxo( rStrm );
3708 break;
3709 default:
3710 bLoop = false;
3713 // re-enable internal CONTINUE handling
3714 rStrm.ResetRecord( true );
3717 void XclImpObjectManager::ReadNote( XclImpStream& rStrm )
3719 switch( GetBiff() )
3721 case EXC_BIFF2:
3722 case EXC_BIFF3:
3723 case EXC_BIFF4:
3724 case EXC_BIFF5:
3725 ReadNote3( rStrm );
3726 break;
3727 case EXC_BIFF8:
3728 ReadNote8( rStrm );
3729 break;
3730 default:
3731 DBG_ERROR_BIFF();
3735 void XclImpObjectManager::ReadTabChart( XclImpStream& rStrm )
3737 DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 );
3738 ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) );
3739 xChartObj->ReadChartSubStream( rStrm );
3740 // insert the chart as raw object without connected DFF data
3741 maRawObjs.push_back( xChartObj );
3744 // *** Drawing objects *** ----------------------------------------------------
3746 XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const DffRecordHeader& rHeader ) const
3748 /* maObjMap stores objects by position of the client data (OBJ record) in
3749 the DFF stream, which is always behind shape start position of the
3750 passed header. The function upper_bound() finds the first element in
3751 the map whose key is greater than the start position of the header. Its
3752 end position is used to test whether the found object is really related
3753 to the shape. */
3754 XclImpDrawObjRef xDrawObj;
3755 XclImpObjMap::const_iterator aIt = maObjMap.upper_bound( rHeader.GetRecBegFilePos() );
3756 if( (aIt != maObjMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
3757 xDrawObj = aIt->second;
3758 return xDrawObj;
3761 XclImpDrawObjRef XclImpObjectManager::FindDrawObj( const XclObjId& rObjId ) const
3763 XclImpDrawObjRef xDrawObj;
3764 XclImpObjMapById::const_iterator aIt = maObjMapId.find( rObjId );
3765 if( aIt != maObjMapId.end() )
3766 xDrawObj = aIt->second;
3767 return xDrawObj;
3770 const XclImpObjTextData* XclImpObjectManager::FindTextData( const DffRecordHeader& rHeader ) const
3772 /* maTextMap stores textbox data by position of the client data (TXO
3773 record) in the DFF stream, which is always behind shape start position
3774 of the passed header. The function upper_bound() finds the first
3775 element in the map whose key is greater than the start position of the
3776 header. Its end position is used to test whether the found object is
3777 really related to the shape. */
3778 XclImpObjTextMap::const_iterator aIt = maTextMap.upper_bound( rHeader.GetRecBegFilePos() );
3779 if( (aIt != maTextMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
3780 return aIt->second.get();
3781 return 0;
3784 void XclImpObjectManager::SetSkipObj( SCTAB nScTab, sal_uInt16 nObjId )
3786 maSkipObjs.push_back( XclObjId( nScTab, nObjId ) );
3789 // *** Drawing object conversion *** ------------------------------------------
3791 XclImpDffManager& XclImpObjectManager::GetDffManager()
3793 if( !mxDffManager )
3794 mxDffManager.reset( new XclImpDffManager( GetRoot(), *this, maDffStrm ) );
3795 return *mxDffManager;
3798 void XclImpObjectManager::ConvertObjects()
3800 RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" );
3802 // do nothing if the document does not contain a drawing layer
3803 if( GetDoc().GetDrawLayer() )
3805 // process list of identifiers of objects to be skipped
3806 for( XclObjIdVec::const_iterator aVIt = maSkipObjs.begin(), aVEnd = maSkipObjs.end(); aVIt != aVEnd; ++aVIt )
3807 if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aVIt ).get() )
3808 pDrawObj->SetProcessSdrObj( false );
3810 // get progress bar size for all valid objects
3811 sal_Size nProgressSize = GetProgressSize();
3812 if( nProgressSize > 0 )
3814 XclImpDffManager& rDffManager = GetDffManager();
3815 rDffManager.StartProgressBar( nProgressSize );
3816 // process drawing objects without DFF data
3817 for( XclImpDrawObjVector::const_iterator aVIt = maRawObjs.begin(), aVEnd = maRawObjs.end(); aVIt != aVEnd; ++aVIt )
3818 rDffManager.ProcessObject( GetSdrPage( (*aVIt)->GetScTab() ), **aVIt );
3819 // process the global DFF container, contains pictures
3820 if( !maTabStrmPos.empty() && (maTabStrmPos.front() > 0) )
3821 rDffManager.ProcessDrawingGroup( maDffStrm );
3822 // process the sheet records, this inserts the objects into the drawing layer
3823 for( StreamPosVec::const_iterator aPIt = maTabStrmPos.begin(), aPEnd = maTabStrmPos.end(); aPIt != aPEnd; ++aPIt )
3824 if( *aPIt != STREAM_SEEK_TO_END )
3825 rDffManager.ProcessDrawing( maDffStrm, *aPIt );
3830 String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const
3832 String aDefName;
3833 DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() );
3834 if( aIt != maDefObjNames.end() )
3835 aDefName.Append( aIt->second );
3836 return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId().mnObjId ) );
3839 ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const
3841 ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID );
3842 if( mxDffManager.is() )
3843 aScUsedArea = mxDffManager->GetUsedArea( nScTab );
3844 return aScUsedArea;
3847 // private --------------------------------------------------------------------
3849 void XclImpObjectManager::ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ) // static helper
3851 // extract graphic data from IMGDATA and following CONTINUE records
3852 rStrm.Ignore( 8 );
3853 SvMemoryStream aMemStrm;
3854 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3855 aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
3856 // import the graphic from memory stream
3857 GDIMetaFile aGDIMetaFile;
3858 if( ::ReadWindowMetafile( aMemStrm, aGDIMetaFile, 0 ) )
3859 rGraphic = aGDIMetaFile;
3862 void XclImpObjectManager::ReadBmp( Graphic& rGraphic, XclImpStream& rStrm ) // static helper
3864 // extract graphic data from IMGDATA and following CONTINUE records
3865 SvMemoryStream aMemStrm;
3867 /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
3868 DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
3869 pixel depth = 32 bit. After that, 3 unused bytes are added before the
3870 actual pixel data. This does even confuse Excel 5 and later, which
3871 cannot read the image data correctly. */
3872 if( rStrm.GetRoot().GetBiff() <= EXC_BIFF4 )
3874 rStrm.PushPosition();
3875 sal_uInt32 nHdrSize;
3876 sal_uInt16 nWidth, nHeight, nPlanes, nDepth;
3877 rStrm >> nHdrSize >> nWidth >> nHeight >> nPlanes >> nDepth;
3878 if( (nHdrSize == 12) && (nPlanes == 1) && (nDepth == 32) )
3880 rStrm.Ignore( 3 );
3881 aMemStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3882 aMemStrm << nHdrSize << nWidth << nHeight << nPlanes << nDepth;
3883 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3885 rStrm.PopPosition();
3888 // no special handling above -> just copy the remaining record data
3889 if( aMemStrm.Tell() == 0 )
3890 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3892 // import the graphic from memory stream
3893 aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
3894 Bitmap aBitmap;
3895 if( aBitmap.Read( aMemStrm, FALSE ) ) // read DIB without file header
3896 rGraphic = aBitmap;
3899 void XclImpObjectManager::ReadDffRecord( XclImpStream& rStrm )
3901 maDffStrm.Seek( STREAM_SEEK_TO_END );
3902 rStrm.CopyRecordToStream( maDffStrm );
3905 void XclImpObjectManager::ReadObj8( XclImpStream& rStrm )
3907 XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( rStrm );
3908 // store the new object in the internal containers
3909 maObjMap[ maDffStrm.Tell() ] = xDrawObj;
3910 maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
3913 void XclImpObjectManager::ReadTxo( XclImpStream& rStrm )
3915 XclImpObjTextRef xTextData( new XclImpObjTextData );
3916 maTextMap[ maDffStrm.Tell() ] = xTextData;
3918 // 1) read the TXO record
3919 xTextData->maData.ReadTxo8( rStrm );
3921 // 2) first CONTINUE with string
3922 xTextData->mxString.reset();
3923 bool bValid = true;
3924 if( xTextData->maData.mnTextLen > 0 )
3926 bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
3927 DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" );
3928 if( bValid )
3929 xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) );
3932 // 3) second CONTINUE with formatting runs
3933 if( xTextData->maData.mnFormatSize > 0 )
3935 bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
3936 DBG_ASSERT( bValid, "XclImpObjectManager::ReadTxo - missing CONTINUE record" );
3937 if( bValid )
3938 xTextData->ReadFormats( rStrm );
3942 void XclImpObjectManager::ReadNote3( XclImpStream& rStrm )
3944 XclAddress aXclPos;
3945 sal_uInt16 nTotalLen;
3946 rStrm >> aXclPos >> nTotalLen;
3948 SCTAB nScTab = GetCurrScTab();
3949 ScAddress aScNotePos( ScAddress::UNINITIALIZED );
3950 if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) )
3952 sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) );
3953 String aNoteText = rStrm.ReadRawByteString( nPartLen );
3954 nTotalLen = nTotalLen - nPartLen;
3955 while( (nTotalLen > 0) && (rStrm.GetNextRecId() == EXC_ID_NOTE) && rStrm.StartNextRecord() )
3957 rStrm >> aXclPos >> nPartLen;
3958 DBG_ASSERT( aXclPos.mnRow == 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
3959 if( aXclPos.mnRow == 0xFFFF )
3961 DBG_ASSERT( nPartLen <= nTotalLen, "XclImpObjectManager::ReadNote3 - string too long" );
3962 aNoteText.Append( rStrm.ReadRawByteString( nPartLen ) );
3963 nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen );
3965 else
3967 // seems to be a new note, record already started -> load the note
3968 rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
3969 ReadNote( rStrm );
3970 nTotalLen = 0;
3973 ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false, false );
3977 void XclImpObjectManager::ReadNote8( XclImpStream& rStrm )
3979 XclAddress aXclPos;
3980 sal_uInt16 nFlags, nObjId;
3981 rStrm >> aXclPos >> nFlags >> nObjId;
3983 SCTAB nScTab = GetCurrScTab();
3984 ScAddress aScNotePos( ScAddress::UNINITIALIZED );
3985 if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, nScTab, true ) )
3986 if( nObjId != EXC_OBJ_INVALID_ID )
3987 if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( XclObjId( nScTab, nObjId ) ).get() ) )
3988 pNoteObj->SetNoteData( aScNotePos, nFlags );
3991 sal_Size XclImpObjectManager::GetProgressSize() const
3993 sal_Size nProgressSize = maRawObjs.GetProgressSize();
3994 for( XclImpObjMap::const_iterator aMIt = maObjMap.begin(), aMEnd = maObjMap.end(); aMIt != aMEnd; ++aMIt )
3995 nProgressSize += aMIt->second->GetProgressSize();
3996 return nProgressSize;
3999 // DFF property set helper ====================================================
4001 XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot& rRoot ) :
4002 XclImpRoot( rRoot ),
4003 maDffManager( rRoot, maDummyStrm )
4007 void XclImpDffPropSet::Read( XclImpStream& rStrm )
4009 sal_uInt32 nPropSetSize;
4011 rStrm.PushPosition();
4012 rStrm.Ignore( 4 );
4013 rStrm >> nPropSetSize;
4014 rStrm.PopPosition();
4016 mxMemStrm.reset( new SvMemoryStream );
4017 rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize );
4018 mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN );
4019 maDffManager.ReadPropSet( *mxMemStrm, 0 );
4022 sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const
4024 return maDffManager.GetPropertyValue( nPropId, nDefault );
4027 void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const
4029 if( mxMemStrm.get() )
4030 maDffManager.ApplyAttributes( *mxMemStrm, rItemSet );
4033 XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet )
4035 rPropSet.Read( rStrm );
4036 return rStrm;
4039 // ============================================================================