1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "xiescher.hxx"
22 #include <com/sun/star/beans/NamedValue.hpp>
23 #include <com/sun/star/container/XIndexContainer.hpp>
24 #include <com/sun/star/container/XNameContainer.hpp>
25 #include <com/sun/star/embed/Aspects.hpp>
26 #include <com/sun/star/embed/XEmbeddedObject.hpp>
27 #include <com/sun/star/embed/XEmbedPersist.hpp>
28 #include <com/sun/star/awt/PushButtonType.hpp>
29 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
30 #include <com/sun/star/awt/VisualEffect.hpp>
31 #include <com/sun/star/style/HorizontalAlignment.hpp>
32 #include <com/sun/star/style/VerticalAlignment.hpp>
33 #include <com/sun/star/drawing/XControlShape.hpp>
34 #include <com/sun/star/form/XForm.hpp>
35 #include <com/sun/star/form/XFormsSupplier.hpp>
36 #include <com/sun/star/form/binding/XBindableValue.hpp>
37 #include <com/sun/star/form/binding/XValueBinding.hpp>
38 #include <com/sun/star/form/binding/XListEntrySink.hpp>
39 #include <com/sun/star/form/binding/XListEntrySource.hpp>
40 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
41 #include <com/sun/star/script/XEventAttacherManager.hpp>
43 #include <rtl/logfile.hxx>
44 #include <sfx2/objsh.hxx>
45 #include <unotools/moduleoptions.hxx>
46 #include <unotools/fltrcfg.hxx>
47 #include <vcl/wmf.hxx>
48 #include <comphelper/types.hxx>
49 #include <comphelper/classids.hxx>
50 #include <toolkit/helper/vclunohelper.hxx>
51 #include <basegfx/point/b2dpoint.hxx>
52 #include <basegfx/polygon/b2dpolygon.hxx>
54 #include <svx/svdopath.hxx>
55 #include <svx/svdocirc.hxx>
56 #include <svx/svdoedge.hxx>
57 #include <svx/svdogrp.hxx>
58 #include <svx/svdoashp.hxx>
59 #include <svx/svdograf.hxx>
60 #include <svx/svdoole2.hxx>
61 #include <svx/svdocapt.hxx>
62 #include <svx/svdouno.hxx>
63 #include <svx/svdpage.hxx>
64 #include <editeng/editobj.hxx>
65 #include <editeng/outliner.hxx>
66 #include <editeng/outlobj.hxx>
67 #include <svx/unoapi.hxx>
68 #include <svx/svditer.hxx>
69 #include <editeng/writingmodeitem.hxx>
71 #include "scitems.hxx"
72 #include <editeng/eeitem.hxx>
73 #include <editeng/colritem.hxx>
74 #include <svx/xflclit.hxx>
75 #include <sal/macros.h>
76 #include <editeng/adjustitem.hxx>
77 #include <svx/xlineit.hxx>
78 #include <svx/xlinjoit.hxx>
79 #include <svx/xlntrit.hxx>
80 #include <svx/xbtmpit.hxx>
81 #include <svx/xbitmap.hxx>
83 #include "document.hxx"
84 #include "drwlayer.hxx"
85 #include "userdat.hxx"
86 #include "chartarr.hxx"
87 #include "detfunc.hxx"
88 #include "unonames.hxx"
89 #include "convuno.hxx"
91 #include "globstr.hrc"
93 #include "fprogressbar.hxx"
94 #include "xltracer.hxx"
95 #include "xistream.hxx"
96 #include "xihelper.hxx"
97 #include "xiformula.hxx"
99 #include "xistyle.hxx"
100 #include "xipage.hxx"
101 #include "xichart.hxx"
102 #include "xicontent.hxx"
103 #include "scextopt.hxx"
105 #include "namebuff.hxx"
106 #include <boost/shared_ptr.hpp>
107 #include <comphelper/mediadescriptor.hxx>
108 #include <sfx2/docfile.hxx>
110 using ::com::sun::star::uno::Any
;
111 using ::com::sun::star::uno::Exception
;
112 using ::com::sun::star::uno::Reference
;
113 using ::com::sun::star::uno::Sequence
;
114 using ::com::sun::star::uno::UNO_QUERY
;
115 using ::com::sun::star::uno::UNO_QUERY_THROW
;
116 using ::com::sun::star::uno::UNO_SET_THROW
;
117 using ::com::sun::star::uno::XComponentContext
;
118 using ::com::sun::star::beans::NamedValue
;
119 using ::com::sun::star::lang::XMultiServiceFactory
;
120 using ::com::sun::star::container::XIndexContainer
;
121 using ::com::sun::star::container::XNameContainer
;
122 using ::com::sun::star::frame::XModel
;
123 using ::com::sun::star::awt::XControlModel
;
124 using ::com::sun::star::embed::XEmbeddedObject
;
125 using ::com::sun::star::embed::XEmbedPersist
;
126 using ::com::sun::star::drawing::XControlShape
;
127 using ::com::sun::star::drawing::XShape
;
128 using ::com::sun::star::form::XForm
;
129 using ::com::sun::star::form::XFormComponent
;
130 using ::com::sun::star::form::XFormsSupplier
;
131 using ::com::sun::star::form::binding::XBindableValue
;
132 using ::com::sun::star::form::binding::XValueBinding
;
133 using ::com::sun::star::form::binding::XListEntrySink
;
134 using ::com::sun::star::form::binding::XListEntrySource
;
135 using ::com::sun::star::script::ScriptEventDescriptor
;
136 using ::com::sun::star::script::XEventAttacherManager
;
137 using ::com::sun::star::table::CellAddress
;
138 using ::com::sun::star::table::CellRangeAddress
;
140 // ============================================================================
144 /** Helper class which mimics the auto_ptr< SdrObject > semantics, but calls
145 SdrObject::Free instead of deleting the SdrObject directly. */
146 template< typename SdrObjType
>
150 inline explicit TSdrObjectPtr( SdrObjType
* pObj
= 0 ) : mpObj( pObj
) {}
151 inline ~TSdrObjectPtr() { free(); }
153 inline const SdrObjType
* operator->() const { return mpObj
; }
154 inline SdrObjType
* operator->() { return mpObj
; }
156 inline const SdrObjType
* get() const { return mpObj
; }
157 inline SdrObjType
* get() { return mpObj
; }
159 inline const SdrObjType
& operator*() const { return *mpObj
; }
160 inline SdrObjType
& operator*() { return *mpObj
; }
162 inline bool is() const { return mpObj
!= 0; }
163 inline bool operator!() const { return mpObj
== 0; }
165 inline void reset( SdrObjType
* pObj
= 0 ) { free(); mpObj
= pObj
; }
166 inline SdrObjType
* release() { SdrObjType
* pObj
= mpObj
; mpObj
= 0; return pObj
; }
169 TSdrObjectPtr( const TSdrObjectPtr
& ); // not implemented
170 TSdrObjectPtr
& operator=( TSdrObjectPtr
& rxObj
); // not implemented
172 inline void free() { SdrObject
* pObj
= mpObj
; mpObj
= 0; SdrObject::Free( pObj
); }
178 typedef TSdrObjectPtr
< SdrObject
> SdrObjectPtr
;
182 // Drawing objects ============================================================
184 XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot
& rRoot
) :
186 mnObjId( EXC_OBJ_INVALID_ID
),
187 mnObjType( EXC_OBJTYPE_UNKNOWN
),
190 mbHasAnchor( false ),
195 mbAutoMargin( true ),
196 mbSimpleMacro( true ),
197 mbProcessSdr( true ),
203 XclImpDrawObjBase::~XclImpDrawObjBase()
207 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj3( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
209 XclImpDrawObjRef xDrawObj
;
211 if( rStrm
.GetRecLeft() >= 30 )
218 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
219 case EXC_OBJTYPE_LINE
: xDrawObj
.reset( new XclImpLineObj( rRoot
) ); break;
220 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
.reset( new XclImpRectObj( rRoot
) ); break;
221 case EXC_OBJTYPE_OVAL
: xDrawObj
.reset( new XclImpOvalObj( rRoot
) ); break;
222 case EXC_OBJTYPE_ARC
: xDrawObj
.reset( new XclImpArcObj( rRoot
) ); break;
223 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
224 case EXC_OBJTYPE_TEXT
: xDrawObj
.reset( new XclImpTextObj( rRoot
) ); break;
225 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
226 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
228 OSL_TRACE( "XclImpDrawObjBase::ReadObj3 - unknown object type 0x%04hX", nObjType
);
229 rRoot
.GetTracer().TraceUnsupportedObjects();
230 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
234 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
235 xDrawObj
->ImplReadObj3( rStrm
);
239 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj4( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
241 XclImpDrawObjRef xDrawObj
;
243 if( rStrm
.GetRecLeft() >= 30 )
250 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
251 case EXC_OBJTYPE_LINE
: xDrawObj
.reset( new XclImpLineObj( rRoot
) ); break;
252 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
.reset( new XclImpRectObj( rRoot
) ); break;
253 case EXC_OBJTYPE_OVAL
: xDrawObj
.reset( new XclImpOvalObj( rRoot
) ); break;
254 case EXC_OBJTYPE_ARC
: xDrawObj
.reset( new XclImpArcObj( rRoot
) ); break;
255 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
256 case EXC_OBJTYPE_TEXT
: xDrawObj
.reset( new XclImpTextObj( rRoot
) ); break;
257 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
258 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
259 case EXC_OBJTYPE_POLYGON
: xDrawObj
.reset( new XclImpPolygonObj( rRoot
) ); break;
261 OSL_TRACE( "XclImpDrawObjBase::ReadObj4 - unknown object type 0x%04hX", nObjType
);
262 rRoot
.GetTracer().TraceUnsupportedObjects();
263 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
267 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
268 xDrawObj
->ImplReadObj4( rStrm
);
272 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj5( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
274 XclImpDrawObjRef xDrawObj
;
276 if( rStrm
.GetRecLeft() >= 34 )
278 sal_uInt16
nObjType(EXC_OBJTYPE_UNKNOWN
);
283 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
284 case EXC_OBJTYPE_LINE
: xDrawObj
.reset( new XclImpLineObj( rRoot
) ); break;
285 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
.reset( new XclImpRectObj( rRoot
) ); break;
286 case EXC_OBJTYPE_OVAL
: xDrawObj
.reset( new XclImpOvalObj( rRoot
) ); break;
287 case EXC_OBJTYPE_ARC
: xDrawObj
.reset( new XclImpArcObj( rRoot
) ); break;
288 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
289 case EXC_OBJTYPE_TEXT
: xDrawObj
.reset( new XclImpTextObj( rRoot
) ); break;
290 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
291 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
292 case EXC_OBJTYPE_POLYGON
: xDrawObj
.reset( new XclImpPolygonObj( rRoot
) ); break;
293 case EXC_OBJTYPE_CHECKBOX
: xDrawObj
.reset( new XclImpCheckBoxObj( rRoot
) ); break;
294 case EXC_OBJTYPE_OPTIONBUTTON
: xDrawObj
.reset( new XclImpOptionButtonObj( rRoot
) ); break;
295 case EXC_OBJTYPE_EDIT
: xDrawObj
.reset( new XclImpEditObj( rRoot
) ); break;
296 case EXC_OBJTYPE_LABEL
: xDrawObj
.reset( new XclImpLabelObj( rRoot
) ); break;
297 case EXC_OBJTYPE_DIALOG
: xDrawObj
.reset( new XclImpDialogObj( rRoot
) ); break;
298 case EXC_OBJTYPE_SPIN
: xDrawObj
.reset( new XclImpSpinButtonObj( rRoot
) ); break;
299 case EXC_OBJTYPE_SCROLLBAR
: xDrawObj
.reset( new XclImpScrollBarObj( rRoot
) ); break;
300 case EXC_OBJTYPE_LISTBOX
: xDrawObj
.reset( new XclImpListBoxObj( rRoot
) ); break;
301 case EXC_OBJTYPE_GROUPBOX
: xDrawObj
.reset( new XclImpGroupBoxObj( rRoot
) ); break;
302 case EXC_OBJTYPE_DROPDOWN
: xDrawObj
.reset( new XclImpDropDownObj( rRoot
) ); break;
304 OSL_TRACE( "XclImpDrawObjBase::ReadObj5 - unknown object type 0x%04hX", nObjType
);
305 rRoot
.GetTracer().TraceUnsupportedObjects();
306 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
310 OSL_ENSURE(xDrawObj
, "object import failed");
314 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
315 xDrawObj
->ImplReadObj5( rStrm
);
320 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj8( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
322 XclImpDrawObjRef xDrawObj
;
324 if( rStrm
.GetRecLeft() >= 10 )
326 sal_uInt16
nSubRecId(0), nSubRecSize(0), nObjType(0);
327 rStrm
>> nSubRecId
>> nSubRecSize
>> nObjType
;
328 OSL_ENSURE( nSubRecId
== EXC_ID_OBJCMO
, "XclImpDrawObjBase::ReadObj8 - OBJCMO subrecord expected" );
329 if( (nSubRecId
== EXC_ID_OBJCMO
) && (nSubRecSize
>= 6) )
333 // in BIFF8, all simple objects support text
334 case EXC_OBJTYPE_LINE
:
335 case EXC_OBJTYPE_ARC
:
336 xDrawObj
.reset( new XclImpTextObj( rRoot
) );
337 // lines and arcs may be 2-dimensional
338 xDrawObj
->SetAreaObj( false );
341 // in BIFF8, all simple objects support text
342 case EXC_OBJTYPE_RECTANGLE
:
343 case EXC_OBJTYPE_OVAL
:
344 case EXC_OBJTYPE_POLYGON
:
345 case EXC_OBJTYPE_DRAWING
:
346 case EXC_OBJTYPE_TEXT
:
347 xDrawObj
.reset( new XclImpTextObj( rRoot
) );
350 case EXC_OBJTYPE_GROUP
: xDrawObj
.reset( new XclImpGroupObj( rRoot
) ); break;
351 case EXC_OBJTYPE_CHART
: xDrawObj
.reset( new XclImpChartObj( rRoot
) ); break;
352 case EXC_OBJTYPE_BUTTON
: xDrawObj
.reset( new XclImpButtonObj( rRoot
) ); break;
353 case EXC_OBJTYPE_PICTURE
: xDrawObj
.reset( new XclImpPictureObj( rRoot
) ); break;
354 case EXC_OBJTYPE_CHECKBOX
: xDrawObj
.reset( new XclImpCheckBoxObj( rRoot
) ); break;
355 case EXC_OBJTYPE_OPTIONBUTTON
: xDrawObj
.reset( new XclImpOptionButtonObj( rRoot
) ); break;
356 case EXC_OBJTYPE_EDIT
: xDrawObj
.reset( new XclImpEditObj( rRoot
) ); break;
357 case EXC_OBJTYPE_LABEL
: xDrawObj
.reset( new XclImpLabelObj( rRoot
) ); break;
358 case EXC_OBJTYPE_DIALOG
: xDrawObj
.reset( new XclImpDialogObj( rRoot
) ); break;
359 case EXC_OBJTYPE_SPIN
: xDrawObj
.reset( new XclImpSpinButtonObj( rRoot
) ); break;
360 case EXC_OBJTYPE_SCROLLBAR
: xDrawObj
.reset( new XclImpScrollBarObj( rRoot
) ); break;
361 case EXC_OBJTYPE_LISTBOX
: xDrawObj
.reset( new XclImpListBoxObj( rRoot
) ); break;
362 case EXC_OBJTYPE_GROUPBOX
: xDrawObj
.reset( new XclImpGroupBoxObj( rRoot
) ); break;
363 case EXC_OBJTYPE_DROPDOWN
: xDrawObj
.reset( new XclImpDropDownObj( rRoot
) ); break;
364 case EXC_OBJTYPE_NOTE
: xDrawObj
.reset( new XclImpNoteObj( rRoot
) ); break;
367 OSL_TRACE( "XclImpDrawObjBase::ReadObj8 - unknown object type 0x%04hX", nObjType
);
368 rRoot
.GetTracer().TraceUnsupportedObjects();
373 if (!xDrawObj
) //ensure placeholder for unknown or broken records
375 SAL_WARN( "sc", "XclImpDrawObjBase::ReadObj8 import failed, substituting placeholder");
376 xDrawObj
.reset( new XclImpPhObj( rRoot
) );
379 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
380 xDrawObj
->ImplReadObj8( rStrm
);
384 void XclImpDrawObjBase::SetAnchor( const XclObjAnchor
& rAnchor
)
390 void XclImpDrawObjBase::SetDffData(
391 const DffObjData
& rDffObjData
, const OUString
& rObjName
, const OUString
& rHyperlink
,
392 bool bVisible
, bool bAutoMargin
)
394 mnDffShapeId
= rDffObjData
.nShapeId
;
395 mnDffFlags
= rDffObjData
.nSpFlags
;
396 maObjName
= rObjName
;
397 maHyperlink
= rHyperlink
;
398 mbVisible
= bVisible
;
399 mbAutoMargin
= bAutoMargin
;
402 OUString
XclImpDrawObjBase::GetObjName() const
404 /* #i51348# Always return a non-empty name. Create English
405 default names depending on the object type. This is not implemented as
406 virtual functions in derived classes, as class type and object type may
408 return maObjName
.isEmpty() ? GetObjectManager().GetDefaultObjName(*this) : maObjName
;
411 const XclObjAnchor
* XclImpDrawObjBase::GetAnchor() const
413 return mbHasAnchor
? &maAnchor
: 0;
416 bool XclImpDrawObjBase::IsValidSize( const Rectangle
& rAnchorRect
) const
418 // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0
420 ((rAnchorRect
.GetWidth() > 3) && (rAnchorRect
.GetHeight() > 1)) :
421 ((rAnchorRect
.GetWidth() > 3) || (rAnchorRect
.GetHeight() > 1));
424 ScRange
XclImpDrawObjBase::GetUsedArea( SCTAB nScTab
) const
426 ScRange
aScUsedArea( ScAddress::INITIALIZE_INVALID
);
427 // #i44077# object inserted -> update used area for OLE object import
428 if( mbHasAnchor
&& GetAddressConverter().ConvertRange( aScUsedArea
, maAnchor
, nScTab
, nScTab
, false ) )
430 // reduce range, if object ends directly on borders between two columns or rows
431 if( (maAnchor
.mnRX
== 0) && (aScUsedArea
.aStart
.Col() < aScUsedArea
.aEnd
.Col()) )
432 aScUsedArea
.aEnd
.IncCol( -1 );
433 if( (maAnchor
.mnBY
== 0) && (aScUsedArea
.aStart
.Row() < aScUsedArea
.aEnd
.Row()) )
434 aScUsedArea
.aEnd
.IncRow( -1 );
439 sal_Size
XclImpDrawObjBase::GetProgressSize() const
441 return DoGetProgressSize();
444 SdrObject
* XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
, bool bIsDff
) const
446 SdrObjectPtr xSdrObj
;
447 if( bIsDff
&& !mbCustomDff
)
449 rDffConv
.Progress( GetProgressSize() );
453 xSdrObj
.reset( DoCreateSdrObj( rDffConv
, rAnchorRect
) );
455 xSdrObj
->SetModel( rDffConv
.GetModel() );
457 return xSdrObj
.release();
460 void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
462 // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj()
463 rSdrObj
.NbcSetLayer( SC_LAYER_FRONT
);
465 // set object name (GetObjName() will always return a non-empty name)
466 rSdrObj
.SetName( GetObjName() );
468 // #i39167# full width for all objects regardless of horizontal alignment
469 rSdrObj
.SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK
) );
471 // automatic text margin
474 sal_Int32 nMargin
= rDffConv
.GetDefaultTextMargin();
475 rSdrObj
.SetMergedItem( SdrTextLeftDistItem( nMargin
) );
476 rSdrObj
.SetMergedItem( SdrTextRightDistItem( nMargin
) );
477 rSdrObj
.SetMergedItem( SdrTextUpperDistItem( nMargin
) );
478 rSdrObj
.SetMergedItem( SdrTextLowerDistItem( nMargin
) );
481 // macro and hyperlink
482 // removed oracle/sun check for mbSimpleMacro ( no idea what its for )
483 if (!maMacroName
.isEmpty() || !maHyperlink
.isEmpty())
485 if( ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( &rSdrObj
, sal_True
) )
487 pInfo
->SetMacro( XclTools::GetSbMacroUrl( maMacroName
, GetDocShell() ) );
488 pInfo
->SetHlink( maHyperlink
);
492 // call virtual function for object type specific processing
493 DoPreProcessSdrObj( rDffConv
, rSdrObj
);
496 void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
498 // call virtual function for object type specific processing
499 DoPostProcessSdrObj( rDffConv
, rSdrObj
);
502 // protected ------------------------------------------------------------------
504 void XclImpDrawObjBase::ReadName5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
)
506 maObjName
= OUString();
509 // name length field is repeated before the name
510 maObjName
= rStrm
.ReadByteString( false );
511 // skip padding byte for word boundaries
512 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
516 void XclImpDrawObjBase::ReadMacro3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
518 maMacroName
= OUString();
519 rStrm
.Ignore( nMacroSize
);
520 // skip padding byte for word boundaries, not contained in nMacroSize
521 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
524 void XclImpDrawObjBase::ReadMacro4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
526 maMacroName
= OUString();
527 rStrm
.Ignore( nMacroSize
);
530 void XclImpDrawObjBase::ReadMacro5( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
532 maMacroName
= OUString();
533 rStrm
.Ignore( nMacroSize
);
536 void XclImpDrawObjBase::ReadMacro8( XclImpStream
& rStrm
)
538 maMacroName
= OUString();
539 if( rStrm
.GetRecLeft() > 6 )
541 // macro is stored in a tNameXR token containing a link to a defined name
542 sal_uInt16 nFmlaSize
;
545 OSL_ENSURE( nFmlaSize
== 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" );
549 sal_uInt16 nExtSheet
, nExtName
;
550 rStrm
>> nTokenId
>> nExtSheet
>> nExtName
;
551 OSL_ENSURE( nTokenId
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
),
552 "XclImpDrawObjBase::ReadMacro - tNameXR token expected" );
553 if( nTokenId
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
) )
554 maMacroName
= GetLinkManager().GetMacroName( nExtSheet
, nExtName
);
559 void XclImpDrawObjBase::ConvertLineStyle( SdrObject
& rSdrObj
, const XclObjLineData
& rLineData
) const
561 if( rLineData
.IsAuto() )
563 XclObjLineData aAutoData
;
564 aAutoData
.mnAuto
= 0;
565 ConvertLineStyle( rSdrObj
, aAutoData
);
569 long nLineWidth
= 35 * ::std::min( rLineData
.mnWidth
, EXC_OBJ_LINE_THICK
);
570 rSdrObj
.SetMergedItem( XLineWidthItem( nLineWidth
) );
571 rSdrObj
.SetMergedItem( XLineColorItem( EMPTY_STRING
, GetPalette().GetColor( rLineData
.mnColorIdx
) ) );
572 rSdrObj
.SetMergedItem( XLineJointItem( com::sun::star::drawing::LineJoint_MITER
) );
574 sal_uLong nDotLen
= ::std::max
< sal_uLong
>( 70 * rLineData
.mnWidth
, 35 );
575 sal_uLong nDashLen
= 3 * nDotLen
;
576 sal_uLong nDist
= 2 * nDotLen
;
578 switch( rLineData
.mnStyle
)
581 case EXC_OBJ_LINE_SOLID
:
582 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
584 case EXC_OBJ_LINE_DASH
:
585 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
586 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 0, nDotLen
, 1, nDashLen
, nDist
) ) );
588 case EXC_OBJ_LINE_DOT
:
589 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
590 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 1, nDotLen
, 0, nDashLen
, nDist
) ) );
592 case EXC_OBJ_LINE_DASHDOT
:
593 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
594 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 1, nDotLen
, 1, nDashLen
, nDist
) ) );
596 case EXC_OBJ_LINE_DASHDOTDOT
:
597 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_DASH
) );
598 rSdrObj
.SetMergedItem( XLineDashItem( EMPTY_STRING
, XDash( XDASH_RECT
, 2, nDotLen
, 1, nDashLen
, nDist
) ) );
600 case EXC_OBJ_LINE_MEDTRANS
:
601 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
602 rSdrObj
.SetMergedItem( XLineTransparenceItem( 50 ) );
604 case EXC_OBJ_LINE_DARKTRANS
:
605 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
606 rSdrObj
.SetMergedItem( XLineTransparenceItem( 25 ) );
608 case EXC_OBJ_LINE_LIGHTTRANS
:
609 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_SOLID
) );
610 rSdrObj
.SetMergedItem( XLineTransparenceItem( 75 ) );
612 case EXC_OBJ_LINE_NONE
:
613 rSdrObj
.SetMergedItem( XLineStyleItem( XLINE_NONE
) );
619 void XclImpDrawObjBase::ConvertFillStyle( SdrObject
& rSdrObj
, const XclObjFillData
& rFillData
) const
621 if( rFillData
.IsAuto() )
623 XclObjFillData aAutoData
;
624 aAutoData
.mnAuto
= 0;
625 ConvertFillStyle( rSdrObj
, aAutoData
);
627 else if( rFillData
.mnPattern
== EXC_PATT_NONE
)
629 rSdrObj
.SetMergedItem( XFillStyleItem( XFILL_NONE
) );
633 Color aPattColor
= GetPalette().GetColor( rFillData
.mnPattColorIdx
);
634 Color aBackColor
= GetPalette().GetColor( rFillData
.mnBackColorIdx
);
635 if( (rFillData
.mnPattern
== EXC_PATT_SOLID
) || (aPattColor
== aBackColor
) )
637 rSdrObj
.SetMergedItem( XFillStyleItem( XFILL_SOLID
) );
638 rSdrObj
.SetMergedItem( XFillColorItem( EMPTY_STRING
, aPattColor
) );
642 static const sal_uInt8 sppnPatterns
[][ 8 ] =
644 { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
645 { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
646 { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
647 { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
648 { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
649 { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
650 { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
651 { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
652 { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
653 { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
654 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
655 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
656 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
657 { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
658 { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
659 { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
660 { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
662 const sal_uInt8
* const pnPattern
= sppnPatterns
[ ::std::min
< size_t >( rFillData
.mnPattern
- 2, SAL_N_ELEMENTS( sppnPatterns
) ) ];
663 // create 2-colored 8x8 DIB
664 SvMemoryStream aMemStrm
;
665 aMemStrm
<< sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 );
666 aMemStrm
<< sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF );
667 aMemStrm
<< sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 );
668 for( size_t nIdx
= 0; nIdx
< 8; ++nIdx
)
669 aMemStrm
<< sal_uInt32( pnPattern
[ nIdx
] ); // 32-bit little-endian
670 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
672 aBitmap
.Read( aMemStrm
, sal_False
);
674 XOBitmap
aXOBitmap( aBitmap
);
675 aXOBitmap
.Bitmap2Array();
676 aXOBitmap
.SetBitmapType( XBITMAP_8X8
);
677 if( aXOBitmap
.GetBackgroundColor().GetColor() == COL_BLACK
)
678 ::std::swap( aPattColor
, aBackColor
);
679 aXOBitmap
.SetPixelColor( aPattColor
);
680 aXOBitmap
.SetBackgroundColor( aBackColor
);
681 aXOBitmap
.Array2Bitmap();
682 aBitmap
= aXOBitmap
.GetBitmap();
684 rSdrObj
.SetMergedItem(XFillStyleItem(XFILL_BITMAP
));
685 rSdrObj
.SetMergedItem(XFillBitmapItem(EMPTY_STRING
, Graphic(aBitmap
)));
690 void XclImpDrawObjBase::ConvertFrameStyle( SdrObject
& rSdrObj
, sal_uInt16 nFrameFlags
) const
692 if( ::get_flag( nFrameFlags
, EXC_OBJ_FRAME_SHADOW
) )
694 rSdrObj
.SetMergedItem( SdrShadowItem( sal_True
) );
695 rSdrObj
.SetMergedItem( SdrShadowXDistItem( 35 ) );
696 rSdrObj
.SetMergedItem( SdrShadowYDistItem( 35 ) );
697 rSdrObj
.SetMergedItem( SdrShadowColorItem( GetPalette().GetColor( EXC_COLOR_WINDOWTEXT
) ) );
701 Color
XclImpDrawObjBase::GetSolidLineColor( const XclObjLineData
& rLineData
) const
703 Color
aColor( COL_TRANSPARENT
);
704 if( rLineData
.IsAuto() )
706 XclObjLineData aAutoData
;
707 aAutoData
.mnAuto
= 0;
708 aColor
= GetSolidLineColor( aAutoData
);
710 else if( rLineData
.mnStyle
!= EXC_OBJ_LINE_NONE
)
712 aColor
= GetPalette().GetColor( rLineData
.mnColorIdx
);
717 Color
XclImpDrawObjBase::GetSolidFillColor( const XclObjFillData
& rFillData
) const
719 Color
aColor( COL_TRANSPARENT
);
720 if( rFillData
.IsAuto() )
722 XclObjFillData aAutoData
;
723 aAutoData
.mnAuto
= 0;
724 aColor
= GetSolidFillColor( aAutoData
);
726 else if( rFillData
.mnPattern
!= EXC_PATT_NONE
)
728 Color aPattColor
= GetPalette().GetColor( rFillData
.mnPattColorIdx
);
729 Color aBackColor
= GetPalette().GetColor( rFillData
.mnBackColorIdx
);
730 aColor
= XclTools::GetPatternColor( aPattColor
, aBackColor
, rFillData
.mnPattern
);
735 void XclImpDrawObjBase::DoReadObj3( XclImpStream
&, sal_uInt16
)
739 void XclImpDrawObjBase::DoReadObj4( XclImpStream
&, sal_uInt16
)
743 void XclImpDrawObjBase::DoReadObj5( XclImpStream
&, sal_uInt16
, sal_uInt16
)
747 void XclImpDrawObjBase::DoReadObj8SubRec( XclImpStream
&, sal_uInt16
, sal_uInt16
)
751 sal_Size
XclImpDrawObjBase::DoGetProgressSize() const
756 SdrObject
* XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& ) const
758 rDffConv
.Progress( GetProgressSize() );
762 void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter
&, SdrObject
& ) const
764 // trace if object is not printable
766 GetTracer().TraceObjectNotPrintable();
769 void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter
&, SdrObject
& ) const
773 void XclImpDrawObjBase::ImplReadObj3( XclImpStream
& rStrm
)
775 // back to offset 4 (ignore object count field)
778 sal_uInt16 nObjFlags
, nMacroSize
;
779 rStrm
>> mnObjType
>> mnObjId
>> nObjFlags
>> maAnchor
>> nMacroSize
;
783 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
784 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
785 DoReadObj3( rStrm
, nMacroSize
);
788 void XclImpDrawObjBase::ImplReadObj4( XclImpStream
& rStrm
)
790 // back to offset 4 (ignore object count field)
793 sal_uInt16 nObjFlags
, nMacroSize
;
794 rStrm
>> mnObjType
>> mnObjId
>> nObjFlags
>> maAnchor
>> nMacroSize
;
798 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
799 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
800 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJ_PRINTABLE
);
801 DoReadObj4( rStrm
, nMacroSize
);
804 void XclImpDrawObjBase::ImplReadObj5( XclImpStream
& rStrm
)
806 // back to offset 4 (ignore object count field)
809 sal_uInt16 nObjFlags
, nMacroSize
, nNameLen
;
810 rStrm
>> mnObjType
>> mnObjId
>> nObjFlags
>> maAnchor
>> nMacroSize
;
816 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
817 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
818 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJ_PRINTABLE
);
819 DoReadObj5( rStrm
, nNameLen
, nMacroSize
);
822 void XclImpDrawObjBase::ImplReadObj8( XclImpStream
& rStrm
)
825 rStrm
.Seek( EXC_REC_SEEK_TO_BEGIN
);
828 while( bLoop
&& (rStrm
.GetRecLeft() >= 4) )
830 sal_uInt16 nSubRecId
, nSubRecSize
;
831 rStrm
>> nSubRecId
>> nSubRecSize
;
832 rStrm
.PushPosition();
833 // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
834 nSubRecSize
= static_cast< sal_uInt16
>( ::std::min
< sal_Size
>( nSubRecSize
, rStrm
.GetRecLeft() ) );
839 OSL_ENSURE( rStrm
.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" );
840 if( (rStrm
.GetRecPos() == 4) && (nSubRecSize
>= 6) )
842 sal_uInt16 nObjFlags
;
843 rStrm
>> mnObjType
>> mnObjId
>> nObjFlags
;
844 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJCMO_PRINTABLE
);
847 case EXC_ID_OBJMACRO
:
854 DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
858 rStrm
.Ignore( nSubRecSize
);
861 /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream
862 processing (e.g. charts), even if the OBJEND subrecord is missing. */
863 DoReadObj8SubRec( rStrm
, EXC_ID_OBJEND
, 0 );
865 /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
866 IMGDATA record following the OBJ record (but they use the image data
867 stored in DFF). The IMGDATA record may be continued by several CONTINUE
868 records. But the last CONTINUE record may be in fact an MSODRAWING
869 record that contains the DFF data of the next drawing object! So we
870 have to skip just enough CONTINUE records to look at the next
871 MSODRAWING/CONTINUE record. */
872 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
874 sal_uInt32 nDataSize
;
877 nDataSize
-= rStrm
.GetRecLeft();
878 // skip following CONTINUE records until IMGDATA ends
879 while( (nDataSize
> 0) && (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord() )
881 OSL_ENSURE( nDataSize
>= rStrm
.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" );
882 nDataSize
-= ::std::min
< sal_uInt32
>( rStrm
.GetRecLeft(), nDataSize
);
884 OSL_ENSURE( nDataSize
== 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" );
885 // next record may be MSODRAWING or CONTINUE or anything else
889 // ----------------------------------------------------------------------------
891 void XclImpDrawObjVector::InsertGrouped( XclImpDrawObjRef xDrawObj
)
894 if( XclImpGroupObj
* pGroupObj
= dynamic_cast< XclImpGroupObj
* >( back().get() ) )
895 if( pGroupObj
->TryInsert( xDrawObj
) )
897 push_back( xDrawObj
);
900 sal_Size
XclImpDrawObjVector::GetProgressSize() const
902 sal_Size nProgressSize
= 0;
903 for( const_iterator aIt
= begin(), aEnd
= end(); aIt
!= aEnd
; ++aIt
)
904 nProgressSize
+= (*aIt
)->GetProgressSize();
905 return nProgressSize
;
908 // ----------------------------------------------------------------------------
910 XclImpPhObj::XclImpPhObj( const XclImpRoot
& rRoot
) :
911 XclImpDrawObjBase( rRoot
)
913 SetProcessSdrObj( false );
916 // ----------------------------------------------------------------------------
918 XclImpGroupObj::XclImpGroupObj( const XclImpRoot
& rRoot
) :
919 XclImpDrawObjBase( rRoot
),
920 mnFirstUngrouped( 0 )
924 bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj
)
926 if( xDrawObj
->GetObjId() == mnFirstUngrouped
)
928 // insert into own list or into nested group
929 maChildren
.InsertGrouped( xDrawObj
);
933 void XclImpGroupObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
936 rStrm
>> mnFirstUngrouped
;
938 ReadMacro3( rStrm
, nMacroSize
);
941 void XclImpGroupObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
944 rStrm
>> mnFirstUngrouped
;
946 ReadMacro4( rStrm
, nMacroSize
);
949 void XclImpGroupObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
952 rStrm
>> mnFirstUngrouped
;
954 ReadName5( rStrm
, nNameLen
);
955 ReadMacro5( rStrm
, nMacroSize
);
958 sal_Size
XclImpGroupObj::DoGetProgressSize() const
960 return XclImpDrawObjBase::DoGetProgressSize() + maChildren
.GetProgressSize();
963 SdrObject
* XclImpGroupObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& /*rAnchorRect*/ ) const
965 TSdrObjectPtr
< SdrObjGroup
> xSdrObj( new SdrObjGroup
);
966 // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle
967 SdrObjList
& rObjList
= *xSdrObj
->GetSubList(); // SdrObjGroup always returns existing sublist
968 for( XclImpDrawObjVector::const_iterator aIt
= maChildren
.begin(), aEnd
= maChildren
.end(); aIt
!= aEnd
; ++aIt
)
969 rDffConv
.ProcessObject( rObjList
, **aIt
);
971 return xSdrObj
.release();
974 // ----------------------------------------------------------------------------
976 XclImpLineObj::XclImpLineObj( const XclImpRoot
& rRoot
) :
977 XclImpDrawObjBase( rRoot
),
979 mnStartPoint( EXC_OBJ_LINE_TL
)
984 void XclImpLineObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
986 rStrm
>> maLineData
>> mnArrows
>> mnStartPoint
;
988 ReadMacro3( rStrm
, nMacroSize
);
991 void XclImpLineObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
993 rStrm
>> maLineData
>> mnArrows
>> mnStartPoint
;
995 ReadMacro4( rStrm
, nMacroSize
);
998 void XclImpLineObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1000 rStrm
>> maLineData
>> mnArrows
>> mnStartPoint
;
1002 ReadName5( rStrm
, nNameLen
);
1003 ReadMacro5( rStrm
, nMacroSize
);
1006 SdrObject
* XclImpLineObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
1008 ::basegfx::B2DPolygon aB2DPolygon
;
1009 switch( mnStartPoint
)
1012 case EXC_OBJ_LINE_TL
:
1013 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Top() ) );
1014 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Bottom() ) );
1016 case EXC_OBJ_LINE_TR
:
1017 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Top() ) );
1018 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Bottom() ) );
1020 case EXC_OBJ_LINE_BR
:
1021 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Bottom() ) );
1022 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Top() ) );
1024 case EXC_OBJ_LINE_BL
:
1025 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Bottom() ) );
1026 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Top() ) );
1029 SdrObjectPtr
xSdrObj( new SdrPathObj( OBJ_LINE
, ::basegfx::B2DPolyPolygon( aB2DPolygon
) ) );
1030 ConvertLineStyle( *xSdrObj
, maLineData
);
1033 sal_uInt8 nArrowType
= ::extract_value
< sal_uInt8
>( mnArrows
, 0, 4 );
1034 bool bLineStart
= false;
1035 bool bLineEnd
= false;
1036 bool bFilled
= false;
1037 switch( nArrowType
)
1039 case EXC_OBJ_ARROW_OPEN
: bLineStart
= false; bLineEnd
= true; bFilled
= false; break;
1040 case EXC_OBJ_ARROW_OPENBOTH
: bLineStart
= true; bLineEnd
= true; bFilled
= false; break;
1041 case EXC_OBJ_ARROW_FILLED
: bLineStart
= false; bLineEnd
= true; bFilled
= true; break;
1042 case EXC_OBJ_ARROW_FILLEDBOTH
: bLineStart
= true; bLineEnd
= true; bFilled
= true; break;
1044 if( bLineStart
|| bLineEnd
)
1046 sal_uInt8 nArrowWidth
= ::extract_value
< sal_uInt8
>( mnArrows
, 4, 4 );
1047 double fArrowWidth
= 3.0;
1048 switch( nArrowWidth
)
1050 case EXC_OBJ_ARROW_NARROW
: fArrowWidth
= 2.0; break;
1051 case EXC_OBJ_ARROW_MEDIUM
: fArrowWidth
= 3.0; break;
1052 case EXC_OBJ_ARROW_WIDE
: fArrowWidth
= 5.0; break;
1055 sal_uInt8 nArrowLength
= ::extract_value
< sal_uInt8
>( mnArrows
, 8, 4 );
1056 double fArrowLength
= 3.0;
1057 switch( nArrowLength
)
1059 case EXC_OBJ_ARROW_NARROW
: fArrowLength
= 2.5; break;
1060 case EXC_OBJ_ARROW_MEDIUM
: fArrowLength
= 3.5; break;
1061 case EXC_OBJ_ARROW_WIDE
: fArrowLength
= 6.0; break;
1064 ::basegfx::B2DPolygon aArrowPoly
;
1065 #define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) )
1068 aArrowPoly
.append( EXC_ARROW_POINT( 0, 100 ) );
1069 aArrowPoly
.append( EXC_ARROW_POINT( 50, 0 ) );
1070 aArrowPoly
.append( EXC_ARROW_POINT( 100, 100 ) );
1074 sal_uInt8 nLineWidth
= ::limit_cast
< sal_uInt8
>( maLineData
.mnWidth
, EXC_OBJ_LINE_THIN
, EXC_OBJ_LINE_THICK
);
1075 aArrowPoly
.append( EXC_ARROW_POINT( 50, 0 ) );
1076 aArrowPoly
.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth
) );
1077 aArrowPoly
.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth
, 100 ) );
1078 aArrowPoly
.append( EXC_ARROW_POINT( 50, 12 * nLineWidth
) );
1079 aArrowPoly
.append( EXC_ARROW_POINT( 5 * nLineWidth
, 100 ) );
1080 aArrowPoly
.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth
) );
1082 #undef EXC_ARROW_POINT
1084 ::basegfx::B2DPolyPolygon
aArrowPolyPoly( aArrowPoly
);
1085 long nWidth
= static_cast< long >( 125 * fArrowWidth
);
1088 xSdrObj
->SetMergedItem( XLineStartItem( EMPTY_STRING
, aArrowPolyPoly
) );
1089 xSdrObj
->SetMergedItem( XLineStartWidthItem( nWidth
) );
1090 xSdrObj
->SetMergedItem( XLineStartCenterItem( false ) );
1094 xSdrObj
->SetMergedItem( XLineEndItem( EMPTY_STRING
, aArrowPolyPoly
) );
1095 xSdrObj
->SetMergedItem( XLineEndWidthItem( nWidth
) );
1096 xSdrObj
->SetMergedItem( XLineEndCenterItem( false ) );
1099 rDffConv
.Progress();
1100 return xSdrObj
.release();
1103 // ----------------------------------------------------------------------------
1105 XclImpRectObj::XclImpRectObj( const XclImpRoot
& rRoot
) :
1106 XclImpDrawObjBase( rRoot
),
1112 void XclImpRectObj::ReadFrameData( XclImpStream
& rStrm
)
1114 rStrm
>> maFillData
>> maLineData
>> mnFrameFlags
;
1117 void XclImpRectObj::ConvertRectStyle( SdrObject
& rSdrObj
) const
1119 ConvertLineStyle( rSdrObj
, maLineData
);
1120 ConvertFillStyle( rSdrObj
, maFillData
);
1121 ConvertFrameStyle( rSdrObj
, mnFrameFlags
);
1124 void XclImpRectObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1126 ReadFrameData( rStrm
);
1127 ReadMacro3( rStrm
, nMacroSize
);
1130 void XclImpRectObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1132 ReadFrameData( rStrm
);
1133 ReadMacro4( rStrm
, nMacroSize
);
1136 void XclImpRectObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1138 ReadFrameData( rStrm
);
1139 ReadName5( rStrm
, nNameLen
);
1140 ReadMacro5( rStrm
, nMacroSize
);
1143 SdrObject
* XclImpRectObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
1145 SdrObjectPtr
xSdrObj( new SdrRectObj( rAnchorRect
) );
1146 ConvertRectStyle( *xSdrObj
);
1147 rDffConv
.Progress();
1148 return xSdrObj
.release();
1151 // ----------------------------------------------------------------------------
1153 XclImpOvalObj::XclImpOvalObj( const XclImpRoot
& rRoot
) :
1154 XclImpRectObj( rRoot
)
1158 SdrObject
* XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
1160 SdrObjectPtr
xSdrObj( new SdrCircObj( OBJ_CIRC
, rAnchorRect
) );
1161 ConvertRectStyle( *xSdrObj
);
1162 rDffConv
.Progress();
1163 return xSdrObj
.release();
1166 // ----------------------------------------------------------------------------
1168 XclImpArcObj::XclImpArcObj( const XclImpRoot
& rRoot
) :
1169 XclImpDrawObjBase( rRoot
),
1170 mnQuadrant( EXC_OBJ_ARC_TR
)
1172 SetAreaObj( false ); // arc may be 2-dimensional
1175 void XclImpArcObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1177 rStrm
>> maFillData
>> maLineData
>> mnQuadrant
;
1179 ReadMacro3( rStrm
, nMacroSize
);
1182 void XclImpArcObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1184 rStrm
>> maFillData
>> maLineData
>> mnQuadrant
;
1186 ReadMacro4( rStrm
, nMacroSize
);
1189 void XclImpArcObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1191 rStrm
>> maFillData
>> maLineData
>> mnQuadrant
;
1193 ReadName5( rStrm
, nNameLen
);
1194 ReadMacro5( rStrm
, nMacroSize
);
1197 SdrObject
* XclImpArcObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
1199 Rectangle aNewRect
= rAnchorRect
;
1200 long nStartAngle
= 0;
1202 switch( mnQuadrant
)
1205 case EXC_OBJ_ARC_TR
:
1208 aNewRect
.Left() -= rAnchorRect
.GetWidth();
1209 aNewRect
.Bottom() += rAnchorRect
.GetHeight();
1211 case EXC_OBJ_ARC_TL
:
1214 aNewRect
.Right() += rAnchorRect
.GetWidth();
1215 aNewRect
.Bottom() += rAnchorRect
.GetHeight();
1217 case EXC_OBJ_ARC_BL
:
1218 nStartAngle
= 18000;
1220 aNewRect
.Right() += rAnchorRect
.GetWidth();
1221 aNewRect
.Top() -= rAnchorRect
.GetHeight();
1223 case EXC_OBJ_ARC_BR
:
1224 nStartAngle
= 27000;
1226 aNewRect
.Left() -= rAnchorRect
.GetWidth();
1227 aNewRect
.Top() -= rAnchorRect
.GetHeight();
1230 SdrObjKind eObjKind
= maFillData
.IsFilled() ? OBJ_SECT
: OBJ_CARC
;
1231 SdrObjectPtr
xSdrObj( new SdrCircObj( eObjKind
, aNewRect
, nStartAngle
, nEndAngle
) );
1232 ConvertFillStyle( *xSdrObj
, maFillData
);
1233 ConvertLineStyle( *xSdrObj
, maLineData
);
1234 rDffConv
.Progress();
1235 return xSdrObj
.release();
1238 // ----------------------------------------------------------------------------
1240 XclImpPolygonObj::XclImpPolygonObj( const XclImpRoot
& rRoot
) :
1241 XclImpRectObj( rRoot
),
1245 SetAreaObj( false ); // polygon may be 2-dimensional
1248 void XclImpPolygonObj::ReadCoordList( XclImpStream
& rStrm
)
1250 if( (rStrm
.GetNextRecId() == EXC_ID_COORDLIST
) && rStrm
.StartNextRecord() )
1252 OSL_ENSURE( rStrm
.GetRecLeft() / 4 == mnPointCount
, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" );
1253 while( rStrm
.GetRecLeft() >= 4 )
1257 maCoords
.push_back( Point( nX
, nY
) );
1262 void XclImpPolygonObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1264 ReadFrameData( rStrm
);
1265 rStrm
>> mnPolyFlags
;
1267 rStrm
>> mnPointCount
;
1269 ReadMacro4( rStrm
, nMacroSize
);
1270 ReadCoordList( rStrm
);
1273 void XclImpPolygonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1275 ReadFrameData( rStrm
);
1276 rStrm
>> mnPolyFlags
;
1278 rStrm
>> mnPointCount
;
1280 ReadName5( rStrm
, nNameLen
);
1281 ReadMacro5( rStrm
, nMacroSize
);
1282 ReadCoordList( rStrm
);
1287 ::basegfx::B2DPoint
lclGetPolyPoint( const Rectangle
& rAnchorRect
, const Point
& rPoint
)
1289 return ::basegfx::B2DPoint(
1290 rAnchorRect
.Left() + static_cast< sal_Int32
>( ::std::min
< double >( rPoint
.X(), 16384.0 ) / 16384.0 * rAnchorRect
.GetWidth() + 0.5 ),
1291 rAnchorRect
.Top() + static_cast< sal_Int32
>( ::std::min
< double >( rPoint
.Y(), 16384.0 ) / 16384.0 * rAnchorRect
.GetHeight() + 0.5 ) );
1296 SdrObject
* XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
1298 SdrObjectPtr xSdrObj
;
1299 if( maCoords
.size() >= 2 )
1301 // create the polygon
1302 ::basegfx::B2DPolygon aB2DPolygon
;
1303 for( PointVector::const_iterator aIt
= maCoords
.begin(), aEnd
= maCoords
.end(); aIt
!= aEnd
; ++aIt
)
1304 aB2DPolygon
.append( lclGetPolyPoint( rAnchorRect
, *aIt
) );
1305 // close polygon if specified
1306 if( ::get_flag( mnPolyFlags
, EXC_OBJ_POLY_CLOSED
) && (maCoords
.front() != maCoords
.back()) )
1307 aB2DPolygon
.append( lclGetPolyPoint( rAnchorRect
, maCoords
.front() ) );
1308 // create the SdrObject
1309 SdrObjKind eObjKind
= maFillData
.IsFilled() ? OBJ_PATHPOLY
: OBJ_PATHPLIN
;
1310 xSdrObj
.reset( new SdrPathObj( eObjKind
, ::basegfx::B2DPolyPolygon( aB2DPolygon
) ) );
1311 ConvertRectStyle( *xSdrObj
);
1313 rDffConv
.Progress();
1314 return xSdrObj
.release();
1317 // ----------------------------------------------------------------------------
1319 void XclImpObjTextData::ReadByteString( XclImpStream
& rStrm
)
1322 if( maData
.mnTextLen
> 0 )
1324 mxString
.reset( new XclImpString( rStrm
.ReadRawByteString( maData
.mnTextLen
) ) );
1325 // skip padding byte for word boundaries
1326 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
1330 void XclImpObjTextData::ReadFormats( XclImpStream
& rStrm
)
1333 mxString
->ReadObjFormats( rStrm
, maData
.mnFormatSize
);
1335 rStrm
.Ignore( maData
.mnFormatSize
);
1338 // ----------------------------------------------------------------------------
1340 XclImpTextObj::XclImpTextObj( const XclImpRoot
& rRoot
) :
1341 XclImpRectObj( rRoot
)
1345 void XclImpTextObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1347 ReadFrameData( rStrm
);
1348 maTextData
.maData
.ReadObj3( rStrm
);
1349 ReadMacro3( rStrm
, nMacroSize
);
1350 maTextData
.ReadByteString( rStrm
);
1351 maTextData
.ReadFormats( rStrm
);
1354 void XclImpTextObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1356 ReadFrameData( rStrm
);
1357 maTextData
.maData
.ReadObj3( rStrm
);
1358 ReadMacro4( rStrm
, nMacroSize
);
1359 maTextData
.ReadByteString( rStrm
);
1360 maTextData
.ReadFormats( rStrm
);
1363 void XclImpTextObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1365 ReadFrameData( rStrm
);
1366 maTextData
.maData
.ReadObj5( rStrm
);
1367 ReadName5( rStrm
, nNameLen
);
1368 ReadMacro5( rStrm
, nMacroSize
);
1369 maTextData
.ReadByteString( rStrm
);
1370 rStrm
.Ignore( maTextData
.maData
.mnLinkSize
); // ignore text link formula
1371 maTextData
.ReadFormats( rStrm
);
1374 SdrObject
* XclImpTextObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
1376 TSdrObjectPtr
< SdrObjCustomShape
> xSdrObj( new SdrObjCustomShape
);
1377 xSdrObj
->NbcSetSnapRect( rAnchorRect
);
1378 OUString aRectType
= "rectangle";
1379 xSdrObj
->MergeDefaultAttributes( &aRectType
);
1380 ConvertRectStyle( *xSdrObj
);
1381 sal_Bool bAutoSize
= ::get_flag( maTextData
.maData
.mnFlags
, EXC_OBJ_TEXT_AUTOSIZE
);
1382 xSdrObj
->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize
) );
1383 xSdrObj
->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize
) );
1384 xSdrObj
->SetMergedItem( SdrTextWordWrapItem( sal_True
) );
1385 rDffConv
.Progress();
1386 return xSdrObj
.release();
1389 void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
1392 if( SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( &rSdrObj
) )
1394 if( maTextData
.mxString
)
1396 if( maTextData
.mxString
->IsRich() )
1399 ::std::auto_ptr
< EditTextObject
> xEditObj(
1400 XclImpStringHelper::CreateTextObject( GetRoot(), *maTextData
.mxString
) );
1401 OutlinerParaObject
* pOutlineObj
= new OutlinerParaObject( *xEditObj
);
1402 pOutlineObj
->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT
);
1403 // text object takes ownership of the outliner object
1404 pTextObj
->NbcSetOutlinerParaObject( pOutlineObj
);
1409 pTextObj
->NbcSetText( maTextData
.mxString
->GetText() );
1412 /* #i96858# Do not apply any formatting if there is no text.
1413 SdrObjCustomShape::SetVerticalWriting (initiated from
1414 SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which
1415 ensures that we can erroneously write a ClientTextbox record
1416 (with no content) while exporting to XLS, which can cause a
1417 corrupted exported document. */
1419 SvxAdjust eHorAlign
= SVX_ADJUST_LEFT
;
1420 SdrTextVertAdjust eVerAlign
= SDRTEXTVERTADJUST_TOP
;
1422 // orientation (this is only a fake, drawing does not support real text orientation)
1423 namespace csst
= ::com::sun::star::text
;
1424 csst::WritingMode eWriteMode
= csst::WritingMode_LR_TB
;
1425 switch( maTextData
.maData
.mnOrient
)
1428 case EXC_OBJ_ORIENT_NONE
:
1430 eWriteMode
= csst::WritingMode_LR_TB
;
1431 switch( maTextData
.maData
.GetHorAlign() )
1433 case EXC_OBJ_HOR_LEFT
: eHorAlign
= SVX_ADJUST_LEFT
; break;
1434 case EXC_OBJ_HOR_CENTER
: eHorAlign
= SVX_ADJUST_CENTER
; break;
1435 case EXC_OBJ_HOR_RIGHT
: eHorAlign
= SVX_ADJUST_RIGHT
; break;
1436 case EXC_OBJ_HOR_JUSTIFY
: eHorAlign
= SVX_ADJUST_BLOCK
; break;
1438 switch( maTextData
.maData
.GetVerAlign() )
1440 case EXC_OBJ_VER_TOP
: eVerAlign
= SDRTEXTVERTADJUST_TOP
; break;
1441 case EXC_OBJ_VER_CENTER
: eVerAlign
= SDRTEXTVERTADJUST_CENTER
; break;
1442 case EXC_OBJ_VER_BOTTOM
: eVerAlign
= SDRTEXTVERTADJUST_BOTTOM
; break;
1443 case EXC_OBJ_VER_JUSTIFY
: eVerAlign
= SDRTEXTVERTADJUST_BLOCK
; break;
1448 case EXC_OBJ_ORIENT_90CCW
:
1450 if( SdrObjCustomShape
* pObjCustomShape
= dynamic_cast< SdrObjCustomShape
* >( &rSdrObj
) )
1452 double fAngle
= 180.0;
1453 com::sun::star::beans::PropertyValue aTextRotateAngle
;
1454 aTextRotateAngle
.Name
= OUString( "TextRotateAngle" );
1455 aTextRotateAngle
.Value
<<= fAngle
;
1456 SdrCustomShapeGeometryItem
aGeometryItem((SdrCustomShapeGeometryItem
&)pObjCustomShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
));
1457 aGeometryItem
.SetPropertyValue( aTextRotateAngle
);
1458 pObjCustomShape
->SetMergedItem( aGeometryItem
);
1460 eWriteMode
= csst::WritingMode_TB_RL
;
1461 switch( maTextData
.maData
.GetHorAlign() )
1463 case EXC_OBJ_HOR_LEFT
: eVerAlign
= SDRTEXTVERTADJUST_TOP
; break;
1464 case EXC_OBJ_HOR_CENTER
: eVerAlign
= SDRTEXTVERTADJUST_CENTER
; break;
1465 case EXC_OBJ_HOR_RIGHT
: eVerAlign
= SDRTEXTVERTADJUST_BOTTOM
; break;
1466 case EXC_OBJ_HOR_JUSTIFY
: eVerAlign
= SDRTEXTVERTADJUST_BLOCK
; break;
1468 MSO_Anchor eTextAnchor
= (MSO_Anchor
)rDffConv
.GetPropertyValue( DFF_Prop_anchorText
, mso_anchorTop
);
1469 switch( eTextAnchor
)
1471 case mso_anchorTopCentered
:
1472 case mso_anchorMiddleCentered
:
1473 case mso_anchorBottomCentered
:
1475 eHorAlign
= SVX_ADJUST_CENTER
;
1481 switch( maTextData
.maData
.GetVerAlign() )
1483 case EXC_OBJ_VER_TOP
: eHorAlign
= SVX_ADJUST_RIGHT
; break;
1484 case EXC_OBJ_VER_CENTER
: eHorAlign
= SVX_ADJUST_CENTER
; break;
1485 case EXC_OBJ_VER_BOTTOM
: eHorAlign
= SVX_ADJUST_LEFT
; break;
1486 case EXC_OBJ_VER_JUSTIFY
: eHorAlign
= SVX_ADJUST_BLOCK
; break;
1493 case EXC_OBJ_ORIENT_STACKED
: // PASSTHROUGH INTENDED
1495 // sj: STACKED is not supported, maybe it can be optimized here a bit
1497 case EXC_OBJ_ORIENT_90CW
:
1499 eWriteMode
= csst::WritingMode_TB_RL
;
1500 switch( maTextData
.maData
.GetHorAlign() )
1502 case EXC_OBJ_HOR_LEFT
: eVerAlign
= SDRTEXTVERTADJUST_BOTTOM
; break;
1503 case EXC_OBJ_HOR_CENTER
: eVerAlign
= SDRTEXTVERTADJUST_CENTER
; break;
1504 case EXC_OBJ_HOR_RIGHT
: eVerAlign
= SDRTEXTVERTADJUST_TOP
; break;
1505 case EXC_OBJ_HOR_JUSTIFY
: eVerAlign
= SDRTEXTVERTADJUST_BLOCK
; break;
1507 MSO_Anchor eTextAnchor
= (MSO_Anchor
)rDffConv
.GetPropertyValue( DFF_Prop_anchorText
, mso_anchorTop
);
1508 switch ( eTextAnchor
)
1510 case mso_anchorTopCentered
:
1511 case mso_anchorMiddleCentered
:
1512 case mso_anchorBottomCentered
:
1514 eHorAlign
= SVX_ADJUST_CENTER
;
1520 switch( maTextData
.maData
.GetVerAlign() )
1522 case EXC_OBJ_VER_TOP
: eHorAlign
= SVX_ADJUST_LEFT
; break;
1523 case EXC_OBJ_VER_CENTER
: eHorAlign
= SVX_ADJUST_CENTER
; break;
1524 case EXC_OBJ_VER_BOTTOM
: eHorAlign
= SVX_ADJUST_RIGHT
; break;
1525 case EXC_OBJ_VER_JUSTIFY
: eHorAlign
= SVX_ADJUST_BLOCK
; break;
1532 rSdrObj
.SetMergedItem( SvxAdjustItem( eHorAlign
, EE_PARA_JUST
) );
1533 rSdrObj
.SetMergedItem( SdrTextVertAdjustItem( eVerAlign
) );
1534 rSdrObj
.SetMergedItem( SvxWritingModeItem( eWriteMode
, SDRATTR_TEXTDIRECTION
) );
1537 // base class processing
1538 XclImpRectObj::DoPreProcessSdrObj( rDffConv
, rSdrObj
);
1541 // ----------------------------------------------------------------------------
1543 XclImpChartObj::XclImpChartObj( const XclImpRoot
& rRoot
, bool bOwnTab
) :
1544 XclImpRectObj( rRoot
),
1547 SetSimpleMacro( false );
1548 SetCustomDffObj( true );
1551 void XclImpChartObj::ReadChartSubStream( XclImpStream
& rStrm
)
1553 /* If chart is read from a chartsheet (mbOwnTab == true), the BOF record
1554 has already been read. If chart is embedded as object, the next record
1555 has to be the BOF record. */
1558 /* #i109800# The input stream may point somewhere inside the chart
1559 substream and not exactly to the leading BOF record. To read this
1560 record correctly in the following, the stream has to rewind it, so
1561 that the next call to StartNextRecord() will find it correctly. */
1562 if( rStrm
.GetRecId() != EXC_ID5_BOF
)
1563 rStrm
.RewindRecord();
1567 if( (rStrm
.GetNextRecId() == EXC_ID5_BOF
) && rStrm
.StartNextRecord() )
1569 sal_uInt16 nBofType
;
1572 DBG_ASSERT( nBofType
== EXC_BOF_CHART
, "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
1576 DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" );
1581 // read chart, even if BOF record contains wrong substream identifier
1582 mxChart
.reset( new XclImpChart( GetRoot(), mbOwnTab
) );
1583 mxChart
->ReadChartSubStream( rStrm
);
1588 void XclImpChartObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1590 // read OBJ record and the following chart substream
1591 ReadFrameData( rStrm
);
1593 ReadMacro3( rStrm
, nMacroSize
);
1594 // set frame format from OBJ record, it is used if chart itself is transparent
1596 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1599 void XclImpChartObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1601 // read OBJ record and the following chart substream
1602 ReadFrameData( rStrm
);
1604 ReadMacro4( rStrm
, nMacroSize
);
1605 // set frame format from OBJ record, it is used if chart itself is transparent
1607 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1610 void XclImpChartObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1612 // read OBJ record and the following chart substream
1613 ReadFrameData( rStrm
);
1615 ReadName5( rStrm
, nNameLen
);
1616 ReadMacro5( rStrm
, nMacroSize
);
1617 ReadChartSubStream( rStrm
);
1618 // set frame format from OBJ record, it is used if chart itself is transparent
1620 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1623 void XclImpChartObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16
/*nSubRecSize*/ )
1625 // read the following chart substream
1626 if( nSubRecId
== EXC_ID_OBJEND
)
1628 // enable CONTINUE handling for the entire chart substream
1629 rStrm
.ResetRecord( true );
1630 ReadChartSubStream( rStrm
);
1631 /* disable CONTINUE handling again to be able to read
1632 following CONTINUE records as MSODRAWING records. */
1633 rStrm
.ResetRecord( false );
1637 sal_Size
XclImpChartObj::DoGetProgressSize() const
1639 return mxChart
? mxChart
->GetProgressSize() : 1;
1642 SdrObject
* XclImpChartObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
1644 SdrObjectPtr xSdrObj
;
1645 SfxObjectShell
* pDocShell
= GetDocShell();
1646 if( rDffConv
.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell
&& mxChart
&& !mxChart
->IsPivotChart() )
1648 // create embedded chart object
1649 OUString aEmbObjName
;
1650 Reference
< XEmbeddedObject
> xEmbObj
= pDocShell
->GetEmbeddedObjectContainer().
1651 CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID
).GetByteSequence(), aEmbObjName
);
1653 /* Set the size to the embedded object, this prevents that font sizes
1654 of text objects are changed in the chart when the object is
1655 inserted into the draw page. */
1656 sal_Int64 nAspect
= ::com::sun::star::embed::Aspects::MSOLE_CONTENT
;
1657 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj
->getMapUnit( nAspect
) );
1658 Size
aSize( Window::LogicToLogic( rAnchorRect
.GetSize(), MapMode( MAP_100TH_MM
), MapMode( aUnit
) ) );
1659 ::com::sun::star::awt::Size
aAwtSize( aSize
.Width(), aSize
.Height() );
1660 xEmbObj
->setVisualAreaSize( nAspect
, aAwtSize
);
1662 // create the container OLE object
1663 xSdrObj
.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj
, nAspect
), aEmbObjName
, rAnchorRect
) );
1666 return xSdrObj
.release();
1669 void XclImpChartObj::DoPostProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
1671 const SdrOle2Obj
* pSdrOleObj
= dynamic_cast< const SdrOle2Obj
* >( &rSdrObj
);
1672 if( mxChart
&& pSdrOleObj
)
1674 Reference
< XEmbeddedObject
> xEmbObj
= pSdrOleObj
->GetObjRef();
1675 if( xEmbObj
.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj
) ) try
1677 Reference
< XEmbedPersist
> xPersist( xEmbObj
, UNO_QUERY_THROW
);
1678 Reference
< XModel
> xModel( xEmbObj
->getComponent(), UNO_QUERY_THROW
);
1679 mxChart
->Convert( xModel
, rDffConv
, xPersist
->getEntryName(), rSdrObj
.GetLogicRect() );
1681 catch( const Exception
& )
1687 void XclImpChartObj::FinalizeTabChart()
1689 /* #i44077# Calculate and store DFF anchor for sheet charts.
1690 Needed to get used area if this chart is inserted as OLE object. */
1691 OSL_ENSURE( mbOwnTab
, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" );
1693 // set uninitialized page to landscape
1694 if( !GetPageSettings().GetPageData().mbValid
)
1695 GetPageSettings().SetPaperSize( EXC_PAPERSIZE_DEFAULT
, false );
1697 // calculate size of the chart object
1698 const XclPageData
& rPageData
= GetPageSettings().GetPageData();
1699 Size aPaperSize
= rPageData
.GetScPaperSize();
1701 long nWidth
= XclTools::GetHmmFromTwips( aPaperSize
.Width() );
1702 long nHeight
= XclTools::GetHmmFromTwips( aPaperSize
.Height() );
1704 // subtract page margins, give some more extra space
1705 nWidth
-= (XclTools::GetHmmFromInch( rPageData
.mfLeftMargin
+ rPageData
.mfRightMargin
) + 2000);
1706 nHeight
-= (XclTools::GetHmmFromInch( rPageData
.mfTopMargin
+ rPageData
.mfBottomMargin
) + 1000);
1708 // print column/row headers?
1709 if( rPageData
.mbPrintHeadings
)
1715 // create the object anchor
1716 XclObjAnchor aAnchor
;
1717 aAnchor
.SetRect( GetRoot(), GetCurrScTab(), Rectangle( 1000, 500, nWidth
, nHeight
), MAP_100TH_MM
);
1718 SetAnchor( aAnchor
);
1721 // ----------------------------------------------------------------------------
1723 XclImpNoteObj::XclImpNoteObj( const XclImpRoot
& rRoot
) :
1724 XclImpTextObj( rRoot
),
1725 maScPos( ScAddress::INITIALIZE_INVALID
),
1728 SetSimpleMacro( false );
1729 // caption object will be created manually
1730 SetInsertSdrObj( false );
1733 void XclImpNoteObj::SetNoteData( const ScAddress
& rScPos
, sal_uInt16 nNoteFlags
)
1736 mnNoteFlags
= nNoteFlags
;
1739 void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
1741 // create formatted text
1742 XclImpTextObj::DoPreProcessSdrObj( rDffConv
, rSdrObj
);
1743 OutlinerParaObject
* pOutlinerObj
= rSdrObj
.GetOutlinerParaObject();
1744 if( maScPos
.IsValid() && pOutlinerObj
)
1746 // create cell note with all data from drawing object
1747 ScNoteUtil::CreateNoteFromObjectData(
1749 rSdrObj
.GetMergedItemSet().Clone(), // new object on heap expected
1750 new OutlinerParaObject( *pOutlinerObj
), // new object on heap expected
1751 rSdrObj
.GetLogicRect(),
1752 ::get_flag( mnNoteFlags
, EXC_NOTE_VISIBLE
),
1757 // ----------------------------------------------------------------------------
1759 XclImpControlHelper::XclImpControlHelper( const XclImpRoot
& rRoot
, XclCtrlBindMode eBindMode
) :
1761 meBindMode( eBindMode
)
1765 XclImpControlHelper::~XclImpControlHelper()
1769 SdrObject
* XclImpControlHelper::CreateSdrObjectFromShape(
1770 const Reference
< XShape
>& rxShape
, const Rectangle
& rAnchorRect
) const
1773 SdrObjectPtr
xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape
) );
1776 xSdrObj
->NbcSetSnapRect( rAnchorRect
);
1777 // #i30543# insert into control layer
1778 xSdrObj
->NbcSetLayer( SC_LAYER_CONTROLS
);
1780 return xSdrObj
.release();
1783 void XclImpControlHelper::ApplySheetLinkProps() const
1786 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( mxShape
);
1787 if( !xCtrlModel
.is() )
1789 ScfPropertySet
aPropSet( xCtrlModel
);
1792 if( SfxObjectShell
* pDocShell
= mrRoot
.GetDocShell() )
1794 Reference
< XMultiServiceFactory
> xFactory( pDocShell
->GetModel(), UNO_QUERY
);
1798 if( mxCellLink
) try
1800 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY_THROW
);
1802 // create argument sequence for createInstanceWithArguments()
1803 CellAddress aApiAddress
;
1804 ScUnoConversion::FillApiAddress( aApiAddress
, *mxCellLink
);
1807 aValue
.Name
= SC_UNONAME_BOUNDCELL
;
1808 aValue
.Value
<<= aApiAddress
;
1810 Sequence
< Any
> aArgs( 1 );
1811 aArgs
[ 0 ] <<= aValue
;
1813 // create the CellValueBinding instance and set at the control model
1814 OUString aServiceName
;
1815 switch( meBindMode
)
1817 case EXC_CTRL_BINDCONTENT
: aServiceName
= SC_SERVICENAME_VALBIND
; break;
1818 case EXC_CTRL_BINDPOSITION
: aServiceName
= SC_SERVICENAME_LISTCELLBIND
; break;
1820 Reference
< XValueBinding
> xBinding(
1821 xFactory
->createInstanceWithArguments( aServiceName
, aArgs
), UNO_QUERY_THROW
);
1822 xBindable
->setValueBinding( xBinding
);
1824 catch( const Exception
& )
1829 if( mxSrcRange
) try
1831 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY_THROW
);
1833 // create argument sequence for createInstanceWithArguments()
1834 CellRangeAddress aApiRange
;
1835 ScUnoConversion::FillApiRange( aApiRange
, *mxSrcRange
);
1838 aValue
.Name
= SC_UNONAME_CELLRANGE
;
1839 aValue
.Value
<<= aApiRange
;
1841 Sequence
< Any
> aArgs( 1 );
1842 aArgs
[ 0 ] <<= aValue
;
1844 // create the EntrySource instance and set at the control model
1845 Reference
< XListEntrySource
> xEntrySource( xFactory
->createInstanceWithArguments(
1846 SC_SERVICENAME_LISTSOURCE
, aArgs
), UNO_QUERY_THROW
);
1847 xEntrySink
->setListEntrySource( xEntrySource
);
1849 catch( const Exception
& )
1856 void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase
& rDrawObj
) const
1858 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( mxShape
);
1859 if( !xCtrlModel
.is() )
1862 ApplySheetLinkProps();
1864 ScfPropertySet
aPropSet( xCtrlModel
);
1866 // #i51348# set object name at control model
1867 aPropSet
.SetStringProperty( "Name", rDrawObj
.GetObjName() );
1869 // control visible and printable?
1870 aPropSet
.SetBoolProperty( "EnableVisible", rDrawObj
.IsVisible() );
1871 aPropSet
.SetBoolProperty( "Printable", rDrawObj
.IsPrintable() );
1874 // virtual call for type specific processing
1875 DoProcessControl( aPropSet
);
1878 void XclImpControlHelper::ReadCellLinkFormula( XclImpStream
& rStrm
, bool bWithBoundSize
)
1880 ScRangeList aScRanges
;
1881 ReadRangeList( aScRanges
, rStrm
, bWithBoundSize
);
1882 // Use first cell of first range
1883 if ( !aScRanges
.empty() )
1885 const ScRange
* pScRange
= aScRanges
.front();
1886 mxCellLink
.reset( new ScAddress( pScRange
->aStart
) );
1890 void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream
& rStrm
, bool bWithBoundSize
)
1892 ScRangeList aScRanges
;
1893 ReadRangeList( aScRanges
, rStrm
, bWithBoundSize
);
1895 if ( !aScRanges
.empty() )
1897 const ScRange
* pScRange
= aScRanges
.front();
1898 mxSrcRange
.reset( new ScRange( *pScRange
) );
1902 void XclImpControlHelper::DoProcessControl( ScfPropertySet
& ) const
1906 void XclImpControlHelper::ReadRangeList( ScRangeList
& rScRanges
, XclImpStream
& rStrm
)
1908 XclTokenArray aXclTokArr
;
1909 aXclTokArr
.ReadSize( rStrm
);
1911 aXclTokArr
.ReadArray( rStrm
);
1912 mrRoot
.GetFormulaCompiler().CreateRangeList( rScRanges
, EXC_FMLATYPE_CONTROL
, aXclTokArr
, rStrm
);
1915 void XclImpControlHelper::ReadRangeList( ScRangeList
& rScRanges
, XclImpStream
& rStrm
, bool bWithBoundSize
)
1917 if( bWithBoundSize
)
1923 rStrm
.PushPosition();
1924 ReadRangeList( rScRanges
, rStrm
);
1925 rStrm
.PopPosition();
1926 rStrm
.Ignore( nSize
);
1931 ReadRangeList( rScRanges
, rStrm
);
1935 // ----------------------------------------------------------------------------
1937 XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot
& rRoot
) :
1938 XclImpTextObj( rRoot
),
1939 XclImpControlHelper( rRoot
, EXC_CTRL_BINDPOSITION
)
1941 SetSimpleMacro( false );
1942 SetCustomDffObj( true );
1947 void lclExtractColor( sal_uInt8
& rnColorIdx
, const DffPropSet
& rDffPropSet
, sal_uInt32 nPropId
)
1949 if( rDffPropSet
.IsProperty( nPropId
) )
1951 sal_uInt32 nColor
= rDffPropSet
.GetPropertyValue( nPropId
);
1952 if( (nColor
& 0xFF000000) == 0x08000000 )
1953 rnColorIdx
= ::extract_value
< sal_uInt8
>( nColor
, 0, 8 );
1959 void XclImpTbxObjBase::SetDffProperties( const DffPropSet
& rDffPropSet
)
1961 maFillData
.mnPattern
= rDffPropSet
.GetPropertyBool( DFF_Prop_fFilled
) ? EXC_PATT_SOLID
: EXC_PATT_NONE
;
1962 lclExtractColor( maFillData
.mnBackColorIdx
, rDffPropSet
, DFF_Prop_fillBackColor
);
1963 lclExtractColor( maFillData
.mnPattColorIdx
, rDffPropSet
, DFF_Prop_fillColor
);
1964 ::set_flag( maFillData
.mnAuto
, EXC_OBJ_LINE_AUTO
, false );
1966 maLineData
.mnStyle
= rDffPropSet
.GetPropertyBool( DFF_Prop_fLine
) ? EXC_OBJ_LINE_SOLID
: EXC_OBJ_LINE_NONE
;
1967 lclExtractColor( maLineData
.mnColorIdx
, rDffPropSet
, DFF_Prop_lineColor
);
1968 ::set_flag( maLineData
.mnAuto
, EXC_OBJ_FILL_AUTO
, false );
1971 bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor
& rDescriptor
) const
1973 return XclControlHelper::FillMacroDescriptor( rDescriptor
, DoGetEventType(), GetMacroName(), GetDocShell() );
1976 void XclImpTbxObjBase::ConvertFont( ScfPropertySet
& rPropSet
) const
1978 if( maTextData
.mxString
)
1980 const XclFormatRunVec
& rFormatRuns
= maTextData
.mxString
->GetFormats();
1981 if( rFormatRuns
.empty() )
1982 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet
);
1984 GetFontBuffer().WriteFontProperties( rPropSet
, EXC_FONTPROPSET_CONTROL
, rFormatRuns
.front().mnFontIdx
);
1988 void XclImpTbxObjBase::ConvertLabel( ScfPropertySet
& rPropSet
) const
1990 if( maTextData
.mxString
)
1992 String aLabel
= maTextData
.mxString
->GetText();
1993 if( maTextData
.maData
.mnShortcut
> 0 )
1995 xub_StrLen nPos
= aLabel
.Search( static_cast< sal_Unicode
>( maTextData
.maData
.mnShortcut
) );
1996 if( nPos
!= STRING_NOTFOUND
)
1997 aLabel
.Insert( '~', nPos
);
1999 rPropSet
.SetStringProperty( "Label", aLabel
);
2001 ConvertFont( rPropSet
);
2004 SdrObject
* XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
2006 SdrObjectPtr
xSdrObj( rDffConv
.CreateSdrObject( *this, rAnchorRect
) );
2007 rDffConv
.Progress();
2008 return xSdrObj
.release();
2011 void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter
& /*rDffConv*/, SdrObject
& /*rSdrObj*/ ) const
2013 // do not call DoPreProcessSdrObj() from base class (to skip text processing)
2014 ProcessControl( *this );
2017 // ----------------------------------------------------------------------------
2019 XclImpButtonObj::XclImpButtonObj( const XclImpRoot
& rRoot
) :
2020 XclImpTbxObjBase( rRoot
)
2024 void XclImpButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2026 // label and text formatting
2027 ConvertLabel( rPropSet
);
2029 /* Horizontal text alignment. For unknown reason, the property type is a
2030 simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
2031 sal_Int16 nHorAlign
= 1;
2032 switch( maTextData
.maData
.GetHorAlign() )
2034 case EXC_OBJ_HOR_LEFT
: nHorAlign
= 0; break;
2035 case EXC_OBJ_HOR_CENTER
: nHorAlign
= 1; break;
2036 case EXC_OBJ_HOR_RIGHT
: nHorAlign
= 2; break;
2038 rPropSet
.SetProperty( "Align", nHorAlign
);
2040 // vertical text alignment
2041 namespace csss
= ::com::sun::star::style
;
2042 csss::VerticalAlignment eVerAlign
= csss::VerticalAlignment_MIDDLE
;
2043 switch( maTextData
.maData
.GetVerAlign() )
2045 case EXC_OBJ_VER_TOP
: eVerAlign
= csss::VerticalAlignment_TOP
; break;
2046 case EXC_OBJ_VER_CENTER
: eVerAlign
= csss::VerticalAlignment_MIDDLE
; break;
2047 case EXC_OBJ_VER_BOTTOM
: eVerAlign
= csss::VerticalAlignment_BOTTOM
; break;
2049 rPropSet
.SetProperty( "VerticalAlign", eVerAlign
);
2051 // always wrap text automatically
2052 rPropSet
.SetBoolProperty( "MultiLine", true );
2055 bool bDefButton
= ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_DEFAULT
);
2056 rPropSet
.SetBoolProperty( "DefaultButton", bDefButton
);
2058 // button type (flags cannot be combined in OOo)
2059 namespace cssa
= ::com::sun::star::awt
;
2060 cssa::PushButtonType eButtonType
= cssa::PushButtonType_STANDARD
;
2061 if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_CLOSE
) )
2062 eButtonType
= cssa::PushButtonType_OK
;
2063 else if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_CANCEL
) )
2064 eButtonType
= cssa::PushButtonType_CANCEL
;
2065 else if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_HELP
) )
2066 eButtonType
= cssa::PushButtonType_HELP
;
2067 // property type is short, not enum
2068 rPropSet
.SetProperty( "PushButtonType", sal_Int16( eButtonType
) );
2071 OUString
XclImpButtonObj::DoGetServiceName() const
2073 return OUString( "com.sun.star.form.component.CommandButton" );
2076 XclTbxEventType
XclImpButtonObj::DoGetEventType() const
2078 return EXC_TBX_EVENT_ACTION
;
2081 // ----------------------------------------------------------------------------
2083 XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot
& rRoot
) :
2084 XclImpTbxObjBase( rRoot
),
2085 mnState( EXC_OBJ_CHECKBOX_UNCHECKED
),
2086 mnCheckBoxFlags( 0 )
2090 void XclImpCheckBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2092 ReadFrameData( rStrm
);
2094 rStrm
>> maTextData
.maData
.mnFlags
;
2096 ReadName5( rStrm
, nNameLen
);
2097 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2098 ReadCellLinkFormula( rStrm
, true );
2099 rStrm
>> maTextData
.maData
.mnTextLen
;
2100 maTextData
.ReadByteString( rStrm
);
2101 rStrm
>> mnState
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnCheckBoxFlags
;
2104 void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2108 case EXC_ID_OBJCBLS
:
2109 // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
2112 rStrm
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnCheckBoxFlags
;
2114 case EXC_ID_OBJCBLSFMLA
:
2115 ReadCellLinkFormula( rStrm
, false );
2118 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2122 void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2124 // label and text formatting
2125 ConvertLabel( rPropSet
);
2128 bool bSupportsTristate
= GetObjType() == EXC_OBJTYPE_CHECKBOX
;
2129 sal_Int16 nApiState
= 0;
2132 case EXC_OBJ_CHECKBOX_UNCHECKED
: nApiState
= 0; break;
2133 case EXC_OBJ_CHECKBOX_CHECKED
: nApiState
= 1; break;
2134 case EXC_OBJ_CHECKBOX_TRISTATE
: nApiState
= bSupportsTristate
? 2 : 1; break;
2136 if( bSupportsTristate
)
2137 rPropSet
.SetBoolProperty( "TriState", nApiState
== 2 );
2138 rPropSet
.SetProperty( "DefaultState", nApiState
);
2141 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
2142 sal_Int16 nEffect
= ::get_flagvalue( mnCheckBoxFlags
, EXC_OBJ_CHECKBOX_FLAT
, AwtVisualEffect::FLAT
, AwtVisualEffect::LOOK3D
);
2143 rPropSet
.SetProperty( "VisualEffect", nEffect
);
2145 // do not wrap text automatically
2146 rPropSet
.SetBoolProperty( "MultiLine", false );
2148 // #i40279# always centered vertically
2149 namespace csss
= ::com::sun::star::style
;
2150 rPropSet
.SetProperty( "VerticalAlign", csss::VerticalAlignment_MIDDLE
);
2153 if( maFillData
.IsFilled() )
2155 sal_Int32 nColor
= static_cast< sal_Int32
>( GetSolidFillColor( maFillData
).GetColor() );
2156 rPropSet
.SetProperty( "BackgroundColor", nColor
);
2160 OUString
XclImpCheckBoxObj::DoGetServiceName() const
2162 return OUString( "com.sun.star.form.component.CheckBox" );
2165 XclTbxEventType
XclImpCheckBoxObj::DoGetEventType() const
2167 return EXC_TBX_EVENT_ACTION
;
2170 // ----------------------------------------------------------------------------
2172 XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot
& rRoot
) :
2173 XclImpCheckBoxObj( rRoot
),
2179 void XclImpOptionButtonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2181 ReadFrameData( rStrm
);
2183 rStrm
>> maTextData
.maData
.mnFlags
;
2185 ReadName5( rStrm
, nNameLen
);
2186 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2187 ReadCellLinkFormula( rStrm
, true );
2188 rStrm
>> maTextData
.maData
.mnTextLen
;
2189 maTextData
.ReadByteString( rStrm
);
2190 rStrm
>> mnState
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
;
2191 rStrm
>> mnCheckBoxFlags
>> mnNextInGroup
>> mnFirstInGroup
;
2194 void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2198 case EXC_ID_OBJRBODATA
:
2199 rStrm
>> mnNextInGroup
>> mnFirstInGroup
;
2202 XclImpCheckBoxObj::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2206 void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2208 XclImpCheckBoxObj::DoProcessControl( rPropSet
);
2210 XclImpOptionButtonObj
* pTbxObj
= dynamic_cast< XclImpOptionButtonObj
* >( GetObjectManager().GetSheetDrawing( GetTab() ).FindDrawObj( mnNextInGroup
).get() );
2211 if ( ( pTbxObj
&& pTbxObj
->mnFirstInGroup
) )
2213 // Group has terminated
2214 // traverse each RadioButton in group and
2215 // a) apply the groupname
2216 // b) propagate the linked cell from the lead radiobutton
2217 // c) apply the correct Ref value
2218 XclImpOptionButtonObj
* pLeader
= pTbxObj
;
2220 sal_Int32 nRefVal
= 1;
2221 OSL_TRACE( "0x%x start group ", pLeader
->GetObjId()/*.mnObjId */);
2225 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( pTbxObj
->mxShape
);
2226 if ( xCtrlModel
.is() )
2228 ScfPropertySet
aProps( xCtrlModel
);
2229 OUString sGroupName
= OUString::valueOf( static_cast< sal_Int32
>( pLeader
->GetDffShapeId() ) );
2231 aProps
.SetStringProperty( "GroupName", sGroupName
);
2232 aProps
.SetStringProperty( "RefValue", OUString::valueOf( nRefVal
++ ) );
2233 if ( pLeader
->HasCellLink() && !pTbxObj
->HasCellLink() )
2235 // propagate cell link info
2236 pTbxObj
->mxCellLink
.reset( new ScAddress( *pLeader
->mxCellLink
.get() ) );
2237 pTbxObj
->ApplySheetLinkProps();
2239 pTbxObj
= dynamic_cast< XclImpOptionButtonObj
* >( GetObjectManager().GetSheetDrawing( GetTab() ).FindDrawObj( pTbxObj
->mnNextInGroup
).get() );
2243 } while ( pTbxObj
&& !( pTbxObj
->mnFirstInGroup
== 1 ) );
2247 // not the leader? try and find it
2251 OUString
XclImpOptionButtonObj::DoGetServiceName() const
2253 return OUString( "com.sun.star.form.component.RadioButton" );
2256 XclTbxEventType
XclImpOptionButtonObj::DoGetEventType() const
2258 return EXC_TBX_EVENT_ACTION
;
2261 // ----------------------------------------------------------------------------
2263 XclImpLabelObj::XclImpLabelObj( const XclImpRoot
& rRoot
) :
2264 XclImpTbxObjBase( rRoot
)
2268 void XclImpLabelObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2270 // label and text formatting
2271 ConvertLabel( rPropSet
);
2273 // text alignment (always top/left aligned)
2274 rPropSet
.SetProperty( "Align", sal_Int16( 0 ) );
2275 namespace csss
= ::com::sun::star::style
;
2276 rPropSet
.SetProperty( "VerticalAlign", csss::VerticalAlignment_TOP
);
2278 // always wrap text automatically
2279 rPropSet
.SetBoolProperty( "MultiLine", true );
2282 OUString
XclImpLabelObj::DoGetServiceName() const
2284 return OUString( "com.sun.star.form.component.FixedText" );
2287 XclTbxEventType
XclImpLabelObj::DoGetEventType() const
2289 return EXC_TBX_EVENT_MOUSE
;
2292 // ----------------------------------------------------------------------------
2294 XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot
& rRoot
) :
2295 XclImpTbxObjBase( rRoot
),
2296 mnGroupBoxFlags( 0 )
2300 void XclImpGroupBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2302 ReadFrameData( rStrm
);
2304 rStrm
>> maTextData
.maData
.mnFlags
;
2306 ReadName5( rStrm
, nNameLen
);
2307 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2308 rStrm
>> maTextData
.maData
.mnTextLen
;
2309 maTextData
.ReadByteString( rStrm
);
2310 rStrm
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnGroupBoxFlags
;
2313 void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2317 case EXC_ID_OBJGBODATA
:
2318 rStrm
>> maTextData
.maData
.mnShortcut
>> maTextData
.maData
.mnShortcutEA
>> mnGroupBoxFlags
;
2321 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2325 void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2327 // label and text formatting
2328 ConvertLabel( rPropSet
);
2331 OUString
XclImpGroupBoxObj::DoGetServiceName() const
2333 return OUString( "com.sun.star.form.component.GroupBox" );
2336 XclTbxEventType
XclImpGroupBoxObj::DoGetEventType() const
2338 return EXC_TBX_EVENT_MOUSE
;
2341 // ----------------------------------------------------------------------------
2343 XclImpDialogObj::XclImpDialogObj( const XclImpRoot
& rRoot
) :
2344 XclImpTbxObjBase( rRoot
)
2348 void XclImpDialogObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2350 // label and text formatting
2351 ConvertLabel( rPropSet
);
2354 OUString
XclImpDialogObj::DoGetServiceName() const
2356 // dialog frame faked by a groupbox
2357 return OUString( "com.sun.star.form.component.GroupBox" );
2360 XclTbxEventType
XclImpDialogObj::DoGetEventType() const
2362 return EXC_TBX_EVENT_MOUSE
;
2365 // ----------------------------------------------------------------------------
2367 XclImpEditObj::XclImpEditObj( const XclImpRoot
& rRoot
) :
2368 XclImpTbxObjBase( rRoot
),
2369 mnContentType( EXC_OBJ_EDIT_TEXT
),
2376 bool XclImpEditObj::IsNumeric() const
2378 return (mnContentType
== EXC_OBJ_EDIT_INTEGER
) || (mnContentType
== EXC_OBJ_EDIT_DOUBLE
);
2381 void XclImpEditObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2383 ReadFrameData( rStrm
);
2385 rStrm
>> maTextData
.maData
.mnFlags
;
2387 ReadName5( rStrm
, nNameLen
);
2388 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2389 rStrm
>> maTextData
.maData
.mnTextLen
;
2390 maTextData
.ReadByteString( rStrm
);
2391 rStrm
>> mnContentType
>> mnMultiLine
>> mnScrollBar
>> mnListBoxObjId
;
2394 void XclImpEditObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2398 case EXC_ID_OBJEDODATA
:
2399 rStrm
>> mnContentType
>> mnMultiLine
>> mnScrollBar
>> mnListBoxObjId
;
2402 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2406 void XclImpEditObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2408 if( maTextData
.mxString
)
2410 OUString aText
= maTextData
.mxString
->GetText();
2413 // TODO: OUString::toDouble() does not handle local decimal separator
2414 rPropSet
.SetProperty( "DefaultValue", aText
.toDouble() );
2415 rPropSet
.SetBoolProperty( "Spin", mnScrollBar
!= 0 );
2419 rPropSet
.SetProperty( "DefaultText", aText
);
2420 rPropSet
.SetBoolProperty( "MultiLine", mnMultiLine
!= 0 );
2421 rPropSet
.SetBoolProperty( "VScroll", mnScrollBar
!= 0 );
2424 ConvertFont( rPropSet
);
2427 OUString
XclImpEditObj::DoGetServiceName() const
2429 return IsNumeric() ?
2430 OUString( "com.sun.star.form.component.NumericField" ) :
2431 OUString( "com.sun.star.form.component.TextField" );
2434 XclTbxEventType
XclImpEditObj::DoGetEventType() const
2436 return EXC_TBX_EVENT_TEXT
;
2439 // ----------------------------------------------------------------------------
2441 XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot
& rRoot
) :
2442 XclImpTbxObjBase( rRoot
),
2454 void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream
& rStrm
)
2457 rStrm
>> mnValue
>> mnMin
>> mnMax
>> mnStep
>> mnPageStep
>> mnOrient
>> mnThumbWidth
>> mnScrollFlags
;
2460 void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2467 case EXC_ID_OBJSBSFMLA
:
2468 ReadCellLinkFormula( rStrm
, false );
2471 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2475 // ----------------------------------------------------------------------------
2477 XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot
& rRoot
) :
2478 XclImpTbxObjScrollableBase( rRoot
)
2482 void XclImpSpinButtonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2484 ReadFrameData( rStrm
);
2486 ReadName5( rStrm
, nNameLen
);
2487 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2488 ReadCellLinkFormula( rStrm
, true );
2491 void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2493 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2494 rPropSet
.SetProperty( "Border", ::com::sun::star::awt::VisualEffect::NONE
);
2495 rPropSet
.SetProperty
< sal_Int32
>( "DefaultSpinValue", mnValue
);
2496 rPropSet
.SetProperty
< sal_Int32
>( "SpinValueMin", mnMin
);
2497 rPropSet
.SetProperty
< sal_Int32
>( "SpinValueMax", mnMax
);
2498 rPropSet
.SetProperty
< sal_Int32
>( "SpinIncrement", mnStep
);
2500 // Excel spin buttons always vertical
2501 rPropSet
.SetProperty( "Orientation", ::com::sun::star::awt::ScrollBarOrientation::VERTICAL
);
2504 OUString
XclImpSpinButtonObj::DoGetServiceName() const
2506 return OUString( "com.sun.star.form.component.SpinButton" );
2509 XclTbxEventType
XclImpSpinButtonObj::DoGetEventType() const
2511 return EXC_TBX_EVENT_VALUE
;
2514 // ----------------------------------------------------------------------------
2516 XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot
& rRoot
) :
2517 XclImpTbxObjScrollableBase( rRoot
)
2521 void XclImpScrollBarObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2523 ReadFrameData( rStrm
);
2525 ReadName5( rStrm
, nNameLen
);
2526 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2527 ReadCellLinkFormula( rStrm
, true );
2530 void XclImpScrollBarObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2532 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2533 rPropSet
.SetProperty( "Border", ::com::sun::star::awt::VisualEffect::NONE
);
2534 rPropSet
.SetProperty
< sal_Int32
>( "DefaultScrollValue", mnValue
);
2535 rPropSet
.SetProperty
< sal_Int32
>( "ScrollValueMin", mnMin
);
2536 rPropSet
.SetProperty
< sal_Int32
>( "ScrollValueMax", mnMax
);
2537 rPropSet
.SetProperty
< sal_Int32
>( "LineIncrement", mnStep
);
2538 rPropSet
.SetProperty
< sal_Int32
>( "BlockIncrement", mnPageStep
);
2539 rPropSet
.SetProperty( "VisibleSize", ::std::min
< sal_Int32
>( mnPageStep
, 1 ) );
2541 namespace AwtScrollOrient
= ::com::sun::star::awt::ScrollBarOrientation
;
2542 sal_Int32 nApiOrient
= ::get_flagvalue( mnOrient
, EXC_OBJ_SCROLLBAR_HOR
, AwtScrollOrient::HORIZONTAL
, AwtScrollOrient::VERTICAL
);
2543 rPropSet
.SetProperty( "Orientation", nApiOrient
);
2546 OUString
XclImpScrollBarObj::DoGetServiceName() const
2548 return OUString( "com.sun.star.form.component.ScrollBar" );
2551 XclTbxEventType
XclImpScrollBarObj::DoGetEventType() const
2553 return EXC_TBX_EVENT_VALUE
;
2556 // ----------------------------------------------------------------------------
2558 XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot
& rRoot
) :
2559 XclImpTbxObjScrollableBase( rRoot
),
2564 mbHasDefFontIdx( false )
2568 void XclImpTbxObjListBase::ReadLbsData( XclImpStream
& rStrm
)
2570 ReadSourceRangeFormula( rStrm
, true );
2571 rStrm
>> mnEntryCount
>> mnSelEntry
>> mnListFlags
>> mnEditObjId
;
2574 void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet
& rPropSet
) const
2577 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
2578 sal_Int16 nApiBorder
= ::get_flagvalue( mnListFlags
, EXC_OBJ_LISTBOX_FLAT
, AwtVisualEffect::FLAT
, AwtVisualEffect::LOOK3D
);
2579 rPropSet
.SetProperty( "Border", nApiBorder
);
2582 if( mbHasDefFontIdx
)
2583 GetFontBuffer().WriteFontProperties( rPropSet
, EXC_FONTPROPSET_CONTROL
, maTextData
.maData
.mnDefFontIdx
);
2585 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet
);
2588 // ----------------------------------------------------------------------------
2590 XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot
& rRoot
) :
2591 XclImpTbxObjListBase( rRoot
)
2595 void XclImpListBoxObj::ReadFullLbsData( XclImpStream
& rStrm
, sal_Size nRecLeft
)
2597 sal_Size nRecEnd
= rStrm
.GetRecPos() + nRecLeft
;
2598 ReadLbsData( rStrm
);
2599 OSL_ENSURE( (rStrm
.GetRecPos() == nRecEnd
) || (rStrm
.GetRecPos() + mnEntryCount
== nRecEnd
),
2600 "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
2601 while( rStrm
.IsValid() && (rStrm
.GetRecPos() < nRecEnd
) )
2602 maSelection
.push_back( rStrm
.ReaduInt8() );
2605 void XclImpListBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2607 ReadFrameData( rStrm
);
2610 rStrm
>> maTextData
.maData
.mnDefFontIdx
;
2612 ReadName5( rStrm
, nNameLen
);
2613 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2614 ReadCellLinkFormula( rStrm
, true );
2615 ReadFullLbsData( rStrm
, rStrm
.GetRecLeft() );
2616 mbHasDefFontIdx
= true;
2619 void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2623 case EXC_ID_OBJLBSDATA
:
2624 ReadFullLbsData( rStrm
, nSubRecSize
);
2627 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2631 void XclImpListBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2633 // listbox formatting
2634 SetBoxFormatting( rPropSet
);
2637 sal_uInt8 nSelType
= ::extract_value
< sal_uInt8
>( mnListFlags
, 4, 2 );
2638 bool bMultiSel
= nSelType
!= EXC_OBJ_LISTBOX_SINGLE
;
2639 rPropSet
.SetBoolProperty( "MultiSelection", bMultiSel
);
2641 // selection (do not set, if listbox is linked to a cell)
2642 if( !HasCellLink() )
2644 ScfInt16Vec aSelVec
;
2646 // multi selection: API expects sequence of list entry indexes
2649 for( ScfUInt8Vec::const_iterator aBeg
= maSelection
.begin(), aIt
= aBeg
, aEnd
= maSelection
.end(); aIt
!= aEnd
; ++aIt
)
2651 aSelVec
.push_back( static_cast< sal_Int16
>( aIt
- aBeg
) );
2653 // single selection: mnSelEntry is one-based, API expects zero-based
2654 else if( mnSelEntry
> 0 )
2655 aSelVec
.push_back( static_cast< sal_Int16
>( mnSelEntry
- 1 ) );
2657 if( !aSelVec
.empty() )
2659 Sequence
< sal_Int16
> aSelSeq( &aSelVec
.front(), static_cast< sal_Int32
>( aSelVec
.size() ) );
2660 rPropSet
.SetProperty( "DefaultSelection", aSelSeq
);
2665 OUString
XclImpListBoxObj::DoGetServiceName() const
2667 return OUString( "com.sun.star.form.component.ListBox" );
2670 XclTbxEventType
XclImpListBoxObj::DoGetEventType() const
2672 return EXC_TBX_EVENT_CHANGE
;
2675 // ----------------------------------------------------------------------------
2677 XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot
& rRoot
) :
2678 XclImpTbxObjListBase( rRoot
),
2683 mnDropDownFlags( 0 ),
2689 sal_uInt16
XclImpDropDownObj::GetDropDownType() const
2691 return ::extract_value
< sal_uInt8
>( mnDropDownFlags
, 0, 2 );
2694 void XclImpDropDownObj::ReadFullLbsData( XclImpStream
& rStrm
)
2696 ReadLbsData( rStrm
);
2697 rStrm
>> mnDropDownFlags
>> mnLineCount
>> mnMinWidth
>> maTextData
.maData
.mnTextLen
;
2698 maTextData
.ReadByteString( rStrm
);
2699 // dropdowns of auto-filters have 'simple' style, they don't have a text area
2700 if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE
)
2701 SetProcessSdrObj( false );
2704 void XclImpDropDownObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2706 ReadFrameData( rStrm
);
2709 rStrm
>> maTextData
.maData
.mnDefFontIdx
;
2711 rStrm
>> mnLeft
>> mnTop
>> mnRight
>> mnBottom
;
2713 ReadName5( rStrm
, nNameLen
);
2714 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // fist macro size invalid and unused
2715 ReadCellLinkFormula( rStrm
, true );
2716 ReadFullLbsData( rStrm
);
2717 mbHasDefFontIdx
= true;
2720 void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2724 case EXC_ID_OBJLBSDATA
:
2725 ReadFullLbsData( rStrm
);
2728 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2732 void XclImpDropDownObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2734 // dropdown listbox formatting
2735 SetBoxFormatting( rPropSet
);
2736 // enable dropdown button
2737 rPropSet
.SetBoolProperty( "Dropdown", true );
2738 // dropdown line count
2739 rPropSet
.SetProperty( "LineCount", mnLineCount
);
2741 if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
)
2743 // text of editable combobox
2744 if( maTextData
.mxString
)
2745 rPropSet
.SetStringProperty( "DefaultText", maTextData
.mxString
->GetText() );
2749 // selection (do not set, if dropdown is linked to a cell)
2750 if( !HasCellLink() && (mnSelEntry
> 0) )
2752 Sequence
< sal_Int16
> aSelSeq( 1 );
2753 aSelSeq
[ 0 ] = mnSelEntry
- 1;
2754 rPropSet
.SetProperty( "DefaultSelection", aSelSeq
);
2759 OUString
XclImpDropDownObj::DoGetServiceName() const
2761 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
) ?
2762 OUString( "com.sun.star.form.component.ComboBox" ) :
2763 OUString( "com.sun.star.form.component.ListBox" );
2766 XclTbxEventType
XclImpDropDownObj::DoGetEventType() const
2768 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
) ? EXC_TBX_EVENT_TEXT
: EXC_TBX_EVENT_CHANGE
;
2771 // ----------------------------------------------------------------------------
2773 XclImpPictureObj::XclImpPictureObj( const XclImpRoot
& rRoot
) :
2774 XclImpRectObj( rRoot
),
2775 XclImpControlHelper( rRoot
, EXC_CTRL_BINDCONTENT
),
2778 mnCtlsStrmSize( 0 ),
2779 mbEmbedded( false ),
2783 mbUseCtlsStrm( false )
2786 SetSimpleMacro( false );
2787 SetCustomDffObj( true );
2790 String
XclImpPictureObj::GetOleStorageName() const
2793 if( (mbEmbedded
|| mbLinked
) && !mbControl
&& (mnStorageId
> 0) )
2795 aStrgName
= mbEmbedded
? EXC_STORAGE_OLE_EMBEDDED
: EXC_STORAGE_OLE_LINKED
;
2796 static const sal_Char spcHexChars
[] = "0123456789ABCDEF";
2797 for( sal_uInt8 nIndex
= 32; nIndex
> 0; nIndex
-= 4 )
2798 aStrgName
.Append( sal_Unicode( spcHexChars
[ ::extract_value
< sal_uInt8
>( mnStorageId
, nIndex
- 4, 4 ) ] ) );
2803 void XclImpPictureObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
2805 sal_uInt16 nLinkSize
;
2806 ReadFrameData( rStrm
);
2810 ReadFlags3( rStrm
);
2811 ReadMacro3( rStrm
, nMacroSize
);
2812 ReadPictFmla( rStrm
, nLinkSize
);
2814 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2815 maGraphic
= XclImpDrawing::ReadImgData( GetRoot(), rStrm
);
2818 void XclImpPictureObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
2820 sal_uInt16 nLinkSize
;
2821 ReadFrameData( rStrm
);
2825 ReadFlags3( rStrm
);
2826 ReadMacro4( rStrm
, nMacroSize
);
2827 ReadPictFmla( rStrm
, nLinkSize
);
2829 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2830 maGraphic
= XclImpDrawing::ReadImgData( GetRoot(), rStrm
);
2833 void XclImpPictureObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
2835 sal_uInt16 nLinkSize
;
2836 ReadFrameData( rStrm
);
2840 ReadFlags3( rStrm
);
2842 ReadName5( rStrm
, nNameLen
);
2843 ReadMacro5( rStrm
, nMacroSize
);
2844 ReadPictFmla( rStrm
, nLinkSize
);
2846 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2848 // page background is stored as hidden picture with name "__BkgndObj"
2849 if ( IsHidden() && (GetObjName() == "__BkgndObj") )
2850 GetPageSettings().ReadImgData( rStrm
);
2852 maGraphic
= XclImpDrawing::ReadImgData( GetRoot(), rStrm
);
2856 void XclImpPictureObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2860 case EXC_ID_OBJFLAGS
:
2861 ReadFlags8( rStrm
);
2863 case EXC_ID_OBJPICTFMLA
:
2864 ReadPictFmla( rStrm
, rStrm
.ReaduInt16() );
2867 XclImpDrawObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2871 SdrObject
* XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const Rectangle
& rAnchorRect
) const
2873 // try to create an OLE object or form control
2874 SdrObjectPtr
xSdrObj( rDffConv
.CreateSdrObject( *this, rAnchorRect
) );
2876 // insert a graphic replacement for unsupported ole object ( if none already
2877 // exists ) Hmm ok, it's possibly that there has been some imported
2878 // graphic at a base level but unlikely, normally controls have a valid
2879 // preview in the IMGDATA record ( see below )
2880 // It might be possible to push such an imported graphic up to this
2881 // XclImpPictureObj instance but there are somany layers of indirection I
2882 // don't see an easy way. This way at least ensures that we can
2883 // avoid a 'blank' shape that can result from a failed control import
2884 if ( !xSdrObj
&& IsOcxControl() && maGraphic
.GetType() == GRAPHIC_NONE
)
2886 Graphic
aReplacement( SdrOle2Obj::GetEmtyOLEReplacementBitmap() );
2887 const_cast< XclImpPictureObj
* >( this )->maGraphic
= aReplacement
;
2889 // no OLE - create a plain picture from IMGDATA record data
2890 if( !xSdrObj
&& (maGraphic
.GetType() != GRAPHIC_NONE
) )
2892 xSdrObj
.reset( new SdrGrafObj( maGraphic
, rAnchorRect
) );
2893 ConvertRectStyle( *xSdrObj
);
2896 rDffConv
.Progress();
2897 return xSdrObj
.release();
2900 OUString
XclImpPictureObj::GetObjName() const
2902 if( IsOcxControl() )
2904 OUString
sName( GetObjectManager().GetOleNameOverride( GetTab(), GetObjId() ) );
2905 if (!sName
.isEmpty())
2908 return XclImpDrawObjBase::GetObjName();
2911 void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
2913 if( IsOcxControl() )
2915 // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature
2916 ProcessControl( *this );
2918 else if( mbEmbedded
|| mbLinked
)
2920 // trace missing "printable" feature
2921 XclImpRectObj::DoPreProcessSdrObj( rDffConv
, rSdrObj
);
2923 SfxObjectShell
* pDocShell
= GetDocShell();
2924 SdrOle2Obj
* pOleSdrObj
= dynamic_cast< SdrOle2Obj
* >( &rSdrObj
);
2925 if( pOleSdrObj
&& pDocShell
)
2927 comphelper::EmbeddedObjectContainer
& rEmbObjCont
= pDocShell
->GetEmbeddedObjectContainer();
2928 Reference
< XEmbeddedObject
> xEmbObj
= pOleSdrObj
->GetObjRef();
2929 OUString
aOldName( pOleSdrObj
->GetPersistName() );
2931 /* The object persistence should be already in the storage, but
2932 the object still might not be inserted into the container. */
2933 if( rEmbObjCont
.HasEmbeddedObject( aOldName
) )
2935 if( !rEmbObjCont
.HasEmbeddedObject( xEmbObj
) )
2936 // filter code is allowed to call the following method
2937 rEmbObjCont
.AddEmbeddedObject( xEmbObj
, aOldName
);
2941 /* If the object is still not in container it must be inserted
2942 there, the name must be generated in this case. */
2944 rEmbObjCont
.InsertEmbeddedObject( xEmbObj
, aNewName
);
2945 if( aOldName
!= aNewName
)
2946 // SetPersistName, not SetName
2947 pOleSdrObj
->SetPersistName( aNewName
);
2953 void XclImpPictureObj::ReadFlags3( XclImpStream
& rStrm
)
2957 mbSymbol
= ::get_flag( nFlags
, EXC_OBJ_PIC_SYMBOL
);
2960 void XclImpPictureObj::ReadFlags8( XclImpStream
& rStrm
)
2964 mbSymbol
= ::get_flag( nFlags
, EXC_OBJ_PIC_SYMBOL
);
2965 mbControl
= ::get_flag( nFlags
, EXC_OBJ_PIC_CONTROL
);
2966 mbUseCtlsStrm
= ::get_flag( nFlags
, EXC_OBJ_PIC_CTLSSTREAM
);
2967 OSL_ENSURE( mbControl
|| !mbUseCtlsStrm
, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
2968 SetProcessSdrObj( mbControl
|| !mbUseCtlsStrm
);
2971 void XclImpPictureObj::ReadPictFmla( XclImpStream
& rStrm
, sal_uInt16 nLinkSize
)
2973 sal_Size nLinkEnd
= rStrm
.GetRecPos() + nLinkSize
;
2974 if( nLinkSize
>= 6 )
2976 sal_uInt16 nFmlaSize
;
2978 OSL_ENSURE( nFmlaSize
> 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
2979 // BIFF3/BIFF4 do not support storages, nothing to do here
2980 if( (nFmlaSize
> 0) && (GetBiff() >= EXC_BIFF5
) )
2986 // different processing for linked vs. embedded OLE objects
2987 if( nToken
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
) )
2995 sal_uInt16 nNameIdx
;
3000 const ExtName
* pExtName
= GetOldRoot().pExtNameBuff
->GetNameByIndex( nRefIdx
, nNameIdx
);
3001 if( pExtName
&& pExtName
->IsOLE() )
3002 mnStorageId
= pExtName
->nStorageId
;
3007 sal_uInt16 nXti
, nExtName
;
3008 rStrm
>> nXti
>> nExtName
;
3009 const XclImpExtName
* pExtName
= GetLinkManager().GetExternName( nXti
, nExtName
);
3010 if( pExtName
&& (pExtName
->GetType() == xlExtOLE
) )
3011 mnStorageId
= pExtName
->GetStorageId();
3018 else if( nToken
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL
, EXC_TOKCLASS_NONE
) )
3021 OSL_ENSURE( nFmlaSize
== 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
3022 rStrm
.Ignore( nFmlaSize
- 1 ); // token ID already read
3024 rStrm
.Ignore( 1 ); // padding byte
3026 // a class name may follow inside the picture link
3027 if( rStrm
.GetRecPos() + 2 <= nLinkEnd
)
3032 maClassName
= (GetBiff() == EXC_BIFF8
) ? rStrm
.ReadUniString( nLen
) : rStrm
.ReadRawByteString( nLen
);
3035 // else: ignore other formulas, e.g. pictures linked to cell ranges
3039 // seek behind picture link data
3040 rStrm
.Seek( nLinkEnd
);
3042 // read additional data for embedded OLE objects following the picture link
3043 if( IsOcxControl() )
3045 // #i26521# form controls to be ignored
3046 if( maClassName
.EqualsAscii( "Forms.HTML:Hidden.1" ) )
3048 SetProcessSdrObj( false );
3052 if( rStrm
.GetRecLeft() <= 8 ) return;
3054 // position and size of control data in 'Ctls' stream
3055 mnCtlsStrmPos
= static_cast< sal_Size
>( rStrm
.ReaduInt32() );
3056 mnCtlsStrmSize
= static_cast< sal_Size
>( rStrm
.ReaduInt32() );
3058 if( rStrm
.GetRecLeft() <= 8 ) return;
3060 // additional string (16-bit characters), e.g. for progress bar control
3061 sal_uInt32 nAddStrSize
;
3062 rStrm
>> nAddStrSize
;
3063 OSL_ENSURE( rStrm
.GetRecLeft() >= nAddStrSize
+ 4, "XclImpPictureObj::ReadPictFmla - missing data" );
3064 if( rStrm
.GetRecLeft() >= nAddStrSize
+ 4 )
3066 rStrm
.Ignore( nAddStrSize
);
3067 // cell link and source range
3068 ReadCellLinkFormula( rStrm
, true );
3069 ReadSourceRangeFormula( rStrm
, true );
3072 else if( mbEmbedded
&& (rStrm
.GetRecLeft() >= 4) )
3074 rStrm
>> mnStorageId
;
3078 // DFF stream conversion ======================================================
3080 void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject
& rSdrObj
, sal_uInt32 nDffShapeId
, sal_uInt32 nDffFlags
)
3082 if( nDffShapeId
> 0 )
3084 maSdrInfoMap
[ nDffShapeId
].Set( &rSdrObj
, nDffFlags
);
3085 maSdrObjMap
[ &rSdrObj
] = nDffShapeId
;
3089 void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject
& rSdrObj
)
3091 // remove info of passed object from the maps
3092 XclImpSdrObjMap::iterator aIt
= maSdrObjMap
.find( &rSdrObj
);
3093 if( aIt
!= maSdrObjMap
.end() )
3095 maSdrInfoMap
.erase( aIt
->second
);
3096 maSdrObjMap
.erase( aIt
);
3099 // remove info of all child objects of a group object
3100 if( SdrObjGroup
* pGroupObj
= dynamic_cast< SdrObjGroup
* >( &rSdrObj
) )
3102 if( SdrObjList
* pSubList
= pGroupObj
->GetSubList() )
3104 // iterate flat over the list because this function already works recursively
3105 SdrObjListIter
aObjIt( *pSubList
, IM_FLAT
);
3106 for( SdrObject
* pChildObj
= aObjIt
.Next(); pChildObj
; pChildObj
= aObjIt
.Next() )
3107 RemoveSdrObjectInfo( *pChildObj
);
3112 void XclImpSolverContainer::UpdateConnectorRules()
3114 for ( size_t i
= 0, n
= aCList
.size(); i
< n
; ++i
)
3116 SvxMSDffConnectorRule
* pRule
= aCList
[ i
];
3117 UpdateConnection( pRule
->nShapeA
, pRule
->pAObj
, &pRule
->nSpFlagsA
);
3118 UpdateConnection( pRule
->nShapeB
, pRule
->pBObj
, &pRule
->nSpFlagsB
);
3119 UpdateConnection( pRule
->nShapeC
, pRule
->pCObj
);
3123 void XclImpSolverContainer::RemoveConnectorRules()
3125 // base class from SVX uses plain untyped tools/List
3126 for ( size_t i
= 0, n
= aCList
.size(); i
< n
; ++i
) {
3130 maSdrInfoMap
.clear();
3131 maSdrObjMap
.clear();
3134 void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId
, SdrObject
*& rpSdrObj
, sal_uInt32
* pnDffFlags
)
3136 XclImpSdrInfoMap::const_iterator aIt
= maSdrInfoMap
.find( nDffShapeId
);
3137 if( aIt
!= maSdrInfoMap
.end() )
3139 rpSdrObj
= aIt
->second
.mpSdrObj
;
3141 *pnDffFlags
= aIt
->second
.mnDffFlags
;
3145 // ----------------------------------------------------------------------------
3147 XclImpSimpleDffConverter::XclImpSimpleDffConverter( const XclImpRoot
& rRoot
, SvStream
& rDffStrm
) :
3148 SvxMSDffManager( rDffStrm
, rRoot
.GetBasePath(), 0, 0, rRoot
.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT
, 24, 0 ),
3151 SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS
| SVXMSDFF_SETTINGS_IMPORT_EXCEL
);
3154 XclImpSimpleDffConverter::~XclImpSimpleDffConverter()
3158 bool XclImpSimpleDffConverter::GetColorFromPalette( sal_uInt16 nIndex
, Color
& rColor
) const
3160 ColorData nColor
= GetPalette().GetColorData( static_cast< sal_uInt16
>( nIndex
) );
3162 if( nColor
== COL_AUTO
)
3165 rColor
.SetColor( nColor
);
3169 XclImpDffConverter::XclImpDffConvData::XclImpDffConvData(
3170 XclImpDrawing
& rDrawing
, SdrModel
& rSdrModel
, SdrPage
& rSdrPage
) :
3171 mrDrawing( rDrawing
),
3172 mrSdrModel( rSdrModel
),
3173 mrSdrPage( rSdrPage
),
3174 mnLastCtrlIndex( -1 ),
3175 mbHasCtrlForm( false )
3178 // ----------------------------------------------------------------------------
3180 XclImpDffConverter::XclImpDffConverter( const XclImpRoot
& rRoot
, SvStream
& rDffStrm
) :
3181 XclImpSimpleDffConverter( rRoot
, rDffStrm
),
3182 oox::ole::MSConvertOCXControls( rRoot
.GetDocShell()->GetModel() ),
3183 maStdFormName( "Standard" ),
3186 const SvtFilterOptions
& rFilterOpt
= SvtFilterOptions::Get();
3187 if( rFilterOpt
.IsMathType2Math() )
3188 mnOleImpFlags
|= OLE_MATHTYPE_2_STARMATH
;
3189 if( rFilterOpt
.IsWinWord2Writer() )
3190 mnOleImpFlags
|= OLE_WINWORD_2_STARWRITER
;
3191 if( rFilterOpt
.IsPowerPoint2Impress() )
3192 mnOleImpFlags
|= OLE_POWERPOINT_2_STARIMPRESS
;
3194 // try to open the 'Ctls' storage stream containing OCX control properties
3195 mxCtlsStrm
= OpenStream( EXC_STREAM_CTLS
);
3197 // default text margin (convert EMU to drawing layer units)
3198 mnDefTextMargin
= EXC_OBJ_TEXT_MARGIN
;
3199 ScaleEmu( mnDefTextMargin
);
3202 XclImpDffConverter::~XclImpDffConverter()
3206 String
XclImpObjectManager::GetOleNameOverride( SCTAB nTab
, sal_uInt16 nObjId
)
3209 String sCodeName
= GetExtDocOptions().GetCodeName( nTab
);
3211 if (mxOleCtrlNameOverride
.is() && mxOleCtrlNameOverride
->hasByName(sCodeName
))
3213 Reference
< XIndexContainer
> xIdToOleName
;
3214 mxOleCtrlNameOverride
->getByName( sCodeName
) >>= xIdToOleName
;
3215 xIdToOleName
->getByIndex( nObjId
) >>= sOleName
;
3217 OSL_TRACE("XclImpObjectManager::GetOleNameOverride tab %d, ( module %s ) object id ( %d ) is %s", nTab
,
3218 OUStringToOString( sCodeName
, RTL_TEXTENCODING_UTF8
).getStr(), nObjId
,
3219 OUStringToOString( sOleName
, RTL_TEXTENCODING_UTF8
).getStr() );
3224 void XclImpDffConverter::StartProgressBar( sal_Size nProgressSize
)
3226 mxProgress
.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING
) );
3227 mxProgress
->AddSegment( nProgressSize
);
3228 mxProgress
->Activate();
3231 void XclImpDffConverter::Progress( sal_Size nDelta
)
3233 OSL_ENSURE( mxProgress
, "XclImpDffConverter::Progress - invalid call, no progress bar" );
3234 mxProgress
->Progress( nDelta
);
3237 void XclImpDffConverter::InitializeDrawing( XclImpDrawing
& rDrawing
, SdrModel
& rSdrModel
, SdrPage
& rSdrPage
)
3239 XclImpDffConvDataRef
xConvData( new XclImpDffConvData( rDrawing
, rSdrModel
, rSdrPage
) );
3240 maDataStack
.push_back( xConvData
);
3241 SetModel( &xConvData
->mrSdrModel
, 1440 );
3244 void XclImpDffConverter::ProcessObject( SdrObjList
& rObjList
, const XclImpDrawObjBase
& rDrawObj
)
3246 if( rDrawObj
.IsProcessSdrObj() )
3248 if( const XclObjAnchor
* pAnchor
= rDrawObj
.GetAnchor() )
3250 Rectangle aAnchorRect
= GetConvData().mrDrawing
.CalcAnchorRect( *pAnchor
, false );
3251 if( rDrawObj
.IsValidSize( aAnchorRect
) )
3253 // CreateSdrObject() recursively creates embedded child objects
3254 SdrObjectPtr
xSdrObj( rDrawObj
.CreateSdrObject( *this, aAnchorRect
, false ) );
3256 rDrawObj
.PreProcessSdrObject( *this, *xSdrObj
);
3257 // call InsertSdrObject() also, if SdrObject is missing
3258 InsertSdrObject( rObjList
, rDrawObj
, xSdrObj
.release() );
3264 void XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector
& rDrawObjs
)
3266 SdrPage
& rSdrPage
= GetConvData().mrSdrPage
;
3267 for( XclImpDrawObjVector::const_iterator aIt
= rDrawObjs
.begin(), aEnd
= rDrawObjs
.end(); aIt
!= aEnd
; ++aIt
)
3268 ProcessObject( rSdrPage
, **aIt
);
3271 void XclImpDffConverter::ProcessDrawing( SvStream
& rDffStrm
)
3273 rDffStrm
.Seek( STREAM_SEEK_TO_END
);
3274 if( rDffStrm
.Tell() > 0 )
3276 rDffStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
3277 DffRecordHeader aHeader
;
3278 rDffStrm
>> aHeader
;
3279 OSL_ENSURE( aHeader
.nRecType
== DFF_msofbtDgContainer
, "XclImpDffConverter::ProcessDrawing - unexpected record" );
3280 if( aHeader
.nRecType
== DFF_msofbtDgContainer
)
3281 ProcessDgContainer( rDffStrm
, aHeader
);
3285 void XclImpDffConverter::FinalizeDrawing()
3287 OSL_ENSURE( !maDataStack
.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" );
3288 maDataStack
.pop_back();
3289 // restore previous model at core DFF converter
3290 if( !maDataStack
.empty() )
3291 SetModel( &maDataStack
.back()->mrSdrModel
, 1440 );
3294 SdrObject
* XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase
& rTbxObj
, const Rectangle
& rAnchorRect
)
3296 SdrObjectPtr xSdrObj
;
3298 OUString aServiceName
= rTbxObj
.GetServiceName();
3299 if( SupportsOleObjects() && !aServiceName
.isEmpty() ) try
3301 // create the form control from scratch
3302 Reference
< XFormComponent
> xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName
), UNO_QUERY_THROW
);
3303 // set controls form, needed in virtual function InsertControl()
3305 // try to insert the control into the form
3306 ::com::sun::star::awt::Size aDummySize
;
3307 Reference
< XShape
> xShape
;
3308 XclImpDffConvData
& rConvData
= GetConvData();
3309 if( rConvData
.mxCtrlForm
.is() && InsertControl( xFormComp
, aDummySize
, &xShape
, sal_True
) )
3311 xSdrObj
.reset( rTbxObj
.CreateSdrObjectFromShape( xShape
, rAnchorRect
) );
3312 // try to attach a macro to the control
3313 ScriptEventDescriptor aDescriptor
;
3314 if( (rConvData
.mnLastCtrlIndex
>= 0) && rTbxObj
.FillMacroDescriptor( aDescriptor
) )
3316 Reference
< XEventAttacherManager
> xEventMgr( rConvData
.mxCtrlForm
, UNO_QUERY_THROW
);
3317 xEventMgr
->registerScriptEvent( rConvData
.mnLastCtrlIndex
, aDescriptor
);
3321 catch( const Exception
& )
3325 return xSdrObj
.release();
3328 SdrObject
* XclImpDffConverter::CreateSdrObject( const XclImpPictureObj
& rPicObj
, const Rectangle
& rAnchorRect
)
3330 SdrObjectPtr xSdrObj
;
3332 if( SupportsOleObjects() )
3334 if( rPicObj
.IsOcxControl() )
3336 if( mxCtlsStrm
.Is() ) try
3338 /* set controls form, needed in virtual function InsertControl()
3339 called from ReadOCXExcelKludgeStream() */
3342 // read from mxCtlsStrm into xShape, insert the control model into the form
3343 Reference
< XShape
> xShape
;
3344 if( GetConvData().mxCtrlForm
.is() )
3346 Reference
< XFormComponent
> xFComp
;
3347 com::sun::star::awt::Size aSz
; // not used in import
3348 ReadOCXCtlsStream( mxCtlsStrm
, xFComp
, rPicObj
.GetCtlsStreamPos(), rPicObj
.GetCtlsStreamSize() );
3349 // recreate the method formally known as
3350 // ReadOCXExcelKludgeStream( )
3353 ScfPropertySet
aPropSet( xFComp
);
3354 aPropSet
.SetStringProperty( "Name", rPicObj
.GetObjName() );
3355 InsertControl( xFComp
, aSz
,&xShape
,true);
3356 xSdrObj
.reset( rPicObj
.CreateSdrObjectFromShape( xShape
, rAnchorRect
) );
3360 catch( const Exception
& )
3366 SfxObjectShell
* pDocShell
= GetDocShell();
3367 SotStorageRef xSrcStrg
= GetRootStorage();
3368 String aStrgName
= rPicObj
.GetOleStorageName();
3369 if( pDocShell
&& xSrcStrg
.Is() && (aStrgName
.Len() > 0) )
3371 // first try to resolve graphic from DFF storage
3374 if( !GetBLIP( GetPropertyValue( DFF_Prop_pib
), aGraphic
, &aVisArea
) )
3376 // if not found, use graphic from object (imported from IMGDATA record)
3377 aGraphic
= rPicObj
.GetGraphic();
3378 aVisArea
= rPicObj
.GetVisArea();
3380 if( aGraphic
.GetType() != GRAPHIC_NONE
)
3382 ErrCode nError
= ERRCODE_NONE
;
3383 namespace cssea
= ::com::sun::star::embed::Aspects
;
3384 sal_Int64 nAspects
= rPicObj
.IsSymbol() ? cssea::MSOLE_ICON
: cssea::MSOLE_CONTENT
;
3385 xSdrObj
.reset( CreateSdrOLEFromStorage(
3386 aStrgName
, xSrcStrg
, pDocShell
->GetStorage(), aGraphic
,
3387 rAnchorRect
, aVisArea
, 0, nError
, mnOleImpFlags
, nAspects
) );
3393 return xSdrObj
.release();
3396 bool XclImpDffConverter::SupportsOleObjects() const
3398 return GetConvData().mrDrawing
.SupportsOleObjects();
3401 // virtual functions ----------------------------------------------------------
3403 void XclImpDffConverter::ProcessClientAnchor2( SvStream
& rDffStrm
,
3404 DffRecordHeader
& rHeader
, void* /*pClientData*/, DffObjData
& rObjData
)
3406 // find the OBJ record data related to the processed shape
3407 XclImpDffConvData
& rConvData
= GetConvData();
3408 if( XclImpDrawObjBase
* pDrawObj
= rConvData
.mrDrawing
.FindDrawObj( rObjData
.rSpHd
).get() )
3410 OSL_ENSURE( rHeader
.nRecType
== DFF_msofbtClientAnchor
, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" );
3411 XclObjAnchor aAnchor
;
3412 rHeader
.SeekToContent( rDffStrm
);
3413 sal_uInt8
nFlags(0);
3415 rDffStrm
.SeekRel( 1 ); // flags
3416 rDffStrm
>> aAnchor
; // anchor format equal to BIFF5 OBJ records
3418 pDrawObj
->SetAnchor( aAnchor
);
3419 rObjData
.aChildAnchor
= rConvData
.mrDrawing
.CalcAnchorRect( aAnchor
, true );
3420 rObjData
.bChildAnchor
= sal_True
;
3421 // page anchoring is the best approximation we have if mbMove
3423 rObjData
.bPageAnchor
= ( nFlags
& 0x1 );
3427 SdrObject
* XclImpDffConverter::ProcessObj( SvStream
& rDffStrm
, DffObjData
& rDffObjData
,
3428 void* pClientData
, Rectangle
& /*rTextRect*/, SdrObject
* pOldSdrObj
)
3430 XclImpDffConvData
& rConvData
= GetConvData();
3432 /* pOldSdrObj passes a generated SdrObject. This function owns this object
3433 and can modify it. The function has either to return it back to caller
3434 or to delete it by itself. */
3435 SdrObjectPtr
xSdrObj( pOldSdrObj
);
3437 // find the OBJ record data related to the processed shape
3438 XclImpDrawObjRef xDrawObj
= rConvData
.mrDrawing
.FindDrawObj( rDffObjData
.rSpHd
);
3439 const Rectangle
& rAnchorRect
= rDffObjData
.aChildAnchor
;
3441 // Do not process the global page group shape (flag SP_FPATRIARCH)
3442 bool bGlobalPageGroup
= ::get_flag
< sal_uInt32
>( rDffObjData
.nSpFlags
, SP_FPATRIARCH
);
3443 if( !xDrawObj
|| !xDrawObj
->IsProcessSdrObj() || bGlobalPageGroup
)
3444 return 0; // simply return, xSdrObj will be destroyed
3446 /* Pass pointer to top-level object back to caller. If the processed
3447 object is embedded in a group, the pointer is already set to the
3448 top-level parent object. */
3449 XclImpDrawObjBase
** ppTopLevelObj
= reinterpret_cast< XclImpDrawObjBase
** >( pClientData
);
3450 bool bIsTopLevel
= !ppTopLevelObj
|| !*ppTopLevelObj
;
3451 if( ppTopLevelObj
&& bIsTopLevel
)
3452 *ppTopLevelObj
= xDrawObj
.get();
3454 // connectors don't have to be area objects
3455 if( dynamic_cast< SdrEdgeObj
* >( xSdrObj
.get() ) )
3456 xDrawObj
->SetAreaObj( false );
3458 /* Check for valid size for all objects. Needed to ignore lots of invisible
3459 phantom objects from deleted rows or columns (for performance reasons).
3460 #i30816# Include objects embedded in groups.
3461 #i58780# Ignore group shapes, size is not initialized. */
3462 bool bEmbeddedGroup
= !bIsTopLevel
&& dynamic_cast< SdrObjGroup
* >( xSdrObj
.get() );
3463 if( !bEmbeddedGroup
&& !xDrawObj
->IsValidSize( rAnchorRect
) )
3464 return 0; // simply return, xSdrObj will be destroyed
3466 // set shape information from DFF stream
3467 String aObjName
= GetPropertyString( DFF_Prop_wzName
, rDffStrm
);
3468 String aHyperlink
= ReadHlinkProperty( rDffStrm
);
3469 bool bVisible
= !GetPropertyBool( DFF_Prop_fHidden
);
3470 bool bAutoMargin
= GetPropertyBool( DFF_Prop_AutoTextMargin
);
3471 xDrawObj
->SetDffData( rDffObjData
, aObjName
, aHyperlink
, bVisible
, bAutoMargin
);
3473 /* Connect textbox data (string, alignment, text orientation) to object.
3474 don't ask for a text-ID, DFF export doesn't set one. */
3475 if( XclImpTextObj
* pTextObj
= dynamic_cast< XclImpTextObj
* >( xDrawObj
.get() ) )
3476 if( const XclImpObjTextData
* pTextData
= rConvData
.mrDrawing
.FindTextData( rDffObjData
.rSpHd
) )
3477 pTextObj
->SetTextData( *pTextData
);
3479 // copy line and fill formatting of TBX form controls from DFF properties
3480 if( XclImpTbxObjBase
* pTbxObj
= dynamic_cast< XclImpTbxObjBase
* >( xDrawObj
.get() ) )
3481 pTbxObj
->SetDffProperties( *this );
3483 // try to create a custom SdrObject that overwrites the passed object
3484 SdrObjectPtr
xNewSdrObj( xDrawObj
->CreateSdrObject( *this, rAnchorRect
, true ) );
3485 if( xNewSdrObj
.is() )
3486 xSdrObj
.reset( xNewSdrObj
.release() );
3488 // process the SdrObject
3492 if ( !rDffObjData
.bPageAnchor
)
3493 ScDrawLayer::SetCellAnchoredFromPosition( *xSdrObj
, GetDoc(), xDrawObj
->GetTab() );
3495 // filled without color -> set system window color
3496 if( GetPropertyBool( DFF_Prop_fFilled
) && !IsProperty( DFF_Prop_fillColor
) )
3497 xSdrObj
->SetMergedItem( XFillColorItem( EMPTY_STRING
, GetPalette().GetColor( EXC_COLOR_WINDOWBACK
) ) );
3499 // additional processing on the SdrObject
3500 xDrawObj
->PreProcessSdrObject( *this, *xSdrObj
);
3502 /* If the SdrObject will not be inserted into the draw page, delete it
3503 here. Happens e.g. for notes: The PreProcessSdrObject() call above
3504 has inserted the note into the document, and the SdrObject is not
3506 if( !xDrawObj
->IsInsertSdrObj() )
3512 /* Store the relation between shape ID and SdrObject for connectors.
3513 Must be done here (and not in InsertSdrObject() function),
3514 otherwise all SdrObjects embedded in groups would be lost. */
3515 rConvData
.maSolverCont
.InsertSdrObjectInfo( *xSdrObj
, xDrawObj
->GetDffShapeId(), xDrawObj
->GetDffFlags() );
3517 /* If the drawing object is embedded in a group object, call
3518 PostProcessSdrObject() here. For top-level objects this will be
3519 done automatically in InsertSdrObject() but grouped shapes are
3520 inserted into their groups somewhere in the SvxMSDffManager base
3521 class without chance of notification. Unfortunately, now this is
3522 called before the object is really inserted into its group object,
3523 but that should not have any effect for grouped objects. */
3525 xDrawObj
->PostProcessSdrObject( *this, *xSdrObj
);
3528 return xSdrObj
.release();
3531 sal_uLong
XclImpDffConverter::Calc_nBLIPPos( sal_uLong
/*nOrgVal*/, sal_uLong nStreamPos
) const
3533 return nStreamPos
+ 4;
3536 sal_Bool
XclImpDffConverter::InsertControl( const Reference
< XFormComponent
>& rxFormComp
,
3537 const ::com::sun::star::awt::Size
& /*rSize*/, Reference
< XShape
>* pxShape
,
3538 sal_Bool
/*bFloatingCtrl*/ )
3540 if( GetDocShell() ) try
3542 XclImpDffConvData
& rConvData
= GetConvData();
3543 Reference
< XIndexContainer
> xFormIC( rConvData
.mxCtrlForm
, UNO_QUERY_THROW
);
3544 Reference
< XControlModel
> xCtrlModel( rxFormComp
, UNO_QUERY_THROW
);
3546 // create the control shape
3547 Reference
< XShape
> xShape( ScfApiHelper::CreateInstance( GetDocShell(), "com.sun.star.drawing.ControlShape" ), UNO_QUERY_THROW
);
3548 Reference
< XControlShape
> xCtrlShape( xShape
, UNO_QUERY_THROW
);
3550 // insert the new control into the form
3551 sal_Int32 nNewIndex
= xFormIC
->getCount();
3552 xFormIC
->insertByIndex( nNewIndex
, Any( rxFormComp
) );
3553 // on success: store new index of the control for later use (macro events)
3554 rConvData
.mnLastCtrlIndex
= nNewIndex
;
3556 // set control model at control shape and pass back shape to caller
3557 xCtrlShape
->setControl( xCtrlModel
);
3558 if( pxShape
) *pxShape
= xShape
;
3561 catch( const Exception
& )
3563 OSL_FAIL( "XclImpDffConverter::InsertControl - cannot create form control" );
3569 // private --------------------------------------------------------------------
3571 XclImpDffConverter::XclImpDffConvData
& XclImpDffConverter::GetConvData()
3573 OSL_ENSURE( !maDataStack
.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3574 return *maDataStack
.back();
3577 const XclImpDffConverter::XclImpDffConvData
& XclImpDffConverter::GetConvData() const
3579 OSL_ENSURE( !maDataStack
.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3580 return *maDataStack
.back();
3583 String
XclImpDffConverter::ReadHlinkProperty( SvStream
& rDffStrm
) const
3585 /* Reads hyperlink data from a complex DFF property. Contents of this
3586 property are equal to the HLINK record, import of this record is
3587 implemented in class XclImpHyperlink. This function has to create an
3588 instance of the XclImpStream class to be able to reuse the
3589 functionality of XclImpHyperlink. */
3591 sal_uInt32 nBufferSize
= GetPropertyValue( DFF_Prop_pihlShape
);
3592 if( (0 < nBufferSize
) && (nBufferSize
<= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape
, rDffStrm
) )
3594 // create a faked BIFF record that can be read by XclImpStream class
3595 SvMemoryStream aMemStream
;
3596 aMemStream
<< sal_uInt16( 0 ) << static_cast< sal_uInt16
>( nBufferSize
);
3598 // copy from DFF stream to memory stream
3599 ::std::vector
< sal_uInt8
> aBuffer( nBufferSize
);
3600 sal_uInt8
* pnData
= &aBuffer
.front();
3601 if( rDffStrm
.Read( pnData
, nBufferSize
) == nBufferSize
)
3603 aMemStream
.Write( pnData
, nBufferSize
);
3605 // create BIFF import stream to be able to use XclImpHyperlink class
3606 XclImpStream
aXclStrm( aMemStream
, GetRoot() );
3607 if( aXclStrm
.StartNextRecord() )
3608 aString
= XclImpHyperlink::ReadEmbeddedData( aXclStrm
);
3614 void XclImpDffConverter::ProcessDgContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rDgHeader
)
3616 sal_Size nEndPos
= rDgHeader
.GetRecEndFilePos();
3617 while( rDffStrm
.Tell() < nEndPos
)
3619 DffRecordHeader aHeader
;
3620 rDffStrm
>> aHeader
;
3621 switch( aHeader
.nRecType
)
3623 case DFF_msofbtSolverContainer
:
3624 ProcessSolverContainer( rDffStrm
, aHeader
);
3626 case DFF_msofbtSpgrContainer
:
3627 ProcessShGrContainer( rDffStrm
, aHeader
);
3630 aHeader
.SeekToEndOfRecord( rDffStrm
);
3633 // seek to end of drawing page container
3634 rDgHeader
.SeekToEndOfRecord( rDffStrm
);
3636 // #i12638# #i37900# connector rules
3637 XclImpSolverContainer
& rSolverCont
= GetConvData().maSolverCont
;
3638 rSolverCont
.UpdateConnectorRules();
3639 SolveSolver( rSolverCont
);
3640 rSolverCont
.RemoveConnectorRules();
3643 void XclImpDffConverter::ProcessShGrContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rShGrHeader
)
3645 sal_Size nEndPos
= rShGrHeader
.GetRecEndFilePos();
3646 while( rDffStrm
.Tell() < nEndPos
)
3648 DffRecordHeader aHeader
;
3649 rDffStrm
>> aHeader
;
3650 switch( aHeader
.nRecType
)
3652 case DFF_msofbtSpgrContainer
:
3653 case DFF_msofbtSpContainer
:
3654 ProcessShContainer( rDffStrm
, aHeader
);
3657 aHeader
.SeekToEndOfRecord( rDffStrm
);
3660 // seek to end of shape group container
3661 rShGrHeader
.SeekToEndOfRecord( rDffStrm
);
3664 void XclImpDffConverter::ProcessSolverContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rSolverHeader
)
3666 // solver container wants to read the solver container header again
3667 rSolverHeader
.SeekToBegOfRecord( rDffStrm
);
3668 // read the entire solver container
3669 rDffStrm
>> GetConvData().maSolverCont
;
3670 // seek to end of solver container
3671 rSolverHeader
.SeekToEndOfRecord( rDffStrm
);
3674 void XclImpDffConverter::ProcessShContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rShHeader
)
3676 rShHeader
.SeekToBegOfRecord( rDffStrm
);
3678 const XclImpDrawObjBase
* pDrawObj
= 0;
3679 /* The call to ImportObj() creates and returns a new SdrObject for the
3680 processed shape. We take ownership of the returned object here. If the
3681 shape is a group object, all embedded objects are created recursively,
3682 and the returned group object contains them all. ImportObj() calls the
3683 virtual functions ProcessClientAnchor2() and ProcessObj() and writes
3684 the pointer to the related draw object data (OBJ record) into pDrawObj. */
3685 SdrObjectPtr
xSdrObj( ImportObj( rDffStrm
, &pDrawObj
, aDummy
, aDummy
, 0, 0 ) );
3686 if( pDrawObj
&& xSdrObj
.is() )
3687 InsertSdrObject( GetConvData().mrSdrPage
, *pDrawObj
, xSdrObj
.release() );
3688 rShHeader
.SeekToEndOfRecord( rDffStrm
);
3691 void XclImpDffConverter::InsertSdrObject( SdrObjList
& rObjList
, const XclImpDrawObjBase
& rDrawObj
, SdrObject
* pSdrObj
)
3693 XclImpDffConvData
& rConvData
= GetConvData();
3694 /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
3695 states to skip insertion), the object is automatically deleted. */
3696 SdrObjectPtr
xSdrObj( pSdrObj
);
3697 if( xSdrObj
.is() && rDrawObj
.IsInsertSdrObj() )
3699 rObjList
.NbcInsertObject( xSdrObj
.release() );
3700 // callback to drawing manager for e.g. tracking of used sheet area
3701 rConvData
.mrDrawing
.OnObjectInserted( rDrawObj
);
3702 // callback to drawing object for post processing (use pSdrObj, xSdrObj already released)
3703 rDrawObj
.PostProcessSdrObject( *this, *pSdrObj
);
3705 /* SdrObject still here? Insertion failed, remove data from shape ID map.
3706 The SdrObject will be destructed then. */
3708 rConvData
.maSolverCont
.RemoveSdrObjectInfo( *xSdrObj
);
3711 void XclImpDffConverter::InitControlForm()
3713 XclImpDffConvData
& rConvData
= GetConvData();
3714 if( rConvData
.mbHasCtrlForm
)
3717 rConvData
.mbHasCtrlForm
= true;
3718 if( SupportsOleObjects() ) try
3720 Reference
< XFormsSupplier
> xFormsSupplier( rConvData
.mrSdrPage
.getUnoPage(), UNO_QUERY_THROW
);
3721 Reference
< XNameContainer
> xFormsNC( xFormsSupplier
->getForms(), UNO_SET_THROW
);
3722 // find or create the Standard form used to insert the imported controls
3723 if( xFormsNC
->hasByName( maStdFormName
) )
3725 xFormsNC
->getByName( maStdFormName
) >>= rConvData
.mxCtrlForm
;
3727 else if( SfxObjectShell
* pDocShell
= GetDocShell() )
3729 rConvData
.mxCtrlForm
.set( ScfApiHelper::CreateInstance( pDocShell
, "com.sun.star.form.component.Form" ), UNO_QUERY_THROW
);
3730 xFormsNC
->insertByName( maStdFormName
, Any( rConvData
.mxCtrlForm
) );
3733 catch( const Exception
& )
3738 // Drawing manager ============================================================
3740 XclImpDrawing::XclImpDrawing( const XclImpRoot
& rRoot
, bool bOleObjects
) :
3741 XclImpRoot( rRoot
),
3742 mbOleObjs( bOleObjects
)
3746 XclImpDrawing::~XclImpDrawing()
3750 Graphic
XclImpDrawing::ReadImgData( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
3753 sal_uInt16 nFormat
, nEnv
;
3754 sal_uInt32 nDataSize
;
3755 rStrm
>> nFormat
>> nEnv
>> nDataSize
;
3756 if( nDataSize
<= rStrm
.GetRecLeft() )
3760 case EXC_IMGDATA_WMF
: ReadWmf( aGraphic
, rRoot
, rStrm
); break;
3761 case EXC_IMGDATA_BMP
: ReadBmp( aGraphic
, rRoot
, rStrm
); break;
3762 default: OSL_FAIL( "XclImpDrawing::ReadImgData - unknown image format" );
3768 void XclImpDrawing::ReadObj( XclImpStream
& rStrm
)
3770 XclImpDrawObjRef xDrawObj
;
3772 /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
3773 records. In this case, the OBJ records are in BIFF5 format. Do a sanity
3774 check here that there is no DFF data loaded before. */
3775 OSL_ENSURE( maDffStrm
.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
3776 if( maDffStrm
.Tell() == 0 ) switch( GetBiff() )
3779 xDrawObj
= XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm
);
3782 xDrawObj
= XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm
);
3786 xDrawObj
= XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm
);
3794 // insert into maRawObjs or into the last open group object
3795 maRawObjs
.InsertGrouped( xDrawObj
);
3796 // to be able to find objects by ID
3797 maObjMapId
[ xDrawObj
->GetObjId() ] = xDrawObj
;
3801 void XclImpDrawing::ReadMsoDrawing( XclImpStream
& rStrm
)
3803 OSL_ENSURE_BIFF( GetBiff() == EXC_BIFF8
);
3804 // disable internal CONTINUE handling
3805 rStrm
.ResetRecord( false );
3806 // read leading MSODRAWING record
3807 ReadDffRecord( rStrm
);
3809 // read following drawing records, but do not start following unrelated record
3811 while( bLoop
) switch( rStrm
.GetNextRecId() )
3813 case EXC_ID_MSODRAWING
:
3814 case EXC_ID_MSODRAWINGSEL
:
3816 rStrm
.StartNextRecord();
3817 ReadDffRecord( rStrm
);
3820 rStrm
.StartNextRecord();
3824 rStrm
.StartNextRecord();
3831 // re-enable internal CONTINUE handling
3832 rStrm
.ResetRecord( true );
3835 XclImpDrawObjRef
XclImpDrawing::FindDrawObj( const DffRecordHeader
& rHeader
) const
3837 /* maObjMap stores objects by position of the client data (OBJ record) in
3838 the DFF stream, which is always behind shape start position of the
3839 passed header. The function upper_bound() finds the first element in
3840 the map whose key is greater than the start position of the header. Its
3841 end position is used to test whether the found object is really related
3843 XclImpDrawObjRef xDrawObj
;
3844 XclImpObjMap::const_iterator aIt
= maObjMap
.upper_bound( rHeader
.GetRecBegFilePos() );
3845 if( (aIt
!= maObjMap
.end()) && (aIt
->first
<= rHeader
.GetRecEndFilePos()) )
3846 xDrawObj
= aIt
->second
;
3850 XclImpDrawObjRef
XclImpDrawing::FindDrawObj( sal_uInt16 nObjId
) const
3852 XclImpDrawObjRef xDrawObj
;
3853 XclImpObjMapById::const_iterator aIt
= maObjMapId
.find( nObjId
);
3854 if( aIt
!= maObjMapId
.end() )
3855 xDrawObj
= aIt
->second
;
3859 const XclImpObjTextData
* XclImpDrawing::FindTextData( const DffRecordHeader
& rHeader
) const
3861 /* maTextMap stores textbox data by position of the client data (TXO
3862 record) in the DFF stream, which is always behind shape start position
3863 of the passed header. The function upper_bound() finds the first
3864 element in the map whose key is greater than the start position of the
3865 header. Its end position is used to test whether the found object is
3866 really related to the shape. */
3867 XclImpObjTextMap::const_iterator aIt
= maTextMap
.upper_bound( rHeader
.GetRecBegFilePos() );
3868 if( (aIt
!= maTextMap
.end()) && (aIt
->first
<= rHeader
.GetRecEndFilePos()) )
3869 return aIt
->second
.get();
3873 void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId
)
3875 maSkipObjs
.push_back( nObjId
);
3878 sal_Size
XclImpDrawing::GetProgressSize() const
3880 sal_Size nProgressSize
= maRawObjs
.GetProgressSize();
3881 for( XclImpObjMap::const_iterator aIt
= maObjMap
.begin(), aEnd
= maObjMap
.end(); aIt
!= aEnd
; ++aIt
)
3882 nProgressSize
+= aIt
->second
->GetProgressSize();
3883 return nProgressSize
;
3886 void XclImpDrawing::ImplConvertObjects( XclImpDffConverter
& rDffConv
, SdrModel
& rSdrModel
, SdrPage
& rSdrPage
)
3888 //rhbz#636521, disable undo during conversion. faster, smaller and stops
3889 //temp objects being inserted into the undo list
3890 bool bOrigUndoStatus
= rSdrModel
.IsUndoEnabled();
3891 rSdrModel
.EnableUndo(false);
3892 // register this drawing manager at the passed (global) DFF manager
3893 rDffConv
.InitializeDrawing( *this, rSdrModel
, rSdrPage
);
3894 // process list of objects to be skipped
3895 for( ScfUInt16Vec::const_iterator aIt
= maSkipObjs
.begin(), aEnd
= maSkipObjs
.end(); aIt
!= aEnd
; ++aIt
)
3896 if( XclImpDrawObjBase
* pDrawObj
= FindDrawObj( *aIt
).get() )
3897 pDrawObj
->SetProcessSdrObj( false );
3898 // process drawing objects without DFF data
3899 rDffConv
.ProcessDrawing( maRawObjs
);
3900 // process all objects in the DFF stream
3901 rDffConv
.ProcessDrawing( maDffStrm
);
3902 // unregister this drawing manager at the passed (global) DFF manager
3903 rDffConv
.FinalizeDrawing();
3904 rSdrModel
.EnableUndo(bOrigUndoStatus
);
3907 // protected ------------------------------------------------------------------
3909 void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef
& rxDrawObj
)
3911 OSL_ENSURE( rxDrawObj
, "XclImpDrawing::AppendRawObject - unexpected empty reference" );
3912 maRawObjs
.push_back( rxDrawObj
);
3915 // private --------------------------------------------------------------------
3917 void XclImpDrawing::ReadWmf( Graphic
& rGraphic
, const XclImpRoot
&, XclImpStream
& rStrm
) // static helper
3919 // extract graphic data from IMGDATA and following CONTINUE records
3921 SvMemoryStream aMemStrm
;
3922 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
3923 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
3924 // import the graphic from memory stream
3925 GDIMetaFile aGDIMetaFile
;
3926 if( ::ReadWindowMetafile( aMemStrm
, aGDIMetaFile
, 0 ) )
3927 rGraphic
= aGDIMetaFile
;
3930 void XclImpDrawing::ReadBmp( Graphic
& rGraphic
, const XclImpRoot
& rRoot
, XclImpStream
& rStrm
) // static helper
3932 // extract graphic data from IMGDATA and following CONTINUE records
3933 SvMemoryStream aMemStrm
;
3935 /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
3936 DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
3937 pixel depth = 32 bit. After that, 3 unused bytes are added before the
3938 actual pixel data. This does even confuse Excel 5 and later, which
3939 cannot read the image data correctly. */
3940 if( rRoot
.GetBiff() <= EXC_BIFF4
)
3942 rStrm
.PushPosition();
3943 sal_uInt32 nHdrSize
;
3944 sal_uInt16 nWidth
, nHeight
, nPlanes
, nDepth
;
3945 rStrm
>> nHdrSize
>> nWidth
>> nHeight
>> nPlanes
>> nDepth
;
3946 if( (nHdrSize
== 12) && (nPlanes
== 1) && (nDepth
== 32) )
3949 aMemStrm
.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
3950 aMemStrm
<< nHdrSize
<< nWidth
<< nHeight
<< nPlanes
<< nDepth
;
3951 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
3953 rStrm
.PopPosition();
3956 // no special handling above -> just copy the remaining record data
3957 if( aMemStrm
.Tell() == 0 )
3958 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
3960 // import the graphic from memory stream
3961 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
3963 if( aBitmap
.Read( aMemStrm
, false ) ) // read DIB without file header
3967 void XclImpDrawing::ReadDffRecord( XclImpStream
& rStrm
)
3969 maDffStrm
.Seek( STREAM_SEEK_TO_END
);
3970 rStrm
.CopyRecordToStream( maDffStrm
);
3973 void XclImpDrawing::ReadObj8( XclImpStream
& rStrm
)
3975 XclImpDrawObjRef xDrawObj
= XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm
);
3976 // store the new object in the internal containers
3977 maObjMap
[ maDffStrm
.Tell() ] = xDrawObj
;
3978 maObjMapId
[ xDrawObj
->GetObjId() ] = xDrawObj
;
3981 void XclImpDrawing::ReadTxo( XclImpStream
& rStrm
)
3983 XclImpObjTextRef
xTextData( new XclImpObjTextData
);
3984 maTextMap
[ maDffStrm
.Tell() ] = xTextData
;
3986 // 1) read the TXO record
3987 xTextData
->maData
.ReadTxo8( rStrm
);
3989 // 2) first CONTINUE with string
3990 xTextData
->mxString
.reset();
3992 if( xTextData
->maData
.mnTextLen
> 0 )
3994 bValid
= (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord();
3995 OSL_ENSURE( bValid
, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
3997 xTextData
->mxString
.reset( new XclImpString( rStrm
.ReadUniString( xTextData
->maData
.mnTextLen
) ) );
4000 // 3) second CONTINUE with formatting runs
4001 if( xTextData
->maData
.mnFormatSize
> 0 )
4003 bValid
= (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord();
4004 OSL_ENSURE( bValid
, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
4006 xTextData
->ReadFormats( rStrm
);
4010 // ----------------------------------------------------------------------------
4012 XclImpSheetDrawing::XclImpSheetDrawing( const XclImpRoot
& rRoot
, SCTAB nScTab
) :
4013 XclImpDrawing( rRoot
, true ),
4014 maScUsedArea( ScAddress::INITIALIZE_INVALID
)
4016 maScUsedArea
.aStart
.SetTab( nScTab
);
4017 maScUsedArea
.aEnd
.SetTab( nScTab
);
4020 void XclImpSheetDrawing::ReadNote( XclImpStream
& rStrm
)
4038 void XclImpSheetDrawing::ReadTabChart( XclImpStream
& rStrm
)
4040 OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF5
);
4041 boost::shared_ptr
< XclImpChartObj
> xChartObj( new XclImpChartObj( GetRoot(), true ) );
4042 xChartObj
->ReadChartSubStream( rStrm
);
4043 // insert the chart as raw object without connected DFF data
4044 AppendRawObject( xChartObj
);
4047 void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter
& rDffConv
)
4049 if( SdrModel
* pSdrModel
= GetDoc().GetDrawLayer() )
4050 if( SdrPage
* pSdrPage
= GetSdrPage( maScUsedArea
.aStart
.Tab() ) )
4051 ImplConvertObjects( rDffConv
, *pSdrModel
, *pSdrPage
);
4054 Rectangle
XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor
& rAnchor
, bool /*bDffAnchor*/ ) const
4056 return rAnchor
.GetRect( GetRoot(), maScUsedArea
.aStart
.Tab(), MAP_100TH_MM
);
4059 void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase
& rDrawObj
)
4061 ScRange aScObjArea
= rDrawObj
.GetUsedArea( maScUsedArea
.aStart
.Tab() );
4062 if( aScObjArea
.IsValid() )
4063 maScUsedArea
.ExtendTo( aScObjArea
);
4066 // private --------------------------------------------------------------------
4068 void XclImpSheetDrawing::ReadNote3( XclImpStream
& rStrm
)
4071 sal_uInt16 nTotalLen
;
4072 rStrm
>> aXclPos
>> nTotalLen
;
4074 ScAddress
aScNotePos( ScAddress::UNINITIALIZED
);
4075 if( GetAddressConverter().ConvertAddress( aScNotePos
, aXclPos
, maScUsedArea
.aStart
.Tab(), true ) )
4077 sal_uInt16 nPartLen
= ::std::min( nTotalLen
, static_cast< sal_uInt16
>( rStrm
.GetRecLeft() ) );
4078 String aNoteText
= rStrm
.ReadRawByteString( nPartLen
);
4079 nTotalLen
= nTotalLen
- nPartLen
;
4080 while( (nTotalLen
> 0) && (rStrm
.GetNextRecId() == EXC_ID_NOTE
) && rStrm
.StartNextRecord() )
4082 rStrm
>> aXclPos
>> nPartLen
;
4083 OSL_ENSURE( aXclPos
.mnRow
== 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
4084 if( aXclPos
.mnRow
== 0xFFFF )
4086 OSL_ENSURE( nPartLen
<= nTotalLen
, "XclImpObjectManager::ReadNote3 - string too long" );
4087 aNoteText
.Append( rStrm
.ReadRawByteString( nPartLen
) );
4088 nTotalLen
= nTotalLen
- ::std::min( nTotalLen
, nPartLen
);
4092 // seems to be a new note, record already started -> load the note
4093 rStrm
.Seek( EXC_REC_SEEK_TO_BEGIN
);
4098 ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos
, aNoteText
, false, false );
4102 void XclImpSheetDrawing::ReadNote8( XclImpStream
& rStrm
)
4105 sal_uInt16 nFlags
, nObjId
;
4106 rStrm
>> aXclPos
>> nFlags
>> nObjId
;
4108 ScAddress
aScNotePos( ScAddress::UNINITIALIZED
);
4109 if( GetAddressConverter().ConvertAddress( aScNotePos
, aXclPos
, maScUsedArea
.aStart
.Tab(), true ) )
4110 if( nObjId
!= EXC_OBJ_INVALID_ID
)
4111 if( XclImpNoteObj
* pNoteObj
= dynamic_cast< XclImpNoteObj
* >( FindDrawObj( nObjId
).get() ) )
4112 pNoteObj
->SetNoteData( aScNotePos
, nFlags
);
4115 // The object manager =========================================================
4117 XclImpObjectManager::XclImpObjectManager( const XclImpRoot
& rRoot
) :
4120 maDefObjNames
[ EXC_OBJTYPE_GROUP
] = "Group";
4121 maDefObjNames
[ EXC_OBJTYPE_LINE
] = ScGlobal::GetRscString( STR_SHAPE_LINE
);
4122 maDefObjNames
[ EXC_OBJTYPE_RECTANGLE
] = ScGlobal::GetRscString( STR_SHAPE_RECTANGLE
);
4123 maDefObjNames
[ EXC_OBJTYPE_OVAL
] = ScGlobal::GetRscString( STR_SHAPE_OVAL
);
4124 maDefObjNames
[ EXC_OBJTYPE_ARC
] = "Arc";
4125 maDefObjNames
[ EXC_OBJTYPE_CHART
] = "Chart";
4126 maDefObjNames
[ EXC_OBJTYPE_TEXT
] = "Text";
4127 maDefObjNames
[ EXC_OBJTYPE_BUTTON
] = ScGlobal::GetRscString( STR_FORM_BUTTON
);
4128 maDefObjNames
[ EXC_OBJTYPE_PICTURE
] = "Picture";
4129 maDefObjNames
[ EXC_OBJTYPE_POLYGON
] = "Freeform";
4130 maDefObjNames
[ EXC_OBJTYPE_CHECKBOX
] = ScGlobal::GetRscString( STR_FORM_CHECKBOX
);
4131 maDefObjNames
[ EXC_OBJTYPE_OPTIONBUTTON
] = ScGlobal::GetRscString( STR_FORM_OPTIONBUTTON
);
4132 maDefObjNames
[ EXC_OBJTYPE_EDIT
] = "Edit Box";
4133 maDefObjNames
[ EXC_OBJTYPE_LABEL
] = ScGlobal::GetRscString( STR_FORM_LABEL
);
4134 maDefObjNames
[ EXC_OBJTYPE_DIALOG
] = "Dialog Frame";
4135 maDefObjNames
[ EXC_OBJTYPE_SPIN
] = ScGlobal::GetRscString( STR_FORM_SPINNER
);
4136 maDefObjNames
[ EXC_OBJTYPE_SCROLLBAR
] = ScGlobal::GetRscString( STR_FORM_SCROLLBAR
);
4137 maDefObjNames
[ EXC_OBJTYPE_LISTBOX
] = ScGlobal::GetRscString( STR_FORM_LISTBOX
);
4138 maDefObjNames
[ EXC_OBJTYPE_GROUPBOX
] = ScGlobal::GetRscString( STR_FORM_GROUPBOX
);
4139 maDefObjNames
[ EXC_OBJTYPE_DROPDOWN
] = ScGlobal::GetRscString( STR_FORM_DROPDOWN
);
4140 maDefObjNames
[ EXC_OBJTYPE_NOTE
] = "Comment";
4141 maDefObjNames
[ EXC_OBJTYPE_DRAWING
] = ScGlobal::GetRscString( STR_SHAPE_AUTOSHAPE
);
4144 XclImpObjectManager::~XclImpObjectManager()
4148 void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream
& rStrm
)
4150 OSL_ENSURE_BIFF( GetBiff() == EXC_BIFF8
);
4151 // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
4152 rStrm
.ResetRecord( true, EXC_ID_MSODRAWINGGROUP
);
4153 maDggStrm
.Seek( STREAM_SEEK_TO_END
);
4154 rStrm
.CopyRecordToStream( maDggStrm
);
4157 XclImpSheetDrawing
& XclImpObjectManager::GetSheetDrawing( SCTAB nScTab
)
4159 XclImpSheetDrawingRef
& rxDrawing
= maSheetDrawings
[ nScTab
];
4161 rxDrawing
.reset( new XclImpSheetDrawing( GetRoot(), nScTab
) );
4165 void XclImpObjectManager::ConvertObjects()
4167 RTL_LOGFILE_CONTEXT_AUTHOR( aLog
, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" );
4169 // do nothing if the document does not contain a drawing layer
4170 if( !GetDoc().GetDrawLayer() )
4173 // get total progress bar size for all sheet drawing managers
4174 sal_Size nProgressSize
= 0;
4175 for( XclImpSheetDrawingMap::iterator aIt
= maSheetDrawings
.begin(), aEnd
= maSheetDrawings
.end(); aIt
!= aEnd
; ++aIt
)
4176 nProgressSize
+= aIt
->second
->GetProgressSize();
4177 // nothing to do if progress bar is zero (no objects present)
4178 if( nProgressSize
== 0 )
4181 XclImpDffConverter
aDffConv( GetRoot(), maDggStrm
);
4182 aDffConv
.StartProgressBar( nProgressSize
);
4183 for( XclImpSheetDrawingMap::iterator aIt
= maSheetDrawings
.begin(), aEnd
= maSheetDrawings
.end(); aIt
!= aEnd
; ++aIt
)
4184 aIt
->second
->ConvertObjects( aDffConv
);
4186 // #i112436# don't call ScChartListenerCollection::SetDirty here,
4187 // instead use InterpretDirtyCells in ScDocument::CalcAfterLoad.
4190 OUString
XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase
& rDrawObj
) const
4192 OUStringBuffer aDefName
;
4193 DefObjNameMap::const_iterator aIt
= maDefObjNames
.find( rDrawObj
.GetObjType() );
4194 if( aIt
!= maDefObjNames
.end() )
4195 aDefName
.append(aIt
->second
);
4196 return aDefName
.append(' ').append(static_cast<sal_Int32
>(rDrawObj
.GetObjId())).makeStringAndClear();
4199 ScRange
XclImpObjectManager::GetUsedArea( SCTAB nScTab
) const
4201 XclImpSheetDrawingMap::const_iterator aIt
= maSheetDrawings
.find( nScTab
);
4202 if( aIt
!= maSheetDrawings
.end() )
4203 return aIt
->second
->GetUsedArea();
4204 return ScRange( ScAddress::INITIALIZE_INVALID
);
4207 // DFF property set helper ====================================================
4209 XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot
& rRoot
) :
4210 XclImpRoot( rRoot
),
4211 maDffConv( rRoot
, maDummyStrm
)
4215 void XclImpDffPropSet::Read( XclImpStream
& rStrm
)
4217 sal_uInt32 nPropSetSize
;
4219 rStrm
.PushPosition();
4221 rStrm
>> nPropSetSize
;
4222 rStrm
.PopPosition();
4224 mxMemStrm
.reset( new SvMemoryStream
);
4225 rStrm
.CopyToStream( *mxMemStrm
, 8 + nPropSetSize
);
4226 mxMemStrm
->Seek( STREAM_SEEK_TO_BEGIN
);
4227 maDffConv
.ReadPropSet( *mxMemStrm
, 0 );
4230 sal_uInt32
XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId
, sal_uInt32 nDefault
) const
4232 return maDffConv
.GetPropertyValue( nPropId
, nDefault
);
4235 void XclImpDffPropSet::FillToItemSet( SfxItemSet
& rItemSet
) const
4237 if( mxMemStrm
.get() )
4238 maDffConv
.ApplyAttributes( *mxMemStrm
, rItemSet
);
4241 XclImpStream
& operator>>( XclImpStream
& rStrm
, XclImpDffPropSet
& rPropSet
)
4243 rPropSet
.Read( rStrm
);
4247 // ============================================================================
4249 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */