1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26
27 #include "xiescher.hxx"
28
29 #include <com/sun/star/beans/NamedValue.hpp>
30 #include <com/sun/star/container/XIndexContainer.hpp>
31 #include <com/sun/star/container/XNameContainer.hpp>
32 #include <com/sun/star/embed/Aspects.hpp>
33 #include <com/sun/star/embed/XEmbeddedObject.hpp>
34 #include <com/sun/star/embed/XEmbedPersist.hpp>
35 #include <com/sun/star/awt/PushButtonType.hpp>
36 #include <com/sun/star/awt/ScrollBarOrientation.hpp>
37 #include <com/sun/star/awt/VisualEffect.hpp>
38 #include <com/sun/star/style/HorizontalAlignment.hpp>
39 #include <com/sun/star/style/VerticalAlignment.hpp>
40 #include <com/sun/star/drawing/XControlShape.hpp>
41 #include <com/sun/star/form/XForm.hpp>
42 #include <com/sun/star/form/XFormsSupplier.hpp>
43 #include <com/sun/star/form/binding/XBindableValue.hpp>
44 #include <com/sun/star/form/binding/XValueBinding.hpp>
45 #include <com/sun/star/form/binding/XListEntrySink.hpp>
46 #include <com/sun/star/form/binding/XListEntrySource.hpp>
47 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
48 #include <com/sun/star/script/XEventAttacherManager.hpp>
49 #include <com/sun/star/beans/XPropertySet.hpp>
50
51 #include <rtl/logfile.hxx>
52 #include <sfx2/objsh.hxx>
53 #include <unotools/moduleoptions.hxx>
54 #include <unotools/fltrcfg.hxx>
55 #include <svtools/wmf.hxx>
56 #include <comphelper/types.hxx>
57 #include <comphelper/classids.hxx>
58 #include <toolkit/helper/vclunohelper.hxx>
59 #include <basegfx/point/b2dpoint.hxx>
60 #include <basegfx/polygon/b2dpolygon.hxx>
61
62 #include <svx/svdopath.hxx>
63 #include <svx/svdocirc.hxx>
64 #include <svx/svdoedge.hxx>
65 #include <svx/svdogrp.hxx>
66 #include <svx/svdoashp.hxx>
67 #include <svx/svdograf.hxx>
68 #include <svx/svdoole2.hxx>
69 #include <svx/svdocapt.hxx>
70 #include <svx/svdouno.hxx>
71 #include <svx/svdpage.hxx>
72 #include <editeng/editobj.hxx>
73 #include <editeng/outliner.hxx>
74 #include <editeng/outlobj.hxx>
75 #include <svx/unoapi.hxx>
76 #include <svx/svditer.hxx>
77 #include <editeng/writingmodeitem.hxx>
78 #include <svx/charthelper.hxx>
79
80 #include "scitems.hxx"
81 #include <editeng/eeitem.hxx>
82 #include <editeng/colritem.hxx>
83 #include <svx/xflclit.hxx>
84 #include <editeng/adjitem.hxx>
85 #include <svx/xlineit.hxx>
86 #include <svx/xlinjoit.hxx>
87 #include <svx/xlntrit.hxx>
88 #include <svx/xbtmpit.hxx>
89 #include <vcl/dibtools.hxx>
90
91 #include "document.hxx"
92 #include "drwlayer.hxx"
93 #include "userdat.hxx"
94 #include "chartarr.hxx"
95 #include "detfunc.hxx"
96 #include "unonames.hxx"
97 #include "convuno.hxx"
98 #include "postit.hxx"
99 #include "globstr.hrc"
100
101 #include "fprogressbar.hxx"
102 #include "xltracer.hxx"
103 #include "xistream.hxx"
104 #include "xihelper.hxx"
105 #include "xiformula.hxx"
106 #include "xilink.hxx"
107 #include "xistyle.hxx"
108 #include "xipage.hxx"
109 #include "xichart.hxx"
110 #include "xicontent.hxx"
111 #include "namebuff.hxx"
112
113 using ::rtl::OUString;
114 using ::rtl::OUStringBuffer;
115 using ::com::sun::star::uno::makeAny;
116 using ::com::sun::star::uno::Any;
117 using ::com::sun::star::beans::XPropertySet;
118 using ::com::sun::star::uno::makeAny;
119 using ::com::sun::star::uno::Exception;
120 using ::com::sun::star::uno::Reference;
121 using ::com::sun::star::uno::Sequence;
122 using ::com::sun::star::uno::UNO_QUERY;
123 using ::com::sun::star::uno::UNO_QUERY_THROW;
124 using ::com::sun::star::uno::UNO_SET_THROW;
125 using ::com::sun::star::beans::NamedValue;
126 using ::com::sun::star::lang::XMultiServiceFactory;
127 using ::com::sun::star::container::XIndexContainer;
128 using ::com::sun::star::container::XNameContainer;
129 using ::com::sun::star::frame::XModel;
130 using ::com::sun::star::awt::XControlModel;
131 using ::com::sun::star::embed::XEmbeddedObject;
132 using ::com::sun::star::embed::XEmbedPersist;
133 using ::com::sun::star::drawing::XControlShape;
134 using ::com::sun::star::drawing::XShape;
135 using ::com::sun::star::form::XForm;
136 using ::com::sun::star::form::XFormComponent;
137 using ::com::sun::star::form::XFormsSupplier;
138 using ::com::sun::star::form::binding::XBindableValue;
139 using ::com::sun::star::form::binding::XValueBinding;
140 using ::com::sun::star::form::binding::XListEntrySink;
141 using ::com::sun::star::form::binding::XListEntrySource;
142 using ::com::sun::star::script::ScriptEventDescriptor;
143 using ::com::sun::star::script::XEventAttacherManager;
144 using ::com::sun::star::table::CellAddress;
145 using ::com::sun::star::table::CellRangeAddress;
146
147 // ============================================================================
148
149 namespace {
150
151 /** Helper class which mimics the auto_ptr< SdrObject > semantics, but calls
152 SdrObject::Free instead of deleting the SdrObject directly. */
153 template< typename SdrObjType >
154 class TSdrObjectPtr
155 {
156 public:
TSdrObjectPtr(SdrObjType * pObj=0)157 inline explicit TSdrObjectPtr( SdrObjType* pObj = 0 ) : mpObj( pObj ) {}
~TSdrObjectPtr()158 inline ~TSdrObjectPtr() { free(); }
159
operator ->() const160 inline const SdrObjType* operator->() const { return mpObj; }
operator ->()161 inline SdrObjType* operator->() { return mpObj; }
162
get() const163 inline const SdrObjType* get() const { return mpObj; }
get()164 inline SdrObjType* get() { return mpObj; }
165
operator *() const166 inline const SdrObjType& operator*() const { return *mpObj; }
operator *()167 inline SdrObjType& operator*() { return *mpObj; }
168
is() const169 inline bool is() const { return mpObj != 0; }
operator !() const170 inline bool operator!() const { return mpObj == 0; }
171
reset(SdrObjType * pObj=0)172 inline void reset( SdrObjType* pObj = 0 ) { free(); mpObj = pObj; }
release()173 inline SdrObjType* release() { SdrObjType* pObj = mpObj; mpObj = 0; return pObj; }
174
175 private:
176 TSdrObjectPtr( const TSdrObjectPtr& ); // not implemented
177 TSdrObjectPtr& operator=( TSdrObjectPtr& rxObj ); // not implemented
178
free()179 inline void free() { SdrObject* pObj = mpObj; mpObj = 0; SdrObject::Free( pObj ); }
180
181 private:
182 SdrObjType* mpObj;
183 };
184
185 typedef TSdrObjectPtr< SdrObject > SdrObjectPtr;
186
187 } // namespace
188
189 // Drawing objects ============================================================
190
XclImpDrawObjBase(const XclImpRoot & rRoot)191 XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot& rRoot ) :
192 XclImpRoot( rRoot ),
193 mnObjId( EXC_OBJ_INVALID_ID ),
194 mnObjType( EXC_OBJTYPE_UNKNOWN ),
195 mnDffShapeId( 0 ),
196 mnDffFlags( 0 ),
197 mbHasAnchor( false ),
198 mbHidden( false ),
199 mbVisible( true ),
200 mbPrintable( true ),
201 mbAreaObj( false ),
202 mbAutoMargin( true ),
203 mbSimpleMacro( true ),
204 mbProcessSdr( true ),
205 mbInsertSdr( true ),
206 mbCustomDff( false )
207 {
208 // if this sheet(ScTab) have an xclimpdrawobjbase (i.e. it contain sdrobject),
209 // then the sheet should be 'updaterowheights' in loading procedure. i120586
210 GetDoc().SetPendingRowHeights( rRoot.GetCurrScTab(), false );
211 }
212
~XclImpDrawObjBase()213 XclImpDrawObjBase::~XclImpDrawObjBase()
214 {
215 }
216
ReadObj3(const XclImpRoot & rRoot,XclImpStream & rStrm)217 /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj3( const XclImpRoot& rRoot, XclImpStream& rStrm )
218 {
219 XclImpDrawObjRef xDrawObj;
220
221 if( rStrm.GetRecLeft() >= 30 )
222 {
223 sal_uInt16 nObjType;
224 rStrm.Ignore( 4 );
225 rStrm >> nObjType;
226 switch( nObjType )
227 {
228 case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
229 case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
230 case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
231 case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
232 case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
233 case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
234 case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
235 case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
236 case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
237 default:
238 DBG_ERROR1( "XclImpDrawObjBase::ReadObj3 - unknown object type 0x%04hX", nObjType );
239 rRoot.GetTracer().TraceUnsupportedObjects();
240 xDrawObj.reset( new XclImpPhObj( rRoot ) );
241 }
242 }
243
244 xDrawObj->ImplReadObj3( rStrm );
245 return xDrawObj;
246 }
247
ReadObj4(const XclImpRoot & rRoot,XclImpStream & rStrm)248 /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj4( const XclImpRoot& rRoot, XclImpStream& rStrm )
249 {
250 XclImpDrawObjRef xDrawObj;
251
252 if( rStrm.GetRecLeft() >= 30 )
253 {
254 sal_uInt16 nObjType;
255 rStrm.Ignore( 4 );
256 rStrm >> nObjType;
257 switch( nObjType )
258 {
259 case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
260 case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
261 case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
262 case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
263 case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
264 case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
265 case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
266 case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
267 case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
268 case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break;
269 default:
270 DBG_ERROR1( "XclImpDrawObjBase::ReadObj4 - unknown object type 0x%04hX", nObjType );
271 rRoot.GetTracer().TraceUnsupportedObjects();
272 xDrawObj.reset( new XclImpPhObj( rRoot ) );
273 }
274 }
275
276 xDrawObj->ImplReadObj4( rStrm );
277 return xDrawObj;
278 }
279
ReadObj5(const XclImpRoot & rRoot,XclImpStream & rStrm)280 /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj5( const XclImpRoot& rRoot, XclImpStream& rStrm )
281 {
282 XclImpDrawObjRef xDrawObj;
283
284 if( rStrm.GetRecLeft() >= 34 )
285 {
286 sal_uInt16 nObjType;
287 rStrm.Ignore( 4 );
288 rStrm >> nObjType;
289 switch( nObjType )
290 {
291 case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
292 case EXC_OBJTYPE_LINE: xDrawObj.reset( new XclImpLineObj( rRoot ) ); break;
293 case EXC_OBJTYPE_RECTANGLE: xDrawObj.reset( new XclImpRectObj( rRoot ) ); break;
294 case EXC_OBJTYPE_OVAL: xDrawObj.reset( new XclImpOvalObj( rRoot ) ); break;
295 case EXC_OBJTYPE_ARC: xDrawObj.reset( new XclImpArcObj( rRoot ) ); break;
296 case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
297 case EXC_OBJTYPE_TEXT: xDrawObj.reset( new XclImpTextObj( rRoot ) ); break;
298 case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
299 case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
300 case EXC_OBJTYPE_POLYGON: xDrawObj.reset( new XclImpPolygonObj( rRoot ) ); break;
301 case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break;
302 case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break;
303 case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break;
304 case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break;
305 case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break;
306 case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break;
307 case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break;
308 case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break;
309 case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break;
310 case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break;
311 default:
312 DBG_ERROR1( "XclImpDrawObjBase::ReadObj5 - unknown object type 0x%04hX", nObjType );
313 rRoot.GetTracer().TraceUnsupportedObjects();
314 xDrawObj.reset( new XclImpPhObj( rRoot ) );
315 }
316 }
317
318 xDrawObj->ImplReadObj5( rStrm );
319 return xDrawObj;
320 }
321
ReadObj8(const XclImpRoot & rRoot,XclImpStream & rStrm)322 /*static*/ XclImpDrawObjRef XclImpDrawObjBase::ReadObj8( const XclImpRoot& rRoot, XclImpStream& rStrm )
323 {
324 XclImpDrawObjRef xDrawObj;
325
326 if( rStrm.GetRecLeft() >= 10 )
327 {
328 sal_uInt16 nSubRecId, nSubRecSize, nObjType;
329 rStrm >> nSubRecId >> nSubRecSize >> nObjType;
330
331 if(EXC_ID_OBJCMO == nSubRecId)
332 {
333 if( (nSubRecSize >= 6) )
334 {
335 switch( nObjType )
336 {
337 // in BIFF8, all simple objects support text
338 case EXC_OBJTYPE_LINE:
339 case EXC_OBJTYPE_ARC:
340 xDrawObj.reset( new XclImpTextObj( rRoot ) );
341 // lines and arcs may be 2-dimensional
342 xDrawObj->SetAreaObj( false );
343 break;
344
345 // in BIFF8, all simple objects support text
346 case EXC_OBJTYPE_RECTANGLE:
347 case EXC_OBJTYPE_OVAL:
348 case EXC_OBJTYPE_POLYGON:
349 case EXC_OBJTYPE_DRAWING:
350 case EXC_OBJTYPE_TEXT:
351 xDrawObj.reset( new XclImpTextObj( rRoot ) );
352 break;
353
354 case EXC_OBJTYPE_GROUP: xDrawObj.reset( new XclImpGroupObj( rRoot ) ); break;
355 case EXC_OBJTYPE_CHART: xDrawObj.reset( new XclImpChartObj( rRoot ) ); break;
356 case EXC_OBJTYPE_BUTTON: xDrawObj.reset( new XclImpButtonObj( rRoot ) ); break;
357 case EXC_OBJTYPE_PICTURE: xDrawObj.reset( new XclImpPictureObj( rRoot ) ); break;
358 case EXC_OBJTYPE_CHECKBOX: xDrawObj.reset( new XclImpCheckBoxObj( rRoot ) ); break;
359 case EXC_OBJTYPE_OPTIONBUTTON: xDrawObj.reset( new XclImpOptionButtonObj( rRoot ) ); break;
360 case EXC_OBJTYPE_EDIT: xDrawObj.reset( new XclImpEditObj( rRoot ) ); break;
361 case EXC_OBJTYPE_LABEL: xDrawObj.reset( new XclImpLabelObj( rRoot ) ); break;
362 case EXC_OBJTYPE_DIALOG: xDrawObj.reset( new XclImpDialogObj( rRoot ) ); break;
363 case EXC_OBJTYPE_SPIN: xDrawObj.reset( new XclImpSpinButtonObj( rRoot ) ); break;
364 case EXC_OBJTYPE_SCROLLBAR: xDrawObj.reset( new XclImpScrollBarObj( rRoot ) ); break;
365 case EXC_OBJTYPE_LISTBOX: xDrawObj.reset( new XclImpListBoxObj( rRoot ) ); break;
366 case EXC_OBJTYPE_GROUPBOX: xDrawObj.reset( new XclImpGroupBoxObj( rRoot ) ); break;
367 case EXC_OBJTYPE_DROPDOWN: xDrawObj.reset( new XclImpDropDownObj( rRoot ) ); break;
368 case EXC_OBJTYPE_NOTE: xDrawObj.reset( new XclImpNoteObj( rRoot ) ); break;
369
370 default:
371 DBG_ERROR1( "XclImpDrawObjBase::ReadObj8 - unknown object type 0x%04hX", nObjType );
372 rRoot.GetTracer().TraceUnsupportedObjects();
373 xDrawObj.reset( new XclImpPhObj( rRoot ) );
374 }
375 }
376
377 xDrawObj->ImplReadObj8( rStrm );
378 }
379 else
380 {
381 DBG_ASSERT(false, "XclImpDrawObjBase::ReadObj8 - OBJCMO subrecord expected" );
382 }
383 }
384
385 return xDrawObj;
386 }
387
SetAnchor(const XclObjAnchor & rAnchor)388 void XclImpDrawObjBase::SetAnchor( const XclObjAnchor& rAnchor )
389 {
390 maAnchor = rAnchor;
391 mbHasAnchor = true;
392 }
393
SetDffData(const DffObjData & rDffObjData,const String & rObjName,const String & rHyperlink,bool bVisible,bool bAutoMargin)394 void XclImpDrawObjBase::SetDffData( const DffObjData& rDffObjData, const String& rObjName, const String& rHyperlink, bool bVisible, bool bAutoMargin )
395 {
396 mnDffShapeId = rDffObjData.nShapeId;
397 mnDffFlags = rDffObjData.nSpFlags;
398 maObjName = rObjName;
399 maHyperlink = rHyperlink;
400 mbVisible = bVisible;
401 mbAutoMargin = bAutoMargin;
402 }
403
GetObjName() const404 String XclImpDrawObjBase::GetObjName() const
405 {
406 /* #118053# #i51348# Always return a non-empty name. Create English
407 default names depending on the object type. This is not implemented as
408 virtual functions in derived classes, as class type and object type may
409 not match. */
410 return (maObjName.Len() > 0) ? maObjName : GetObjectManager().GetDefaultObjName( *this );
411 }
412
GetAnchor() const413 const XclObjAnchor* XclImpDrawObjBase::GetAnchor() const
414 {
415 return mbHasAnchor ? &maAnchor : 0;
416 }
417
IsValidSize(const Rectangle & rAnchorRect) const418 bool XclImpDrawObjBase::IsValidSize( const Rectangle& rAnchorRect ) const
419 {
420 // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0
421 return mbAreaObj ?
422 ((rAnchorRect.GetWidth() > 3) && (rAnchorRect.GetHeight() > 1)) :
423 ((rAnchorRect.GetWidth() > 3) || (rAnchorRect.GetHeight() > 1));
424 }
425
GetUsedArea(SCTAB nScTab) const426 ScRange XclImpDrawObjBase::GetUsedArea( SCTAB nScTab ) const
427 {
428 ScRange aScUsedArea( ScAddress::INITIALIZE_INVALID );
429 // #i44077# object inserted -> update used area for OLE object import
430 if( mbHasAnchor && GetAddressConverter().ConvertRange( aScUsedArea, maAnchor, nScTab, nScTab, false ) )
431 {
432 // reduce range, if object ends directly on borders between two columns or rows
433 if( (maAnchor.mnRX == 0) && (aScUsedArea.aStart.Col() < aScUsedArea.aEnd.Col()) )
434 aScUsedArea.aEnd.IncCol( -1 );
435 if( (maAnchor.mnBY == 0) && (aScUsedArea.aStart.Row() < aScUsedArea.aEnd.Row()) )
436 aScUsedArea.aEnd.IncRow( -1 );
437 }
438 return aScUsedArea;
439 }
440
GetProgressSize() const441 sal_Size XclImpDrawObjBase::GetProgressSize() const
442 {
443 return DoGetProgressSize();
444 }
445
CreateSdrObject(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect,bool bIsDff) const446 SdrObject* XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect, bool bIsDff ) const
447 {
448 SdrObjectPtr xSdrObj;
449 if( bIsDff && !mbCustomDff )
450 {
451 rDffConv.Progress( GetProgressSize() );
452 }
453 else
454 {
455 xSdrObj.reset( DoCreateSdrObj( rDffConv, rAnchorRect ) );
456 if( xSdrObj.is() )
457 xSdrObj->SetModel( rDffConv.GetModel() );
458 //added for exporting OCX control
459 /* mnObjType value set should be as below table:
460 0x0000 Group 0x0001 Line
461 0x0002 Rectangle 0x0003 Oval
462 0x0004 Arc 0x0005 Chart
463 0x0006 Text 0x0009 Polygon
464 +-----------------------------------------------------+
465 OCX ==>| 0x0008 Picture |
466 +-----------------------------------------------------+
467 | 0x0007 Button |
468 | 0x000B Checkbox 0x000C Radio button |
469 | 0x000D Edit box 0x000E Label |
470 TBX ==> | 0x000F Dialog box 0x0010 Spin control |
471 | 0x0011 Scrollbar 0x0012 List |
472 | 0x0013 Group box 0x0014 Dropdown list |
473 +-----------------------------------------------------+
474 0x0019 Note 0x001E OfficeArt object
475 */
476 if( xSdrObj.is() && xSdrObj->IsUnoObj() &&
477 ( (mnObjType < 25 && mnObjType > 10) || mnObjType == 7 || mnObjType == 8 ) )
478 {
479 SdrUnoObj* pSdrUnoObj = dynamic_cast< SdrUnoObj* >( xSdrObj.get() );
480 if( pSdrUnoObj != NULL )
481 {
482 Reference< XControlModel > xCtrlModel = pSdrUnoObj->GetUnoControlModel();
483 Reference< XPropertySet > xPropSet(xCtrlModel,UNO_QUERY);
484 const static rtl::OUString sPropertyName = rtl::OUString::createFromAscii("ControlTypeinMSO");
485
486 enum ControlType { eCreateFromAOO = 0, eCreateFromMSTBXControl, eCreateFromMSOCXControl };
487
488 if( mnObjType == 7 || (mnObjType < 25 && mnObjType > 10) )//TBX
489 {
490 //Need summary type for export. Detail type(checkbox, button ...) has been contained by mnObjType
491 const sal_Int16 nTBXControlType = eCreateFromMSTBXControl ;
492 Any aAny;
493 aAny <<= nTBXControlType;
494 try{
495 xPropSet->setPropertyValue(sPropertyName, aAny);
496 }catch(...)
497 {
498 OSL_TRACE("XclImpDrawObjBase::CreateSdrObject, this control can't be set the property ControlTypeinMSO!");
499 }
500 }
501 if( mnObjType == 8 )//OCX
502 {
503 //Need summary type for export
504 const static rtl::OUString sObjIdPropertyName = rtl::OUString::createFromAscii("ObjIDinMSO");
505 const XclImpPictureObj* const pObj = dynamic_cast< const XclImpPictureObj* const >(this);
506 if( pObj != NULL && pObj->IsOcxControl() )
507 {
508 const sal_Int16 nOCXControlType = eCreateFromMSOCXControl;
509 Any aAny;
510 try{
511 aAny <<= nOCXControlType;
512 xPropSet->setPropertyValue(sPropertyName, aAny);
513 //Detail type(checkbox, button ...)
514 aAny<<= mnObjId;
515 xPropSet->setPropertyValue(sObjIdPropertyName, aAny);
516 }catch(...)
517 {
518 OSL_TRACE("XclImpDrawObjBase::CreateSdrObject, this control can't be set the property ObjIDinMSO!");
519 }
520 }
521 }
522
523 }
524 }
525 }
526 return xSdrObj.release();
527 }
528
PreProcessSdrObject(XclImpDffConverter & rDffConv,SdrObject & rSdrObj) const529 void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
530 {
531 // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj()
532 rSdrObj.NbcSetLayer( SC_LAYER_FRONT );
533 SdrModel * pModel = rSdrObj.GetModel();
534 if ( pModel ) {
535 const bool bEnableUndo = pModel->IsUndoEnabled();
536 pModel->EnableUndo(false);
537 // set object name (GetObjName() will always return a non-empty name)
538 rSdrObj.SetName( GetObjName() );
539 pModel->EnableUndo(bEnableUndo);
540 } else
541 rSdrObj.SetName( GetObjName() );
542 // #i39167# full width for all objects regardless of horizontal alignment
543 rSdrObj.SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK ) );
544
545 // automatic text margin
546 if( mbAutoMargin )
547 {
548 sal_Int32 nMargin = rDffConv.GetDefaultTextMargin();
549 rSdrObj.SetMergedItem( SdrTextLeftDistItem( nMargin ) );
550 rSdrObj.SetMergedItem( SdrTextRightDistItem( nMargin ) );
551 rSdrObj.SetMergedItem( SdrTextUpperDistItem( nMargin ) );
552 rSdrObj.SetMergedItem( SdrTextLowerDistItem( nMargin ) );
553 }
554
555 // macro and hyperlink
556 #ifdef ISSUE66550_HLINK_FOR_SHAPES
557 if( mbSimpleMacro && ((maMacroName.Len() > 0) || (maHyperlink.getLength() > 0)) )
558 {
559 if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, sal_True ) )
560 {
561 pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) );
562 pInfo->SetHlink( maHyperlink );
563 }
564 }
565 #else
566 if( mbSimpleMacro && (maMacroName.Len() > 0) )
567 if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, sal_True ) )
568 pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) );
569 #endif
570
571 // call virtual function for object type specific processing
572 DoPreProcessSdrObj( rDffConv, rSdrObj );
573 }
574
PostProcessSdrObject(XclImpDffConverter & rDffConv,SdrObject & rSdrObj) const575 void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
576 {
577 // call virtual function for object type specific processing
578 DoPostProcessSdrObj( rDffConv, rSdrObj );
579 }
580
581 // protected ------------------------------------------------------------------
582
ReadName5(XclImpStream & rStrm,sal_uInt16 nNameLen)583 void XclImpDrawObjBase::ReadName5( XclImpStream& rStrm, sal_uInt16 nNameLen )
584 {
585 maObjName.Erase();
586 if( nNameLen > 0 )
587 {
588 // name length field is repeated before the name
589 maObjName = rStrm.ReadByteString( false );
590 // skip padding byte for word boundaries
591 if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
592 }
593 }
594
ReadMacro3(XclImpStream & rStrm,sal_uInt16 nMacroSize)595 void XclImpDrawObjBase::ReadMacro3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
596 {
597 maMacroName.Erase();
598 rStrm.Ignore( nMacroSize );
599 // skip padding byte for word boundaries, not contained in nMacroSize
600 if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
601 }
602
ReadMacro4(XclImpStream & rStrm,sal_uInt16 nMacroSize)603 void XclImpDrawObjBase::ReadMacro4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
604 {
605 maMacroName.Erase();
606 rStrm.Ignore( nMacroSize );
607 }
608
ReadMacro5(XclImpStream & rStrm,sal_uInt16 nMacroSize)609 void XclImpDrawObjBase::ReadMacro5( XclImpStream& rStrm, sal_uInt16 nMacroSize )
610 {
611 maMacroName.Erase();
612 rStrm.Ignore( nMacroSize );
613 }
614
ReadMacro8(XclImpStream & rStrm)615 void XclImpDrawObjBase::ReadMacro8( XclImpStream& rStrm )
616 {
617 maMacroName.Erase();
618 if( rStrm.GetRecLeft() > 6 )
619 {
620 // macro is stored in a tNameXR token containing a link to a defined name
621 sal_uInt16 nFmlaSize;
622 rStrm >> nFmlaSize;
623 rStrm.Ignore( 4 );
624 DBG_ASSERT( nFmlaSize == 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" );
625 if( nFmlaSize == 7 )
626 {
627 sal_uInt8 nTokenId;
628 sal_uInt16 nExtSheet, nExtName;
629 rStrm >> nTokenId >> nExtSheet >> nExtName;
630 DBG_ASSERT( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ),
631 "XclImpDrawObjBase::ReadMacro - tNameXR token expected" );
632 if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
633 maMacroName = GetLinkManager().GetMacroName( nExtSheet, nExtName );
634 }
635 }
636 }
637
ConvertLineStyle(SdrObject & rSdrObj,const XclObjLineData & rLineData) const638 void XclImpDrawObjBase::ConvertLineStyle( SdrObject& rSdrObj, const XclObjLineData& rLineData ) const
639 {
640 if( rLineData.IsAuto() )
641 {
642 XclObjLineData aAutoData;
643 aAutoData.mnAuto = 0;
644 ConvertLineStyle( rSdrObj, aAutoData );
645 }
646 else
647 {
648 long nLineWidth = 35 * ::std::min( rLineData.mnWidth, EXC_OBJ_LINE_THICK );
649 rSdrObj.SetMergedItem( XLineWidthItem( nLineWidth ) );
650 rSdrObj.SetMergedItem( XLineColorItem( EMPTY_STRING, GetPalette().GetColor( rLineData.mnColorIdx ) ) );
651 rSdrObj.SetMergedItem( XLineJointItem( com::sun::star::drawing::LineJoint_MITER ) );
652
653 sal_uLong nDotLen = ::std::max< sal_uLong >( 70 * rLineData.mnWidth, 35 );
654 sal_uLong nDashLen = 3 * nDotLen;
655 sal_uLong nDist = 2 * nDotLen;
656
657 switch( rLineData.mnStyle )
658 {
659 default:
660 case EXC_OBJ_LINE_SOLID:
661 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
662 break;
663 case EXC_OBJ_LINE_DASH:
664 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
665 rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 0, nDotLen, 1, nDashLen, nDist ) ) );
666 break;
667 case EXC_OBJ_LINE_DOT:
668 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
669 rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 0, nDashLen, nDist ) ) );
670 break;
671 case EXC_OBJ_LINE_DASHDOT:
672 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
673 rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 1, nDotLen, 1, nDashLen, nDist ) ) );
674 break;
675 case EXC_OBJ_LINE_DASHDOTDOT:
676 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_DASH ) );
677 rSdrObj.SetMergedItem( XLineDashItem( EMPTY_STRING, XDash( XDASH_RECT, 2, nDotLen, 1, nDashLen, nDist ) ) );
678 break;
679 case EXC_OBJ_LINE_MEDTRANS:
680 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
681 rSdrObj.SetMergedItem( XLineTransparenceItem( 50 ) );
682 break;
683 case EXC_OBJ_LINE_DARKTRANS:
684 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
685 rSdrObj.SetMergedItem( XLineTransparenceItem( 25 ) );
686 break;
687 case EXC_OBJ_LINE_LIGHTTRANS:
688 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_SOLID ) );
689 rSdrObj.SetMergedItem( XLineTransparenceItem( 75 ) );
690 break;
691 case EXC_OBJ_LINE_NONE:
692 rSdrObj.SetMergedItem( XLineStyleItem( XLINE_NONE ) );
693 break;
694 }
695 }
696 }
697
ConvertFillStyle(SdrObject & rSdrObj,const XclObjFillData & rFillData) const698 void XclImpDrawObjBase::ConvertFillStyle( SdrObject& rSdrObj, const XclObjFillData& rFillData ) const
699 {
700 if( rFillData.IsAuto() )
701 {
702 XclObjFillData aAutoData;
703 aAutoData.mnAuto = 0;
704 ConvertFillStyle( rSdrObj, aAutoData );
705 }
706 else if( rFillData.mnPattern == EXC_PATT_NONE )
707 {
708 rSdrObj.SetMergedItem( XFillStyleItem( XFILL_NONE ) );
709 }
710 else
711 {
712 Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx );
713 Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx );
714 if( (rFillData.mnPattern == EXC_PATT_SOLID) || (aPattColor == aBackColor) )
715 {
716 rSdrObj.SetMergedItem( XFillStyleItem( XFILL_SOLID ) );
717 rSdrObj.SetMergedItem( XFillColorItem( EMPTY_STRING, aPattColor ) );
718 }
719 else
720 {
721 static const sal_uInt8 sppnPatterns[][ 8 ] =
722 {
723 { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
724 { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
725 { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
726 { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
727 { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
728 { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
729 { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
730 { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
731 { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
732 { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
733 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
734 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
735 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
736 { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
737 { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
738 { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
739 { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
740 };
741 const sal_uInt8* const pnPattern = sppnPatterns[ ::std::min< size_t >( rFillData.mnPattern - 2, STATIC_ARRAY_SIZE( sppnPatterns ) ) ];
742 // create 2-colored 8x8 DIB
743 SvMemoryStream aMemStrm;
744 aMemStrm << sal_uInt32( 12 ) << sal_Int16( 8 ) << sal_Int16( 8 ) << sal_uInt16( 1 ) << sal_uInt16( 1 );
745 aMemStrm << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF ) << sal_uInt8( 0xFF );
746 aMemStrm << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 ) << sal_uInt8( 0x00 );
747 for( size_t nIdx = 0; nIdx < 8; ++nIdx )
748 aMemStrm << sal_uInt32( pnPattern[ nIdx ] ); // 32-bit little-endian
749 aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
750 Bitmap aBitmap;
751 ReadDIB(aBitmap, aMemStrm, false);
752 rSdrObj.SetMergedItem(XFillStyleItem(XFILL_BITMAP));
753 rSdrObj.SetMergedItem(XFillBitmapItem(EMPTY_STRING, Graphic(aBitmap)));
754 }
755 }
756 }
757
ConvertFrameStyle(SdrObject & rSdrObj,sal_uInt16 nFrameFlags) const758 void XclImpDrawObjBase::ConvertFrameStyle( SdrObject& rSdrObj, sal_uInt16 nFrameFlags ) const
759 {
760 if( ::get_flag( nFrameFlags, EXC_OBJ_FRAME_SHADOW ) )
761 {
762 rSdrObj.SetMergedItem( SdrShadowItem( sal_True ) );
763 rSdrObj.SetMergedItem( SdrShadowXDistItem( 35 ) );
764 rSdrObj.SetMergedItem( SdrShadowYDistItem( 35 ) );
765 rSdrObj.SetMergedItem( SdrShadowColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWTEXT ) ) );
766 }
767 }
768
GetSolidLineColor(const XclObjLineData & rLineData) const769 Color XclImpDrawObjBase::GetSolidLineColor( const XclObjLineData& rLineData ) const
770 {
771 Color aColor( COL_TRANSPARENT );
772 if( rLineData.IsAuto() )
773 {
774 XclObjLineData aAutoData;
775 aAutoData.mnAuto = 0;
776 aColor = GetSolidLineColor( aAutoData );
777 }
778 else if( rLineData.mnStyle != EXC_OBJ_LINE_NONE )
779 {
780 aColor = GetPalette().GetColor( rLineData.mnColorIdx );
781 }
782 return aColor;
783 }
784
GetSolidFillColor(const XclObjFillData & rFillData) const785 Color XclImpDrawObjBase::GetSolidFillColor( const XclObjFillData& rFillData ) const
786 {
787 Color aColor( COL_TRANSPARENT );
788 if( rFillData.IsAuto() )
789 {
790 XclObjFillData aAutoData;
791 aAutoData.mnAuto = 0;
792 aColor = GetSolidFillColor( aAutoData );
793 }
794 else if( rFillData.mnPattern != EXC_PATT_NONE )
795 {
796 Color aPattColor = GetPalette().GetColor( rFillData.mnPattColorIdx );
797 Color aBackColor = GetPalette().GetColor( rFillData.mnBackColorIdx );
798 aColor = XclTools::GetPatternColor( aPattColor, aBackColor, rFillData.mnPattern );
799 }
800 return aColor;
801 }
802
DoReadObj3(XclImpStream &,sal_uInt16)803 void XclImpDrawObjBase::DoReadObj3( XclImpStream&, sal_uInt16 )
804 {
805 }
806
DoReadObj4(XclImpStream &,sal_uInt16)807 void XclImpDrawObjBase::DoReadObj4( XclImpStream&, sal_uInt16 )
808 {
809 }
810
DoReadObj5(XclImpStream &,sal_uInt16,sal_uInt16)811 void XclImpDrawObjBase::DoReadObj5( XclImpStream&, sal_uInt16, sal_uInt16 )
812 {
813 }
814
DoReadObj8SubRec(XclImpStream &,sal_uInt16,sal_uInt16)815 void XclImpDrawObjBase::DoReadObj8SubRec( XclImpStream&, sal_uInt16, sal_uInt16 )
816 {
817 }
818
DoGetProgressSize() const819 sal_Size XclImpDrawObjBase::DoGetProgressSize() const
820 {
821 return 1;
822 }
823
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle &) const824 SdrObject* XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& ) const
825 {
826 rDffConv.Progress( GetProgressSize() );
827 return 0;
828 }
829
DoPreProcessSdrObj(XclImpDffConverter &,SdrObject &) const830 void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter&, SdrObject& ) const
831 {
832 // trace if object is not printable
833 if( !IsPrintable() )
834 GetTracer().TraceObjectNotPrintable();
835 }
836
DoPostProcessSdrObj(XclImpDffConverter &,SdrObject &) const837 void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter&, SdrObject& ) const
838 {
839 }
840
ImplReadObj3(XclImpStream & rStrm)841 void XclImpDrawObjBase::ImplReadObj3( XclImpStream& rStrm )
842 {
843 // back to offset 4 (ignore object count field)
844 rStrm.Seek( 4 );
845
846 sal_uInt16 nObjFlags, nMacroSize;
847 rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
848 rStrm.Ignore( 2 );
849
850 mbHasAnchor = true;
851 mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
852 mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
853 DoReadObj3( rStrm, nMacroSize );
854 }
855
ImplReadObj4(XclImpStream & rStrm)856 void XclImpDrawObjBase::ImplReadObj4( XclImpStream& rStrm )
857 {
858 // back to offset 4 (ignore object count field)
859 rStrm.Seek( 4 );
860
861 sal_uInt16 nObjFlags, nMacroSize;
862 rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
863 rStrm.Ignore( 2 );
864
865 mbHasAnchor = true;
866 mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
867 mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
868 mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE );
869 DoReadObj4( rStrm, nMacroSize );
870 }
871
ImplReadObj5(XclImpStream & rStrm)872 void XclImpDrawObjBase::ImplReadObj5( XclImpStream& rStrm )
873 {
874 // back to offset 4 (ignore object count field)
875 rStrm.Seek( 4 );
876
877 sal_uInt16 nObjFlags, nMacroSize, nNameLen;
878 rStrm >> mnObjType >> mnObjId >> nObjFlags >> maAnchor >> nMacroSize;
879 rStrm.Ignore( 2 );
880 rStrm >> nNameLen;
881 rStrm.Ignore( 2 );
882
883 mbHasAnchor = true;
884 mbHidden = ::get_flag( nObjFlags, EXC_OBJ_HIDDEN );
885 mbVisible = ::get_flag( nObjFlags, EXC_OBJ_VISIBLE );
886 mbPrintable = ::get_flag( nObjFlags, EXC_OBJ_PRINTABLE );
887 DoReadObj5( rStrm, nNameLen, nMacroSize );
888 }
889
ImplReadObj8(XclImpStream & rStrm)890 void XclImpDrawObjBase::ImplReadObj8( XclImpStream& rStrm )
891 {
892 // back to beginning
893 rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
894
895 bool bLoop = true;
896 while( bLoop && (rStrm.GetRecLeft() >= 4) )
897 {
898 sal_uInt16 nSubRecId, nSubRecSize;
899 rStrm >> nSubRecId >> nSubRecSize;
900 rStrm.PushPosition();
901 // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
902 nSubRecSize = static_cast< sal_uInt16 >( ::std::min< sal_Size >( nSubRecSize, rStrm.GetRecLeft() ) );
903
904 switch( nSubRecId )
905 {
906 case EXC_ID_OBJCMO:
907 DBG_ASSERT( rStrm.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" );
908 if( (rStrm.GetRecPos() == 4) && (nSubRecSize >= 6) )
909 {
910 sal_uInt16 nObjFlags;
911 rStrm >> mnObjType >> mnObjId >> nObjFlags;
912 mbPrintable = ::get_flag( nObjFlags, EXC_OBJCMO_PRINTABLE );
913 }
914 break;
915 case EXC_ID_OBJMACRO:
916 ReadMacro8( rStrm );
917 break;
918 case EXC_ID_OBJEND:
919 bLoop = false;
920 break;
921 default:
922 DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
923 }
924
925 rStrm.PopPosition();
926 rStrm.Ignore( nSubRecSize );
927 }
928
929 /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream
930 processing (e.g. charts), even if the OBJEND subrecord is missing. */
931 DoReadObj8SubRec( rStrm, EXC_ID_OBJEND, 0 );
932
933 /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
934 IMGDATA record following the OBJ record (but they use the image data
935 stored in DFF). The IMGDATA record may be continued by several CONTINUE
936 records. But the last CONTINUE record may be in fact an MSODRAWING
937 record that contains the DFF data of the next drawing object! So we
938 have to skip just enough CONTINUE records to look at the next
939 MSODRAWING/CONTINUE record. */
940 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
941 {
942 sal_uInt32 nDataSize;
943 rStrm.Ignore( 4 );
944 rStrm >> nDataSize;
945 nDataSize -= rStrm.GetRecLeft();
946 // skip following CONTINUE records until IMGDATA ends
947 while( (nDataSize > 0) && (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord() )
948 {
949 DBG_ASSERT( nDataSize >= rStrm.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" );
950 nDataSize -= ::std::min< sal_uInt32 >( rStrm.GetRecLeft(), nDataSize );
951 }
952 DBG_ASSERT( nDataSize == 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" );
953 // next record may be MSODRAWING or CONTINUE or anything else
954 }
955 }
956
957 // ----------------------------------------------------------------------------
958
InsertGrouped(XclImpDrawObjRef xDrawObj)959 void XclImpDrawObjVector::InsertGrouped( XclImpDrawObjRef xDrawObj )
960 {
961 if( !empty() )
962 if( XclImpGroupObj* pGroupObj = dynamic_cast< XclImpGroupObj* >( back().get() ) )
963 if( pGroupObj->TryInsert( xDrawObj ) )
964 return;
965 push_back( xDrawObj );
966 }
967
GetProgressSize() const968 sal_Size XclImpDrawObjVector::GetProgressSize() const
969 {
970 sal_Size nProgressSize = 0;
971 for( const_iterator aIt = begin(), aEnd = end(); aIt != aEnd; ++aIt )
972 nProgressSize += (*aIt)->GetProgressSize();
973 return nProgressSize;
974 }
975
976 // ----------------------------------------------------------------------------
977
XclImpPhObj(const XclImpRoot & rRoot)978 XclImpPhObj::XclImpPhObj( const XclImpRoot& rRoot ) :
979 XclImpDrawObjBase( rRoot )
980 {
981 SetProcessSdrObj( false );
982 }
983
984 // ----------------------------------------------------------------------------
985
XclImpGroupObj(const XclImpRoot & rRoot)986 XclImpGroupObj::XclImpGroupObj( const XclImpRoot& rRoot ) :
987 XclImpDrawObjBase( rRoot ),
988 mnFirstUngrouped( 0 )
989 {
990 }
991
TryInsert(XclImpDrawObjRef xDrawObj)992 bool XclImpGroupObj::TryInsert( XclImpDrawObjRef xDrawObj )
993 {
994 if( xDrawObj->GetObjId() == mnFirstUngrouped )
995 return false;
996 // insert into own list or into nested group
997 maChildren.InsertGrouped( xDrawObj );
998 return true;
999 }
1000
DoReadObj3(XclImpStream & rStrm,sal_uInt16 nMacroSize)1001 void XclImpGroupObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1002 {
1003 rStrm.Ignore( 4 );
1004 rStrm >> mnFirstUngrouped;
1005 rStrm.Ignore( 16 );
1006 ReadMacro3( rStrm, nMacroSize );
1007 }
1008
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)1009 void XclImpGroupObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1010 {
1011 rStrm.Ignore( 4 );
1012 rStrm >> mnFirstUngrouped;
1013 rStrm.Ignore( 16 );
1014 ReadMacro4( rStrm, nMacroSize );
1015 }
1016
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)1017 void XclImpGroupObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1018 {
1019 rStrm.Ignore( 4 );
1020 rStrm >> mnFirstUngrouped;
1021 rStrm.Ignore( 16 );
1022 ReadName5( rStrm, nNameLen );
1023 ReadMacro5( rStrm, nMacroSize );
1024 }
1025
DoGetProgressSize() const1026 sal_Size XclImpGroupObj::DoGetProgressSize() const
1027 {
1028 return XclImpDrawObjBase::DoGetProgressSize() + maChildren.GetProgressSize();
1029 }
1030
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle &) const1031 SdrObject* XclImpGroupObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& /*rAnchorRect*/ ) const
1032 {
1033 TSdrObjectPtr< SdrObjGroup > xSdrObj( new SdrObjGroup );
1034 // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle
1035 SdrObjList& rObjList = *xSdrObj->GetSubList(); // SdrObjGroup always returns existing sublist
1036 for( XclImpDrawObjVector::const_iterator aIt = maChildren.begin(), aEnd = maChildren.end(); aIt != aEnd; ++aIt )
1037 rDffConv.ProcessObject( rObjList, **aIt );
1038 rDffConv.Progress();
1039 return xSdrObj.release();
1040 }
1041
1042 // ----------------------------------------------------------------------------
1043
XclImpLineObj(const XclImpRoot & rRoot)1044 XclImpLineObj::XclImpLineObj( const XclImpRoot& rRoot ) :
1045 XclImpDrawObjBase( rRoot ),
1046 mnArrows( 0 ),
1047 mnStartPoint( EXC_OBJ_LINE_TL )
1048 {
1049 SetAreaObj( false );
1050 }
1051
DoReadObj3(XclImpStream & rStrm,sal_uInt16 nMacroSize)1052 void XclImpLineObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1053 {
1054 rStrm >> maLineData >> mnArrows >> mnStartPoint;
1055 rStrm.Ignore( 1 );
1056 ReadMacro3( rStrm, nMacroSize );
1057 }
1058
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)1059 void XclImpLineObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1060 {
1061 rStrm >> maLineData >> mnArrows >> mnStartPoint;
1062 rStrm.Ignore( 1 );
1063 ReadMacro4( rStrm, nMacroSize );
1064 }
1065
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)1066 void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1067 {
1068 rStrm >> maLineData >> mnArrows >> mnStartPoint;
1069 rStrm.Ignore( 1 );
1070 ReadName5( rStrm, nNameLen );
1071 ReadMacro5( rStrm, nMacroSize );
1072 }
1073
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const1074 SdrObject* XclImpLineObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
1075 {
1076 ::basegfx::B2DPolygon aB2DPolygon;
1077 switch( mnStartPoint )
1078 {
1079 default:
1080 case EXC_OBJ_LINE_TL:
1081 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
1082 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
1083 break;
1084 case EXC_OBJ_LINE_TR:
1085 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
1086 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
1087 break;
1088 case EXC_OBJ_LINE_BR:
1089 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
1090 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
1091 break;
1092 case EXC_OBJ_LINE_BL:
1093 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
1094 aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
1095 break;
1096 }
1097 SdrObjectPtr xSdrObj( new SdrPathObj( OBJ_LINE, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) );
1098 ConvertLineStyle( *xSdrObj, maLineData );
1099
1100 // line ends
1101 sal_uInt8 nArrowType = ::extract_value< sal_uInt8 >( mnArrows, 0, 4 );
1102 bool bLineStart = false;
1103 bool bLineEnd = false;
1104 bool bFilled = false;
1105 switch( nArrowType )
1106 {
1107 case EXC_OBJ_ARROW_OPEN: bLineStart = false; bLineEnd = true; bFilled = false; break;
1108 case EXC_OBJ_ARROW_OPENBOTH: bLineStart = true; bLineEnd = true; bFilled = false; break;
1109 case EXC_OBJ_ARROW_FILLED: bLineStart = false; bLineEnd = true; bFilled = true; break;
1110 case EXC_OBJ_ARROW_FILLEDBOTH: bLineStart = true; bLineEnd = true; bFilled = true; break;
1111 }
1112 if( bLineStart || bLineEnd )
1113 {
1114 sal_uInt8 nArrowWidth = ::extract_value< sal_uInt8 >( mnArrows, 4, 4 );
1115 double fArrowWidth = 3.0;
1116 switch( nArrowWidth )
1117 {
1118 case EXC_OBJ_ARROW_NARROW: fArrowWidth = 2.0; break;
1119 case EXC_OBJ_ARROW_MEDIUM: fArrowWidth = 3.0; break;
1120 case EXC_OBJ_ARROW_WIDE: fArrowWidth = 5.0; break;
1121 }
1122
1123 sal_uInt8 nArrowLength = ::extract_value< sal_uInt8 >( mnArrows, 8, 4 );
1124 double fArrowLength = 3.0;
1125 switch( nArrowLength )
1126 {
1127 case EXC_OBJ_ARROW_NARROW: fArrowLength = 2.5; break;
1128 case EXC_OBJ_ARROW_MEDIUM: fArrowLength = 3.5; break;
1129 case EXC_OBJ_ARROW_WIDE: fArrowLength = 6.0; break;
1130 }
1131
1132 ::basegfx::B2DPolygon aArrowPoly;
1133 #define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) )
1134 if( bFilled )
1135 {
1136 aArrowPoly.append( EXC_ARROW_POINT( 0, 100 ) );
1137 aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
1138 aArrowPoly.append( EXC_ARROW_POINT( 100, 100 ) );
1139 }
1140 else
1141 {
1142 sal_uInt8 nLineWidth = ::limit_cast< sal_uInt8 >( maLineData.mnWidth, EXC_OBJ_LINE_THIN, EXC_OBJ_LINE_THICK );
1143 aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
1144 aArrowPoly.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth ) );
1145 aArrowPoly.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth, 100 ) );
1146 aArrowPoly.append( EXC_ARROW_POINT( 50, 12 * nLineWidth ) );
1147 aArrowPoly.append( EXC_ARROW_POINT( 5 * nLineWidth, 100 ) );
1148 aArrowPoly.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth ) );
1149 }
1150 #undef EXC_ARROW_POINT
1151
1152 ::basegfx::B2DPolyPolygon aArrowPolyPoly( aArrowPoly );
1153 long nWidth = static_cast< long >( 125 * fArrowWidth );
1154 if( bLineStart )
1155 {
1156 xSdrObj->SetMergedItem( XLineStartItem( EMPTY_STRING, aArrowPolyPoly ) );
1157 xSdrObj->SetMergedItem( XLineStartWidthItem( nWidth ) );
1158 xSdrObj->SetMergedItem( XLineStartCenterItem( sal_False ) );
1159 }
1160 if( bLineEnd )
1161 {
1162 xSdrObj->SetMergedItem( XLineEndItem( EMPTY_STRING, aArrowPolyPoly ) );
1163 xSdrObj->SetMergedItem( XLineEndWidthItem( nWidth ) );
1164 xSdrObj->SetMergedItem( XLineEndCenterItem( sal_False ) );
1165 }
1166 }
1167 rDffConv.Progress();
1168 return xSdrObj.release();
1169 }
1170
1171 // ----------------------------------------------------------------------------
1172
XclImpRectObj(const XclImpRoot & rRoot)1173 XclImpRectObj::XclImpRectObj( const XclImpRoot& rRoot ) :
1174 XclImpDrawObjBase( rRoot ),
1175 mnFrameFlags( 0 )
1176 {
1177 SetAreaObj( true );
1178 }
1179
ReadFrameData(XclImpStream & rStrm)1180 void XclImpRectObj::ReadFrameData( XclImpStream& rStrm )
1181 {
1182 rStrm >> maFillData >> maLineData >> mnFrameFlags;
1183 }
1184
ConvertRectStyle(SdrObject & rSdrObj) const1185 void XclImpRectObj::ConvertRectStyle( SdrObject& rSdrObj ) const
1186 {
1187 ConvertLineStyle( rSdrObj, maLineData );
1188 ConvertFillStyle( rSdrObj, maFillData );
1189 ConvertFrameStyle( rSdrObj, mnFrameFlags );
1190 }
1191
DoReadObj3(XclImpStream & rStrm,sal_uInt16 nMacroSize)1192 void XclImpRectObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1193 {
1194 ReadFrameData( rStrm );
1195 ReadMacro3( rStrm, nMacroSize );
1196 }
1197
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)1198 void XclImpRectObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1199 {
1200 ReadFrameData( rStrm );
1201 ReadMacro4( rStrm, nMacroSize );
1202 }
1203
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)1204 void XclImpRectObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1205 {
1206 ReadFrameData( rStrm );
1207 ReadName5( rStrm, nNameLen );
1208 ReadMacro5( rStrm, nMacroSize );
1209 }
1210
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const1211 SdrObject* XclImpRectObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
1212 {
1213 SdrObjectPtr xSdrObj( new SdrRectObj( rAnchorRect ) );
1214 ConvertRectStyle( *xSdrObj );
1215 rDffConv.Progress();
1216 return xSdrObj.release();
1217 }
1218
1219 // ----------------------------------------------------------------------------
1220
XclImpOvalObj(const XclImpRoot & rRoot)1221 XclImpOvalObj::XclImpOvalObj( const XclImpRoot& rRoot ) :
1222 XclImpRectObj( rRoot )
1223 {
1224 }
1225
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const1226 SdrObject* XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
1227 {
1228 SdrObjectPtr xSdrObj( new SdrCircObj( OBJ_CIRC, rAnchorRect ) );
1229 ConvertRectStyle( *xSdrObj );
1230 rDffConv.Progress();
1231 return xSdrObj.release();
1232 }
1233
1234 // ----------------------------------------------------------------------------
1235
XclImpArcObj(const XclImpRoot & rRoot)1236 XclImpArcObj::XclImpArcObj( const XclImpRoot& rRoot ) :
1237 XclImpDrawObjBase( rRoot ),
1238 mnQuadrant( EXC_OBJ_ARC_TR )
1239 {
1240 SetAreaObj( false ); // arc may be 2-dimensional
1241 }
1242
DoReadObj3(XclImpStream & rStrm,sal_uInt16 nMacroSize)1243 void XclImpArcObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1244 {
1245 rStrm >> maFillData >> maLineData >> mnQuadrant;
1246 rStrm.Ignore( 1 );
1247 ReadMacro3( rStrm, nMacroSize );
1248 }
1249
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)1250 void XclImpArcObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1251 {
1252 rStrm >> maFillData >> maLineData >> mnQuadrant;
1253 rStrm.Ignore( 1 );
1254 ReadMacro4( rStrm, nMacroSize );
1255 }
1256
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)1257 void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1258 {
1259 rStrm >> maFillData >> maLineData >> mnQuadrant;
1260 rStrm.Ignore( 1 );
1261 ReadName5( rStrm, nNameLen );
1262 ReadMacro5( rStrm, nMacroSize );
1263 }
1264
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const1265 SdrObject* XclImpArcObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
1266 {
1267 Rectangle aNewRect = rAnchorRect;
1268 long nStartAngle = 0;
1269 long nEndAngle = 0;
1270 switch( mnQuadrant )
1271 {
1272 default:
1273 case EXC_OBJ_ARC_TR:
1274 nStartAngle = 0;
1275 nEndAngle = 9000;
1276 aNewRect.Left() -= rAnchorRect.GetWidth();
1277 aNewRect.Bottom() += rAnchorRect.GetHeight();
1278 break;
1279 case EXC_OBJ_ARC_TL:
1280 nStartAngle = 9000;
1281 nEndAngle = 18000;
1282 aNewRect.Right() += rAnchorRect.GetWidth();
1283 aNewRect.Bottom() += rAnchorRect.GetHeight();
1284 break;
1285 case EXC_OBJ_ARC_BL:
1286 nStartAngle = 18000;
1287 nEndAngle = 27000;
1288 aNewRect.Right() += rAnchorRect.GetWidth();
1289 aNewRect.Top() -= rAnchorRect.GetHeight();
1290 break;
1291 case EXC_OBJ_ARC_BR:
1292 nStartAngle = 27000;
1293 nEndAngle = 0;
1294 aNewRect.Left() -= rAnchorRect.GetWidth();
1295 aNewRect.Top() -= rAnchorRect.GetHeight();
1296 break;
1297 }
1298 SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_SECT : OBJ_CARC;
1299 SdrObjectPtr xSdrObj( new SdrCircObj( eObjKind, aNewRect, nStartAngle, nEndAngle ) );
1300 ConvertFillStyle( *xSdrObj, maFillData );
1301 ConvertLineStyle( *xSdrObj, maLineData );
1302 rDffConv.Progress();
1303 return xSdrObj.release();
1304 }
1305
1306 // ----------------------------------------------------------------------------
1307
XclImpPolygonObj(const XclImpRoot & rRoot)1308 XclImpPolygonObj::XclImpPolygonObj( const XclImpRoot& rRoot ) :
1309 XclImpRectObj( rRoot ),
1310 mnPolyFlags( 0 ),
1311 mnPointCount( 0 )
1312 {
1313 SetAreaObj( false ); // polygon may be 2-dimensional
1314 }
1315
ReadCoordList(XclImpStream & rStrm)1316 void XclImpPolygonObj::ReadCoordList( XclImpStream& rStrm )
1317 {
1318 if( (rStrm.GetNextRecId() == EXC_ID_COORDLIST) && rStrm.StartNextRecord() )
1319 {
1320 DBG_ASSERT( rStrm.GetRecLeft() / 4 == mnPointCount, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" );
1321 while( rStrm.GetRecLeft() >= 4 )
1322 {
1323 sal_uInt16 nX, nY;
1324 rStrm >> nX >> nY;
1325 maCoords.push_back( Point( nX, nY ) );
1326 }
1327 }
1328 }
1329
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)1330 void XclImpPolygonObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1331 {
1332 ReadFrameData( rStrm );
1333 rStrm >> mnPolyFlags;
1334 rStrm.Ignore( 10 );
1335 rStrm >> mnPointCount;
1336 rStrm.Ignore( 8 );
1337 ReadMacro4( rStrm, nMacroSize );
1338 ReadCoordList( rStrm );
1339 }
1340
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)1341 void XclImpPolygonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1342 {
1343 ReadFrameData( rStrm );
1344 rStrm >> mnPolyFlags;
1345 rStrm.Ignore( 10 );
1346 rStrm >> mnPointCount;
1347 rStrm.Ignore( 8 );
1348 ReadName5( rStrm, nNameLen );
1349 ReadMacro5( rStrm, nMacroSize );
1350 ReadCoordList( rStrm );
1351 }
1352
1353 namespace {
1354
lclGetPolyPoint(const Rectangle & rAnchorRect,const Point & rPoint)1355 ::basegfx::B2DPoint lclGetPolyPoint( const Rectangle& rAnchorRect, const Point& rPoint )
1356 {
1357 return ::basegfx::B2DPoint(
1358 rAnchorRect.Left() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.X(), 16384.0 ) / 16384.0 * rAnchorRect.GetWidth() + 0.5 ),
1359 rAnchorRect.Top() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.Y(), 16384.0 ) / 16384.0 * rAnchorRect.GetHeight() + 0.5 ) );
1360 }
1361
1362 } // namespace
1363
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const1364 SdrObject* XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
1365 {
1366 SdrObjectPtr xSdrObj;
1367 if( maCoords.size() >= 2 )
1368 {
1369 // create the polygon
1370 ::basegfx::B2DPolygon aB2DPolygon;
1371 for( PointVector::const_iterator aIt = maCoords.begin(), aEnd = maCoords.end(); aIt != aEnd; ++aIt )
1372 aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, *aIt ) );
1373 // close polygon if specified
1374 if( ::get_flag( mnPolyFlags, EXC_OBJ_POLY_CLOSED ) && (maCoords.front() != maCoords.back()) )
1375 aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, maCoords.front() ) );
1376 // create the SdrObject
1377 SdrObjKind eObjKind = maFillData.IsFilled() ? OBJ_PATHPOLY : OBJ_PATHPLIN;
1378 xSdrObj.reset( new SdrPathObj( eObjKind, ::basegfx::B2DPolyPolygon( aB2DPolygon ) ) );
1379 ConvertRectStyle( *xSdrObj );
1380 }
1381 rDffConv.Progress();
1382 return xSdrObj.release();
1383 }
1384
1385 // ----------------------------------------------------------------------------
1386
ReadByteString(XclImpStream & rStrm)1387 void XclImpObjTextData::ReadByteString( XclImpStream& rStrm )
1388 {
1389 mxString.reset();
1390 if( maData.mnTextLen > 0 )
1391 {
1392 mxString.reset( new XclImpString( rStrm.ReadRawByteString( maData.mnTextLen ) ) );
1393 // skip padding byte for word boundaries
1394 if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
1395 }
1396 }
1397
ReadFormats(XclImpStream & rStrm)1398 void XclImpObjTextData::ReadFormats( XclImpStream& rStrm )
1399 {
1400 if( mxString.is() )
1401 mxString->ReadObjFormats( rStrm, maData.mnFormatSize );
1402 else
1403 rStrm.Ignore( maData.mnFormatSize );
1404 }
1405
1406 // ----------------------------------------------------------------------------
1407
XclImpTextObj(const XclImpRoot & rRoot)1408 XclImpTextObj::XclImpTextObj( const XclImpRoot& rRoot ) :
1409 XclImpRectObj( rRoot )
1410 {
1411 }
1412
DoReadObj3(XclImpStream & rStrm,sal_uInt16 nMacroSize)1413 void XclImpTextObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1414 {
1415 ReadFrameData( rStrm );
1416 maTextData.maData.ReadObj3( rStrm );
1417 ReadMacro3( rStrm, nMacroSize );
1418 maTextData.ReadByteString( rStrm );
1419 maTextData.ReadFormats( rStrm );
1420 }
1421
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)1422 void XclImpTextObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1423 {
1424 ReadFrameData( rStrm );
1425 maTextData.maData.ReadObj3( rStrm );
1426 ReadMacro4( rStrm, nMacroSize );
1427 maTextData.ReadByteString( rStrm );
1428 maTextData.ReadFormats( rStrm );
1429 }
1430
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)1431 void XclImpTextObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1432 {
1433 ReadFrameData( rStrm );
1434 maTextData.maData.ReadObj5( rStrm );
1435 ReadName5( rStrm, nNameLen );
1436 ReadMacro5( rStrm, nMacroSize );
1437 maTextData.ReadByteString( rStrm );
1438 rStrm.Ignore( maTextData.maData.mnLinkSize ); // ignore text link formula
1439 maTextData.ReadFormats( rStrm );
1440 }
1441
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const1442 SdrObject* XclImpTextObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
1443 {
1444 TSdrObjectPtr< SdrObjCustomShape > xSdrObj( new SdrObjCustomShape );
1445 xSdrObj->NbcSetSnapRect( rAnchorRect );
1446 OUString aRectType = CREATE_OUSTRING( "rectangle" );
1447 xSdrObj->MergeDefaultAttributes( &aRectType );
1448 ConvertRectStyle( *xSdrObj );
1449 sal_Bool bAutoSize = ::get_flag( maTextData.maData.mnFlags, EXC_OBJ_TEXT_AUTOSIZE );
1450 xSdrObj->SetMergedItem( SdrTextAutoGrowWidthItem( bAutoSize ) );
1451 xSdrObj->SetMergedItem( SdrTextAutoGrowHeightItem( bAutoSize ) );
1452 xSdrObj->SetMergedItem( SdrTextWordWrapItem( sal_True ) );
1453 rDffConv.Progress();
1454 return xSdrObj.release();
1455 }
1456
DoPreProcessSdrObj(XclImpDffConverter & rDffConv,SdrObject & rSdrObj) const1457 void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
1458 {
1459 // set text data
1460 if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) )
1461 {
1462 if( maTextData.mxString.is() )
1463 {
1464 if( maTextData.mxString->IsRich() )
1465 {
1466 // rich text
1467 ::std::auto_ptr< EditTextObject > xEditObj(
1468 XclImpStringHelper::CreateTextObject( GetRoot(), *maTextData.mxString ) );
1469 OutlinerParaObject* pOutlineObj = new OutlinerParaObject( *xEditObj );
1470 pOutlineObj->SetOutlinerMode( OUTLINERMODE_TEXTOBJECT );
1471 // text object takes ownership of the outliner object
1472 pTextObj->NbcSetOutlinerParaObject( pOutlineObj );
1473 }
1474 else
1475 {
1476 // plain text
1477 pTextObj->NbcSetText( maTextData.mxString->GetText() );
1478 }
1479
1480 /* #i96858# Do not apply any formatting if there is no text.
1481 SdrObjCustomShape::SetVerticalWriting (initiated from
1482 SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which
1483 ensures that we can erroneously write a ClientTextbox record
1484 (with no content) while exporting to XLS, which can cause a
1485 corrupted exported document. */
1486
1487 SvxAdjust eHorAlign = SVX_ADJUST_LEFT;
1488 SdrTextVertAdjust eVerAlign = SDRTEXTVERTADJUST_TOP;
1489
1490 // orientation (this is only a fake, drawing does not support real text orientation)
1491 namespace csst = ::com::sun::star::text;
1492 csst::WritingMode eWriteMode = csst::WritingMode_LR_TB;
1493 switch( maTextData.maData.mnOrient )
1494 {
1495 default:
1496 case EXC_OBJ_ORIENT_NONE:
1497 {
1498 eWriteMode = csst::WritingMode_LR_TB;
1499 switch( maTextData.maData.GetHorAlign() )
1500 {
1501 case EXC_OBJ_HOR_LEFT: eHorAlign = SVX_ADJUST_LEFT; break;
1502 case EXC_OBJ_HOR_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
1503 case EXC_OBJ_HOR_RIGHT: eHorAlign = SVX_ADJUST_RIGHT; break;
1504 case EXC_OBJ_HOR_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
1505 }
1506 switch( maTextData.maData.GetVerAlign() )
1507 {
1508 case EXC_OBJ_VER_TOP: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
1509 case EXC_OBJ_VER_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
1510 case EXC_OBJ_VER_BOTTOM: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
1511 case EXC_OBJ_VER_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
1512 }
1513 }
1514 break;
1515
1516 case EXC_OBJ_ORIENT_90CCW:
1517 {
1518 if( SdrObjCustomShape* pObjCustomShape = dynamic_cast< SdrObjCustomShape* >( &rSdrObj ) )
1519 {
1520 double fAngle = 180.0;
1521 com::sun::star::beans::PropertyValue aTextRotateAngle;
1522 aTextRotateAngle.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
1523 aTextRotateAngle.Value <<= fAngle;
1524 SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)pObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
1525 aGeometryItem.SetPropertyValue( aTextRotateAngle );
1526 pObjCustomShape->SetMergedItem( aGeometryItem );
1527 }
1528 eWriteMode = csst::WritingMode_TB_RL;
1529 switch( maTextData.maData.GetHorAlign() )
1530 {
1531 case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
1532 case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
1533 case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
1534 case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
1535 }
1536 MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
1537 switch( eTextAnchor )
1538 {
1539 case mso_anchorTopCentered :
1540 case mso_anchorMiddleCentered :
1541 case mso_anchorBottomCentered :
1542 {
1543 eHorAlign = SVX_ADJUST_CENTER;
1544 }
1545 break;
1546
1547 default:
1548 {
1549 switch( maTextData.maData.GetVerAlign() )
1550 {
1551 case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_RIGHT; break;
1552 case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
1553 case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_LEFT; break;
1554 case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
1555 }
1556 }
1557 }
1558 }
1559 break;
1560
1561 case EXC_OBJ_ORIENT_STACKED: // PASSTHROUGH INTENDED
1562 {
1563 // sj: STACKED is not supported, maybe it can be optimized here a bit
1564 }
1565 case EXC_OBJ_ORIENT_90CW:
1566 {
1567 eWriteMode = csst::WritingMode_TB_RL;
1568 switch( maTextData.maData.GetHorAlign() )
1569 {
1570 case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
1571 case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
1572 case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
1573 case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
1574 }
1575 MSO_Anchor eTextAnchor = (MSO_Anchor)rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
1576 switch ( eTextAnchor )
1577 {
1578 case mso_anchorTopCentered :
1579 case mso_anchorMiddleCentered :
1580 case mso_anchorBottomCentered :
1581 {
1582 eHorAlign = SVX_ADJUST_CENTER;
1583 }
1584 break;
1585
1586 default:
1587 {
1588 switch( maTextData.maData.GetVerAlign() )
1589 {
1590 case EXC_OBJ_VER_TOP: eHorAlign = SVX_ADJUST_LEFT; break;
1591 case EXC_OBJ_VER_CENTER: eHorAlign = SVX_ADJUST_CENTER; break;
1592 case EXC_OBJ_VER_BOTTOM: eHorAlign = SVX_ADJUST_RIGHT; break;
1593 case EXC_OBJ_VER_JUSTIFY: eHorAlign = SVX_ADJUST_BLOCK; break;
1594 }
1595 }
1596 }
1597 }
1598 break;
1599 }
1600 rSdrObj.SetMergedItem( SvxAdjustItem( eHorAlign, EE_PARA_JUST ) );
1601 rSdrObj.SetMergedItem( SdrTextVertAdjustItem( eVerAlign ) );
1602 rSdrObj.SetMergedItem( SvxWritingModeItem( eWriteMode, SDRATTR_TEXTDIRECTION ) );
1603 }
1604 }
1605 // base class processing
1606 XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
1607 }
1608
1609 // ----------------------------------------------------------------------------
1610
XclImpChartObj(const XclImpRoot & rRoot,bool bOwnTab)1611 XclImpChartObj::XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab ) :
1612 XclImpRectObj( rRoot ),
1613 mbOwnTab( bOwnTab )
1614 {
1615 SetSimpleMacro( false );
1616 SetCustomDffObj( true );
1617 }
1618
ReadChartSubStream(XclImpStream & rStrm)1619 void XclImpChartObj::ReadChartSubStream( XclImpStream& rStrm )
1620 {
1621 /* If chart is read from a chartsheet (mbOwnTab == true), the BOF record
1622 has already been read. If chart is embedded as object, the next record
1623 has to be the BOF record. */
1624 if( mbOwnTab )
1625 {
1626 /* #i109800# The input stream may point somewhere inside the chart
1627 substream and not exactly to the leading BOF record. To read this
1628 record correctly in the following, the stream has to rewind it, so
1629 that the next call to StartNextRecord() will find it correctly. */
1630 if( rStrm.GetRecId() != EXC_ID5_BOF )
1631 rStrm.RewindRecord();
1632 }
1633 else
1634 {
1635 if( (rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord() )
1636 {
1637 sal_uInt16 nBofType;
1638 rStrm.Seek( 2 );
1639 rStrm >> nBofType;
1640 DBG_ASSERT( nBofType == EXC_BOF_CHART, "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
1641 }
1642 else
1643 {
1644 DBG_ERRORFILE( "XclImpChartObj::ReadChartSubStream - missing chart substream" );
1645 return;
1646 }
1647 }
1648
1649 // read chart, even if BOF record contains wrong substream identifier
1650 mxChart.reset( new XclImpChart( GetRoot(), mbOwnTab ) );
1651 mxChart->ReadChartSubStream( rStrm );
1652 if( mbOwnTab )
1653 FinalizeTabChart();
1654 }
1655
DoReadObj3(XclImpStream & rStrm,sal_uInt16 nMacroSize)1656 void XclImpChartObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1657 {
1658 // read OBJ record and the following chart substream
1659 ReadFrameData( rStrm );
1660 rStrm.Ignore( 18 );
1661 ReadMacro3( rStrm, nMacroSize );
1662 #if 0
1663 ReadChartSubStream( rStrm );
1664 #endif
1665 // set frame format from OBJ record, it is used if chart itself is transparent
1666 if( mxChart.is() )
1667 mxChart->UpdateObjFrame( maLineData, maFillData );
1668 }
1669
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)1670 void XclImpChartObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1671 {
1672 // read OBJ record and the following chart substream
1673 ReadFrameData( rStrm );
1674 rStrm.Ignore( 18 );
1675 ReadMacro4( rStrm, nMacroSize );
1676 #if 0
1677 ReadChartSubStream( rStrm );
1678 #endif
1679 // set frame format from OBJ record, it is used if chart itself is transparent
1680 if( mxChart.is() )
1681 mxChart->UpdateObjFrame( maLineData, maFillData );
1682 }
1683
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)1684 void XclImpChartObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1685 {
1686 // read OBJ record and the following chart substream
1687 ReadFrameData( rStrm );
1688 rStrm.Ignore( 18 );
1689 ReadName5( rStrm, nNameLen );
1690 ReadMacro5( rStrm, nMacroSize );
1691 ReadChartSubStream( rStrm );
1692 // set frame format from OBJ record, it is used if chart itself is transparent
1693 if( mxChart.is() )
1694 mxChart->UpdateObjFrame( maLineData, maFillData );
1695 }
1696
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16)1697 void XclImpChartObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 /*nSubRecSize*/ )
1698 {
1699 // read the following chart substream
1700 if( nSubRecId == EXC_ID_OBJEND )
1701 {
1702 // enable CONTINUE handling for the entire chart substream
1703 rStrm.ResetRecord( true );
1704 ReadChartSubStream( rStrm );
1705 /* #90118# disable CONTINUE handling again to be able to read
1706 following CONTINUE records as MSODRAWING records. */
1707 rStrm.ResetRecord( false );
1708 }
1709 }
1710
DoGetProgressSize() const1711 sal_Size XclImpChartObj::DoGetProgressSize() const
1712 {
1713 return mxChart.is() ? mxChart->GetProgressSize() : 1;
1714 }
1715
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const1716 SdrObject* XclImpChartObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
1717 {
1718 SdrObjectPtr xSdrObj;
1719 SfxObjectShell* pDocShell = GetDocShell();
1720 if( rDffConv.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell && mxChart.is() && !mxChart->IsPivotChart() )
1721 {
1722 // create embedded chart object
1723 OUString aEmbObjName;
1724 Reference< XEmbeddedObject > xEmbObj = pDocShell->GetEmbeddedObjectContainer().
1725 CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aEmbObjName );
1726
1727 /* Set the size to the embedded object, this prevents that font sizes
1728 of text objects are changed in the chart when the object is
1729 inserted into the draw page. */
1730 sal_Int64 nAspect = ::com::sun::star::embed::Aspects::MSOLE_CONTENT;
1731 MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj->getMapUnit( nAspect ) );
1732 Size aSize( Window::LogicToLogic( rAnchorRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( aUnit ) ) );
1733 ::com::sun::star::awt::Size aAwtSize( aSize.Width(), aSize.Height() );
1734 xEmbObj->setVisualAreaSize( nAspect, aAwtSize );
1735
1736 // #121334# This call will change the chart's default background fill from white to transparent.
1737 // Add here again if this is wanted (see task description for details)
1738 // ChartHelper::AdaptDefaultsForChart( xEmbObj );
1739
1740 // create the container OLE object
1741 xSdrObj.reset( new SdrOle2Obj( svt::EmbeddedObjectRef( xEmbObj, nAspect ), aEmbObjName, rAnchorRect ) );
1742 }
1743
1744 return xSdrObj.release();
1745 }
1746
DoPostProcessSdrObj(XclImpDffConverter & rDffConv,SdrObject & rSdrObj) const1747 void XclImpChartObj::DoPostProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
1748 {
1749 const SdrOle2Obj* pSdrOleObj = dynamic_cast< const SdrOle2Obj* >( &rSdrObj );
1750 if( mxChart.is() && pSdrOleObj )
1751 {
1752 Reference< XEmbeddedObject > xEmbObj = pSdrOleObj->GetObjRef();
1753 if( xEmbObj.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) try
1754 {
1755 Reference< XEmbedPersist > xPersist( xEmbObj, UNO_QUERY_THROW );
1756 Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY_THROW );
1757 mxChart->Convert( xModel, rDffConv, xPersist->getEntryName(), rSdrObj.GetLogicRect() );
1758 xPersist->storeOwn();
1759 }
1760 catch( Exception& )
1761 {
1762 }
1763 }
1764 }
1765
FinalizeTabChart()1766 void XclImpChartObj::FinalizeTabChart()
1767 {
1768 /* #i44077# Calculate and store DFF anchor for sheet charts.
1769 Needed to get used area if this chart is inserted as OLE object. */
1770 DBG_ASSERT( mbOwnTab, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" );
1771
1772 // set uninitialized page to landscape
1773 if( !GetPageSettings().GetPageData().mbValid )
1774 GetPageSettings().SetPaperSize( EXC_PAPERSIZE_DEFAULT, false );
1775
1776 // calculate size of the chart object
1777 const XclPageData& rPageData = GetPageSettings().GetPageData();
1778 Size aPaperSize = rPageData.GetScPaperSize();
1779
1780 long nWidth = XclTools::GetHmmFromTwips( aPaperSize.Width() );
1781 long nHeight = XclTools::GetHmmFromTwips( aPaperSize.Height() );
1782
1783 // subtract page margins, give some more extra space
1784 nWidth -= (XclTools::GetHmmFromInch( rPageData.mfLeftMargin + rPageData.mfRightMargin ) + 2000);
1785 nHeight -= (XclTools::GetHmmFromInch( rPageData.mfTopMargin + rPageData.mfBottomMargin ) + 1000);
1786
1787 // print column/row headers?
1788 if( rPageData.mbPrintHeadings )
1789 {
1790 nWidth -= 2000;
1791 nHeight -= 1000;
1792 }
1793
1794 // create the object anchor
1795 XclObjAnchor aAnchor;
1796 aAnchor.SetRect( GetRoot(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM );
1797 SetAnchor( aAnchor );
1798 }
1799
1800 // ----------------------------------------------------------------------------
1801
XclImpNoteObj(const XclImpRoot & rRoot)1802 XclImpNoteObj::XclImpNoteObj( const XclImpRoot& rRoot ) :
1803 XclImpTextObj( rRoot ),
1804 maScPos( ScAddress::INITIALIZE_INVALID ),
1805 mnNoteFlags( 0 )
1806 {
1807 SetSimpleMacro( false );
1808 // caption object will be created manually
1809 SetInsertSdrObj( false );
1810 }
1811
SetNoteData(const ScAddress & rScPos,sal_uInt16 nNoteFlags)1812 void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags )
1813 {
1814 maScPos = rScPos;
1815 mnNoteFlags = nNoteFlags;
1816 }
1817
DoPreProcessSdrObj(XclImpDffConverter & rDffConv,SdrObject & rSdrObj) const1818 void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
1819 {
1820 // create formatted text
1821 XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
1822 OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject();
1823 if( maScPos.IsValid() && pOutlinerObj )
1824 {
1825 // create cell note with all data from drawing object
1826 ScNoteUtil::CreateNoteFromObjectData(
1827 GetDoc(), maScPos,
1828 rSdrObj.GetMergedItemSet().Clone(), // new object on heap expected
1829 new OutlinerParaObject( *pOutlinerObj ), // new object on heap expected
1830 rSdrObj.GetLogicRect(),
1831 ::get_flag( mnNoteFlags, EXC_NOTE_VISIBLE ),
1832 false );
1833 }
1834 }
1835
1836 // ----------------------------------------------------------------------------
1837
XclImpControlHelper(const XclImpRoot & rRoot,XclCtrlBindMode eBindMode)1838 XclImpControlHelper::XclImpControlHelper( const XclImpRoot& rRoot, XclCtrlBindMode eBindMode ) :
1839 mrRoot( rRoot ),
1840 meBindMode( eBindMode )
1841 {
1842 }
1843
~XclImpControlHelper()1844 XclImpControlHelper::~XclImpControlHelper()
1845 {
1846 }
1847
CreateSdrObjectFromShape(const Reference<XShape> & rxShape,const Rectangle & rAnchorRect) const1848 SdrObject* XclImpControlHelper::CreateSdrObjectFromShape(
1849 const Reference< XShape >& rxShape, const Rectangle& rAnchorRect ) const
1850 {
1851 mxShape = rxShape;
1852 SdrObjectPtr xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape ) );
1853 if( xSdrObj.is() )
1854 {
1855 xSdrObj->NbcSetSnapRect( rAnchorRect );
1856 // #i30543# insert into control layer
1857 xSdrObj->NbcSetLayer( SC_LAYER_CONTROLS );
1858 }
1859 return xSdrObj.release();
1860 }
1861
ProcessControl(const XclImpDrawObjBase & rDrawObj) const1862 void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase& rDrawObj ) const
1863 {
1864 Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
1865 if( !xCtrlModel.is() )
1866 return;
1867
1868 ScfPropertySet aPropSet( xCtrlModel );
1869
1870 // #118053# #i51348# set object name at control model
1871 aPropSet.SetStringProperty( CREATE_OUSTRING( "Name" ), rDrawObj.GetObjName() );
1872
1873 // control visible and printable?
1874 aPropSet.SetBoolProperty( CREATE_OUSTRING( "EnableVisible" ), rDrawObj.IsVisible() );
1875 aPropSet.SetBoolProperty( CREATE_OUSTRING( "Printable" ), rDrawObj.IsPrintable() );
1876
1877 // sheet links
1878 if( SfxObjectShell* pDocShell = mrRoot.GetDocShell() )
1879 {
1880 Reference< XMultiServiceFactory > xFactory( pDocShell->GetModel(), UNO_QUERY );
1881 if( xFactory.is() )
1882 {
1883 // cell link
1884 if( mxCellLink.is() ) try
1885 {
1886 Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY_THROW );
1887
1888 // create argument sequence for createInstanceWithArguments()
1889 CellAddress aApiAddress;
1890 ScUnoConversion::FillApiAddress( aApiAddress, *mxCellLink );
1891
1892 NamedValue aValue;
1893 aValue.Name = CREATE_OUSTRING( SC_UNONAME_BOUNDCELL );
1894 aValue.Value <<= aApiAddress;
1895
1896 Sequence< Any > aArgs( 1 );
1897 aArgs[ 0 ] <<= aValue;
1898
1899 // create the CellValueBinding instance and set at the control model
1900 OUString aServiceName;
1901 switch( meBindMode )
1902 {
1903 case EXC_CTRL_BINDCONTENT: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_VALBIND ); break;
1904 case EXC_CTRL_BINDPOSITION: aServiceName = CREATE_OUSTRING( SC_SERVICENAME_LISTCELLBIND ); break;
1905 }
1906 Reference< XValueBinding > xBinding(
1907 xFactory->createInstanceWithArguments( aServiceName, aArgs ), UNO_QUERY_THROW );
1908 xBindable->setValueBinding( xBinding );
1909 }
1910 catch( const Exception& )
1911 {
1912 }
1913
1914 // source range
1915 if( mxSrcRange.is() ) try
1916 {
1917 Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY_THROW );
1918
1919 // create argument sequence for createInstanceWithArguments()
1920 CellRangeAddress aApiRange;
1921 ScUnoConversion::FillApiRange( aApiRange, *mxSrcRange );
1922
1923 NamedValue aValue;
1924 aValue.Name = CREATE_OUSTRING( SC_UNONAME_CELLRANGE );
1925 aValue.Value <<= aApiRange;
1926
1927 Sequence< Any > aArgs( 1 );
1928 aArgs[ 0 ] <<= aValue;
1929
1930 // create the EntrySource instance and set at the control model
1931 Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
1932 CREATE_OUSTRING( SC_SERVICENAME_LISTSOURCE ), aArgs ), UNO_QUERY_THROW );
1933 xEntrySink->setListEntrySource( xEntrySource );
1934 }
1935 catch( const Exception& )
1936 {
1937 }
1938 }
1939 }
1940
1941 // virtual call for type specific processing
1942 DoProcessControl( aPropSet );
1943 }
1944
ReadCellLinkFormula(XclImpStream & rStrm,bool bWithBoundSize)1945 void XclImpControlHelper::ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize )
1946 {
1947 ScRangeList aScRanges;
1948 ReadRangeList( aScRanges, rStrm, bWithBoundSize );
1949 // Use first cell of first range
1950 if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
1951 mxCellLink.reset( new ScAddress( pScRange->aStart ) );
1952 }
1953
ReadSourceRangeFormula(XclImpStream & rStrm,bool bWithBoundSize)1954 void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream& rStrm, bool bWithBoundSize )
1955 {
1956 ScRangeList aScRanges;
1957 ReadRangeList( aScRanges, rStrm, bWithBoundSize );
1958 // Use first range
1959 if( const ScRange* pScRange = aScRanges.GetObject( 0 ) )
1960 mxSrcRange.reset( new ScRange( *pScRange ) );
1961 }
1962
DoProcessControl(ScfPropertySet &) const1963 void XclImpControlHelper::DoProcessControl( ScfPropertySet& ) const
1964 {
1965 }
1966
ReadRangeList(ScRangeList & rScRanges,XclImpStream & rStrm)1967 void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm )
1968 {
1969 XclTokenArray aXclTokArr;
1970 aXclTokArr.ReadSize( rStrm );
1971 rStrm.Ignore( 4 );
1972 aXclTokArr.ReadArray( rStrm );
1973 mrRoot.GetFormulaCompiler().CreateRangeList( rScRanges, EXC_FMLATYPE_CONTROL, aXclTokArr, rStrm );
1974 }
1975
ReadRangeList(ScRangeList & rScRanges,XclImpStream & rStrm,bool bWithBoundSize)1976 void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize )
1977 {
1978 if( bWithBoundSize )
1979 {
1980 sal_uInt16 nSize;
1981 rStrm >> nSize;
1982 if( nSize > 0 )
1983 {
1984 rStrm.PushPosition();
1985 ReadRangeList( rScRanges, rStrm );
1986 rStrm.PopPosition();
1987 rStrm.Ignore( nSize );
1988 }
1989 }
1990 else
1991 {
1992 ReadRangeList( rScRanges, rStrm );
1993 }
1994 }
1995
1996 // ----------------------------------------------------------------------------
1997
XclImpTbxObjBase(const XclImpRoot & rRoot)1998 XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot& rRoot ) :
1999 XclImpTextObj( rRoot ),
2000 XclImpControlHelper( rRoot, EXC_CTRL_BINDPOSITION )
2001 {
2002 SetSimpleMacro( false );
2003 SetCustomDffObj( true );
2004 }
2005
2006 namespace {
2007
lclExtractColor(sal_uInt8 & rnColorIdx,const DffPropSet & rDffPropSet,sal_uInt32 nPropId)2008 void lclExtractColor( sal_uInt8& rnColorIdx, const DffPropSet& rDffPropSet, sal_uInt32 nPropId )
2009 {
2010 if( rDffPropSet.IsProperty( nPropId ) )
2011 {
2012 sal_uInt32 nColor = rDffPropSet.GetPropertyValue( nPropId );
2013 if( (nColor & 0xFF000000) == 0x08000000 )
2014 rnColorIdx = ::extract_value< sal_uInt8 >( nColor, 0, 8 );
2015 }
2016 }
2017
2018 } // namespace
2019
SetDffProperties(const DffPropSet & rDffPropSet)2020 void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet )
2021 {
2022 maFillData.mnPattern = rDffPropSet.GetPropertyBool( DFF_Prop_fFilled ) ? EXC_PATT_SOLID : EXC_PATT_NONE;
2023 lclExtractColor( maFillData.mnBackColorIdx, rDffPropSet, DFF_Prop_fillBackColor );
2024 lclExtractColor( maFillData.mnPattColorIdx, rDffPropSet, DFF_Prop_fillColor );
2025 ::set_flag( maFillData.mnAuto, EXC_OBJ_LINE_AUTO, false );
2026
2027 maLineData.mnStyle = rDffPropSet.GetPropertyBool( DFF_Prop_fLine ) ? EXC_OBJ_LINE_SOLID : EXC_OBJ_LINE_NONE;
2028 lclExtractColor( maLineData.mnColorIdx, rDffPropSet, DFF_Prop_lineColor );
2029 ::set_flag( maLineData.mnAuto, EXC_OBJ_FILL_AUTO, false );
2030 }
2031
FillMacroDescriptor(ScriptEventDescriptor & rDescriptor) const2032 bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const
2033 {
2034 return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() );
2035 }
2036
ConvertFont(ScfPropertySet & rPropSet) const2037 void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const
2038 {
2039 if( maTextData.mxString.is() )
2040 {
2041 const XclFormatRunVec& rFormatRuns = maTextData.mxString->GetFormats();
2042 if( rFormatRuns.empty() )
2043 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
2044 else
2045 GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, rFormatRuns.front().mnFontIdx );
2046 }
2047 }
2048
ConvertLabel(ScfPropertySet & rPropSet) const2049 void XclImpTbxObjBase::ConvertLabel( ScfPropertySet& rPropSet ) const
2050 {
2051 if( maTextData.mxString.is() )
2052 {
2053 String aLabel = maTextData.mxString->GetText();
2054 if( maTextData.maData.mnShortcut > 0 )
2055 {
2056 xub_StrLen nPos = aLabel.Search( static_cast< sal_Unicode >( maTextData.maData.mnShortcut ) );
2057 if( nPos != STRING_NOTFOUND )
2058 aLabel.Insert( '~', nPos );
2059 }
2060 rPropSet.SetStringProperty( CREATE_OUSTRING( "Label" ), aLabel );
2061
2062 //Excel Alt text <==> Aoo description
2063 //For TBX control, if user does not operate alt text, alt text will be set label text as default value in Excel.
2064 //In this case, DFF_Prop_wzDescription will not be set in excel file.
2065 //So In the end of SvxMSDffManager::ImportShape, description will not be set. But actually in excel,
2066 //the alt text is the label value. So here set description as label text first which is called before ImportShape.
2067 Reference< ::com::sun::star::beans::XPropertySet > xPropset( mxShape, UNO_QUERY );
2068 try{
2069 if(xPropset.is())
2070 xPropset->setPropertyValue( CREATE_OUSTRING( "Description" ), makeAny(::rtl::OUString(aLabel)) );
2071 }catch( ... )
2072 {
2073 OSL_TRACE( " Can't set a default text for TBX Control ");
2074 }
2075 }
2076 ConvertFont( rPropSet );
2077 }
2078
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const2079 SdrObject* XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
2080 {
2081 SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
2082 rDffConv.Progress();
2083 return xSdrObj.release();
2084 }
2085
DoPreProcessSdrObj(XclImpDffConverter &,SdrObject &) const2086 void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter& /*rDffConv*/, SdrObject& /*rSdrObj*/ ) const
2087 {
2088 // do not call DoPreProcessSdrObj() from base class (to skip text processing)
2089 ProcessControl( *this );
2090 }
2091
2092 // ----------------------------------------------------------------------------
2093
XclImpButtonObj(const XclImpRoot & rRoot)2094 XclImpButtonObj::XclImpButtonObj( const XclImpRoot& rRoot ) :
2095 XclImpTbxObjBase( rRoot )
2096 {
2097 }
2098
DoProcessControl(ScfPropertySet & rPropSet) const2099 void XclImpButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2100 {
2101 // label and text formatting
2102 ConvertLabel( rPropSet );
2103
2104 /* Horizontal text alignment. For unknown reason, the property type is a
2105 simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
2106 sal_Int16 nHorAlign = 1;
2107 switch( maTextData.maData.GetHorAlign() )
2108 {
2109 case EXC_OBJ_HOR_LEFT: nHorAlign = 0; break;
2110 case EXC_OBJ_HOR_CENTER: nHorAlign = 1; break;
2111 case EXC_OBJ_HOR_RIGHT: nHorAlign = 2; break;
2112 }
2113 rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), nHorAlign );
2114
2115 // vertical text alignment
2116 namespace csss = ::com::sun::star::style;
2117 csss::VerticalAlignment eVerAlign = csss::VerticalAlignment_MIDDLE;
2118 switch( maTextData.maData.GetVerAlign() )
2119 {
2120 case EXC_OBJ_VER_TOP: eVerAlign = csss::VerticalAlignment_TOP; break;
2121 case EXC_OBJ_VER_CENTER: eVerAlign = csss::VerticalAlignment_MIDDLE; break;
2122 case EXC_OBJ_VER_BOTTOM: eVerAlign = csss::VerticalAlignment_BOTTOM; break;
2123 }
2124 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), eVerAlign );
2125
2126 // always wrap text automatically
2127 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
2128
2129 // default button
2130 bool bDefButton = ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_DEFAULT );
2131 rPropSet.SetBoolProperty( CREATE_OUSTRING( "DefaultButton" ), bDefButton );
2132
2133 // button type (flags cannot be combined in OOo)
2134 namespace cssa = ::com::sun::star::awt;
2135 cssa::PushButtonType eButtonType = cssa::PushButtonType_STANDARD;
2136 if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CLOSE ) )
2137 eButtonType = cssa::PushButtonType_OK;
2138 else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_CANCEL ) )
2139 eButtonType = cssa::PushButtonType_CANCEL;
2140 else if( ::get_flag( maTextData.maData.mnButtonFlags, EXC_OBJ_BUTTON_HELP ) )
2141 eButtonType = cssa::PushButtonType_HELP;
2142 // property type is short, not enum
2143 rPropSet.SetProperty( CREATE_OUSTRING( "PushButtonType" ), sal_Int16( eButtonType ) );
2144 }
2145
DoGetServiceName() const2146 OUString XclImpButtonObj::DoGetServiceName() const
2147 {
2148 return CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" );
2149 }
2150
DoGetEventType() const2151 XclTbxEventType XclImpButtonObj::DoGetEventType() const
2152 {
2153 return EXC_TBX_EVENT_ACTION;
2154 }
2155
2156 // ----------------------------------------------------------------------------
2157
XclImpCheckBoxObj(const XclImpRoot & rRoot)2158 XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot& rRoot ) :
2159 XclImpTbxObjBase( rRoot ),
2160 mnState( EXC_OBJ_CHECKBOX_UNCHECKED ),
2161 mnCheckBoxFlags( 0 )
2162 {
2163 }
2164
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2165 void XclImpCheckBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2166 {
2167 ReadFrameData( rStrm );
2168 rStrm.Ignore( 10 );
2169 rStrm >> maTextData.maData.mnFlags;
2170 rStrm.Ignore( 20 );
2171 ReadName5( rStrm, nNameLen );
2172 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2173 ReadCellLinkFormula( rStrm, true );
2174 rStrm >> maTextData.maData.mnTextLen;
2175 maTextData.ReadByteString( rStrm );
2176 rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
2177 }
2178
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2179 void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2180 {
2181 switch( nSubRecId )
2182 {
2183 case EXC_ID_OBJCBLS:
2184 // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
2185 rStrm >> mnState;
2186 rStrm.Ignore( 4 );
2187 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnCheckBoxFlags;
2188 break;
2189 case EXC_ID_OBJCBLSFMLA:
2190 ReadCellLinkFormula( rStrm, false );
2191 break;
2192 default:
2193 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2194 }
2195 }
2196
DoProcessControl(ScfPropertySet & rPropSet) const2197 void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2198 {
2199 // label and text formatting
2200 ConvertLabel( rPropSet );
2201
2202 // state
2203 bool bSupportsTristate = GetObjType() == EXC_OBJTYPE_CHECKBOX;
2204 sal_Int16 nApiState = 0;
2205 switch( mnState )
2206 {
2207 case EXC_OBJ_CHECKBOX_UNCHECKED: nApiState = 0; break;
2208 case EXC_OBJ_CHECKBOX_CHECKED: nApiState = 1; break;
2209 case EXC_OBJ_CHECKBOX_TRISTATE: nApiState = bSupportsTristate ? 2 : 1; break;
2210 }
2211 if( bSupportsTristate )
2212 rPropSet.SetBoolProperty( CREATE_OUSTRING( "TriState" ), nApiState == 2 );
2213 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultState" ), nApiState );
2214
2215 // box style
2216 namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2217 sal_Int16 nEffect = ::get_flagvalue( mnCheckBoxFlags, EXC_OBJ_CHECKBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2218 rPropSet.SetProperty( CREATE_OUSTRING( "VisualEffect" ), nEffect );
2219
2220 // do not wrap text automatically
2221 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), false );
2222
2223 // #i40279# always centered vertically
2224 namespace csss = ::com::sun::star::style;
2225 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_MIDDLE );
2226
2227 // background color
2228 if( maFillData.IsFilled() )
2229 {
2230 sal_Int32 nColor = static_cast< sal_Int32 >( GetSolidFillColor( maFillData ).GetColor() );
2231 rPropSet.SetProperty( CREATE_OUSTRING( "BackgroundColor" ), nColor );
2232 }
2233 }
2234
DoGetServiceName() const2235 OUString XclImpCheckBoxObj::DoGetServiceName() const
2236 {
2237 return CREATE_OUSTRING( "com.sun.star.form.component.CheckBox" );
2238 }
2239
DoGetEventType() const2240 XclTbxEventType XclImpCheckBoxObj::DoGetEventType() const
2241 {
2242 return EXC_TBX_EVENT_ACTION;
2243 }
2244
2245 // ----------------------------------------------------------------------------
2246
XclImpOptionButtonObj(const XclImpRoot & rRoot)2247 XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot& rRoot ) :
2248 XclImpCheckBoxObj( rRoot ),
2249 mnNextInGroup( 0 ),
2250 mnFirstInGroup( 1 )
2251 {
2252 }
2253
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2254 void XclImpOptionButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2255 {
2256 ReadFrameData( rStrm );
2257 rStrm.Ignore( 10 );
2258 rStrm >> maTextData.maData.mnFlags;
2259 rStrm.Ignore( 32 );
2260 ReadName5( rStrm, nNameLen );
2261 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2262 ReadCellLinkFormula( rStrm, true );
2263 rStrm >> maTextData.maData.mnTextLen;
2264 maTextData.ReadByteString( rStrm );
2265 rStrm >> mnState >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA;
2266 rStrm >> mnCheckBoxFlags >> mnNextInGroup >> mnFirstInGroup;
2267 }
2268
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2269 void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2270 {
2271 switch( nSubRecId )
2272 {
2273 case EXC_ID_OBJRBODATA:
2274 rStrm >> mnNextInGroup >> mnFirstInGroup;
2275 break;
2276 default:
2277 XclImpCheckBoxObj::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2278 }
2279 }
2280
DoProcessControl(ScfPropertySet & rPropSet) const2281 void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2282 {
2283 XclImpCheckBoxObj::DoProcessControl( rPropSet );
2284 // TODO: grouping
2285 }
2286
DoGetServiceName() const2287 OUString XclImpOptionButtonObj::DoGetServiceName() const
2288 {
2289 return CREATE_OUSTRING( "com.sun.star.form.component.RadioButton" );
2290 }
2291
DoGetEventType() const2292 XclTbxEventType XclImpOptionButtonObj::DoGetEventType() const
2293 {
2294 return EXC_TBX_EVENT_ACTION;
2295 }
2296
2297 // ----------------------------------------------------------------------------
2298
XclImpLabelObj(const XclImpRoot & rRoot)2299 XclImpLabelObj::XclImpLabelObj( const XclImpRoot& rRoot ) :
2300 XclImpTbxObjBase( rRoot )
2301 {
2302 }
2303
DoProcessControl(ScfPropertySet & rPropSet) const2304 void XclImpLabelObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2305 {
2306 // label and text formatting
2307 ConvertLabel( rPropSet );
2308
2309 // text alignment (always top/left aligned)
2310 rPropSet.SetProperty( CREATE_OUSTRING( "Align" ), sal_Int16( 0 ) );
2311 namespace csss = ::com::sun::star::style;
2312 rPropSet.SetProperty( CREATE_OUSTRING( "VerticalAlign" ), csss::VerticalAlignment_TOP );
2313
2314 // always wrap text automatically
2315 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), true );
2316 }
2317
DoGetServiceName() const2318 OUString XclImpLabelObj::DoGetServiceName() const
2319 {
2320 return CREATE_OUSTRING( "com.sun.star.form.component.FixedText" );
2321 }
2322
DoGetEventType() const2323 XclTbxEventType XclImpLabelObj::DoGetEventType() const
2324 {
2325 return EXC_TBX_EVENT_MOUSE;
2326 }
2327
2328 // ----------------------------------------------------------------------------
2329
XclImpGroupBoxObj(const XclImpRoot & rRoot)2330 XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot& rRoot ) :
2331 XclImpTbxObjBase( rRoot ),
2332 mnGroupBoxFlags( 0 )
2333 {
2334 }
2335
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2336 void XclImpGroupBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2337 {
2338 ReadFrameData( rStrm );
2339 rStrm.Ignore( 10 );
2340 rStrm >> maTextData.maData.mnFlags;
2341 rStrm.Ignore( 26 );
2342 ReadName5( rStrm, nNameLen );
2343 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2344 rStrm >> maTextData.maData.mnTextLen;
2345 maTextData.ReadByteString( rStrm );
2346 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
2347 }
2348
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2349 void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2350 {
2351 switch( nSubRecId )
2352 {
2353 case EXC_ID_OBJGBODATA:
2354 rStrm >> maTextData.maData.mnShortcut >> maTextData.maData.mnShortcutEA >> mnGroupBoxFlags;
2355 break;
2356 default:
2357 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2358 }
2359 }
2360
DoProcessControl(ScfPropertySet & rPropSet) const2361 void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2362 {
2363 // label and text formatting
2364 ConvertLabel( rPropSet );
2365 }
2366
DoGetServiceName() const2367 OUString XclImpGroupBoxObj::DoGetServiceName() const
2368 {
2369 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2370 }
2371
DoGetEventType() const2372 XclTbxEventType XclImpGroupBoxObj::DoGetEventType() const
2373 {
2374 return EXC_TBX_EVENT_MOUSE;
2375 }
2376
2377 // ----------------------------------------------------------------------------
2378
XclImpDialogObj(const XclImpRoot & rRoot)2379 XclImpDialogObj::XclImpDialogObj( const XclImpRoot& rRoot ) :
2380 XclImpTbxObjBase( rRoot )
2381 {
2382 }
2383
DoProcessControl(ScfPropertySet & rPropSet) const2384 void XclImpDialogObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2385 {
2386 // label and text formatting
2387 ConvertLabel( rPropSet );
2388 }
2389
DoGetServiceName() const2390 OUString XclImpDialogObj::DoGetServiceName() const
2391 {
2392 // dialog frame faked by a groupbox
2393 return CREATE_OUSTRING( "com.sun.star.form.component.GroupBox" );
2394 }
2395
DoGetEventType() const2396 XclTbxEventType XclImpDialogObj::DoGetEventType() const
2397 {
2398 return EXC_TBX_EVENT_MOUSE;
2399 }
2400
2401 // ----------------------------------------------------------------------------
2402
XclImpEditObj(const XclImpRoot & rRoot)2403 XclImpEditObj::XclImpEditObj( const XclImpRoot& rRoot ) :
2404 XclImpTbxObjBase( rRoot ),
2405 mnContentType( EXC_OBJ_EDIT_TEXT ),
2406 mnMultiLine( 0 ),
2407 mnScrollBar( 0 ),
2408 mnListBoxObjId( 0 )
2409 {
2410 }
2411
IsNumeric() const2412 bool XclImpEditObj::IsNumeric() const
2413 {
2414 return (mnContentType == EXC_OBJ_EDIT_INTEGER) || (mnContentType == EXC_OBJ_EDIT_DOUBLE);
2415 }
2416
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2417 void XclImpEditObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2418 {
2419 ReadFrameData( rStrm );
2420 rStrm.Ignore( 10 );
2421 rStrm >> maTextData.maData.mnFlags;
2422 rStrm.Ignore( 14 );
2423 ReadName5( rStrm, nNameLen );
2424 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2425 rStrm >> maTextData.maData.mnTextLen;
2426 maTextData.ReadByteString( rStrm );
2427 rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
2428 }
2429
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2430 void XclImpEditObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2431 {
2432 switch( nSubRecId )
2433 {
2434 case EXC_ID_OBJEDODATA:
2435 rStrm >> mnContentType >> mnMultiLine >> mnScrollBar >> mnListBoxObjId;
2436 break;
2437 default:
2438 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2439 }
2440 }
2441
DoProcessControl(ScfPropertySet & rPropSet) const2442 void XclImpEditObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2443 {
2444 if( maTextData.mxString.is() )
2445 {
2446 OUString aText = maTextData.mxString->GetText();
2447 if( IsNumeric() )
2448 {
2449 // TODO: OUString::toDouble() does not handle local decimal separator
2450 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultValue" ), aText.toDouble() );
2451 rPropSet.SetBoolProperty( CREATE_OUSTRING( "Spin" ), mnScrollBar != 0 );
2452 }
2453 else
2454 {
2455 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultText" ), aText );
2456 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiLine" ), mnMultiLine != 0 );
2457 rPropSet.SetBoolProperty( CREATE_OUSTRING( "VScroll" ), mnScrollBar != 0 );
2458 }
2459 }
2460 ConvertFont( rPropSet );
2461 }
2462
DoGetServiceName() const2463 OUString XclImpEditObj::DoGetServiceName() const
2464 {
2465 return IsNumeric() ?
2466 CREATE_OUSTRING( "com.sun.star.form.component.NumericField" ) :
2467 CREATE_OUSTRING( "com.sun.star.form.component.TextField" );
2468 }
2469
DoGetEventType() const2470 XclTbxEventType XclImpEditObj::DoGetEventType() const
2471 {
2472 return EXC_TBX_EVENT_TEXT;
2473 }
2474
2475 // ----------------------------------------------------------------------------
2476
XclImpTbxObjScrollableBase(const XclImpRoot & rRoot)2477 XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot& rRoot ) :
2478 XclImpTbxObjBase( rRoot ),
2479 mnValue( 0 ),
2480 mnMin( 0 ),
2481 mnMax( 100 ),
2482 mnStep( 1 ),
2483 mnPageStep( 10 ),
2484 mnOrient( 0 ),
2485 mnThumbWidth( 1 ),
2486 mnScrollFlags( 0 )
2487 {
2488 }
2489
ReadSbs(XclImpStream & rStrm)2490 void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream& rStrm )
2491 {
2492 rStrm.Ignore( 4 );
2493 rStrm >> mnValue >> mnMin >> mnMax >> mnStep >> mnPageStep >> mnOrient >> mnThumbWidth >> mnScrollFlags;
2494 }
2495
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2496 void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2497 {
2498 switch( nSubRecId )
2499 {
2500 case EXC_ID_OBJSBS:
2501 ReadSbs( rStrm );
2502 break;
2503 case EXC_ID_OBJSBSFMLA:
2504 ReadCellLinkFormula( rStrm, false );
2505 break;
2506 default:
2507 XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2508 }
2509 }
2510
2511 // ----------------------------------------------------------------------------
2512
XclImpSpinButtonObj(const XclImpRoot & rRoot)2513 XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot& rRoot ) :
2514 XclImpTbxObjScrollableBase( rRoot )
2515 {
2516 }
2517
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2518 void XclImpSpinButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2519 {
2520 ReadFrameData( rStrm );
2521 ReadSbs( rStrm );
2522 ReadName5( rStrm, nNameLen );
2523 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2524 ReadCellLinkFormula( rStrm, true );
2525 }
2526
DoProcessControl(ScfPropertySet & rPropSet) const2527 void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2528 {
2529 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2530 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
2531 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultSpinValue" ), mnValue );
2532 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMin" ), mnMin );
2533 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinValueMax" ), mnMax );
2534 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "SpinIncrement" ), mnStep );
2535
2536 // Excel spin buttons always vertical
2537 rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), ::com::sun::star::awt::ScrollBarOrientation::VERTICAL );
2538 }
2539
DoGetServiceName() const2540 OUString XclImpSpinButtonObj::DoGetServiceName() const
2541 {
2542 return CREATE_OUSTRING( "com.sun.star.form.component.SpinButton" );
2543 }
2544
DoGetEventType() const2545 XclTbxEventType XclImpSpinButtonObj::DoGetEventType() const
2546 {
2547 return EXC_TBX_EVENT_VALUE;
2548 }
2549
2550 // ----------------------------------------------------------------------------
2551
XclImpScrollBarObj(const XclImpRoot & rRoot)2552 XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot& rRoot ) :
2553 XclImpTbxObjScrollableBase( rRoot )
2554 {
2555 }
2556
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2557 void XclImpScrollBarObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2558 {
2559 ReadFrameData( rStrm );
2560 ReadSbs( rStrm );
2561 ReadName5( rStrm, nNameLen );
2562 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2563 ReadCellLinkFormula( rStrm, true );
2564 }
2565
DoProcessControl(ScfPropertySet & rPropSet) const2566 void XclImpScrollBarObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2567 {
2568 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2569 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), ::com::sun::star::awt::VisualEffect::NONE );
2570 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "DefaultScrollValue" ), mnValue );
2571 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMin" ), mnMin );
2572 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "ScrollValueMax" ), mnMax );
2573 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "LineIncrement" ), mnStep );
2574 rPropSet.SetProperty< sal_Int32 >( CREATE_OUSTRING( "BlockIncrement" ), mnPageStep );
2575 rPropSet.SetProperty( CREATE_OUSTRING( "VisibleSize" ), ::std::min< sal_Int32 >( mnPageStep, 1 ) );
2576
2577 namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
2578 sal_Int32 nApiOrient = ::get_flagvalue( mnOrient, EXC_OBJ_SCROLLBAR_HOR, AwtScrollOrient::HORIZONTAL, AwtScrollOrient::VERTICAL );
2579 rPropSet.SetProperty( CREATE_OUSTRING( "Orientation" ), nApiOrient );
2580 }
2581
DoGetServiceName() const2582 OUString XclImpScrollBarObj::DoGetServiceName() const
2583 {
2584 return CREATE_OUSTRING( "com.sun.star.form.component.ScrollBar" );
2585 }
2586
DoGetEventType() const2587 XclTbxEventType XclImpScrollBarObj::DoGetEventType() const
2588 {
2589 return EXC_TBX_EVENT_VALUE;
2590 }
2591
2592 // ----------------------------------------------------------------------------
2593
XclImpTbxObjListBase(const XclImpRoot & rRoot)2594 XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot& rRoot ) :
2595 XclImpTbxObjScrollableBase( rRoot ),
2596 mnEntryCount( 0 ),
2597 mnSelEntry( 0 ),
2598 mnListFlags( 0 ),
2599 mnEditObjId( 0 ),
2600 mbHasDefFontIdx( false )
2601 {
2602 }
2603
ReadLbsData(XclImpStream & rStrm)2604 void XclImpTbxObjListBase::ReadLbsData( XclImpStream& rStrm )
2605 {
2606 ReadSourceRangeFormula( rStrm, true );
2607 rStrm >> mnEntryCount >> mnSelEntry >> mnListFlags >> mnEditObjId;
2608 }
2609
SetBoxFormatting(ScfPropertySet & rPropSet) const2610 void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet& rPropSet ) const
2611 {
2612 // border style
2613 namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2614 sal_Int16 nApiBorder = ::get_flagvalue( mnListFlags, EXC_OBJ_LISTBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2615 rPropSet.SetProperty( CREATE_OUSTRING( "Border" ), nApiBorder );
2616
2617 // font formatting
2618 if( mbHasDefFontIdx )
2619 GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, maTextData.maData.mnDefFontIdx );
2620 else
2621 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet );
2622 }
2623
2624 // ----------------------------------------------------------------------------
2625
XclImpListBoxObj(const XclImpRoot & rRoot)2626 XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot& rRoot ) :
2627 XclImpTbxObjListBase( rRoot )
2628 {
2629 }
2630
ReadFullLbsData(XclImpStream & rStrm,sal_Size nRecLeft)2631 void XclImpListBoxObj::ReadFullLbsData( XclImpStream& rStrm, sal_Size nRecLeft )
2632 {
2633 sal_Size nRecEnd = rStrm.GetRecPos() + nRecLeft;
2634 ReadLbsData( rStrm );
2635 DBG_ASSERT( (rStrm.GetRecPos() == nRecEnd) || (rStrm.GetRecPos() + mnEntryCount == nRecEnd),
2636 "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
2637 while( rStrm.IsValid() && (rStrm.GetRecPos() < nRecEnd) )
2638 maSelection.push_back( rStrm.ReaduInt8() );
2639 }
2640
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2641 void XclImpListBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2642 {
2643 ReadFrameData( rStrm );
2644 ReadSbs( rStrm );
2645 rStrm.Ignore( 18 );
2646 rStrm >> maTextData.maData.mnDefFontIdx;
2647 rStrm.Ignore( 4 );
2648 ReadName5( rStrm, nNameLen );
2649 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2650 ReadCellLinkFormula( rStrm, true );
2651 ReadFullLbsData( rStrm, rStrm.GetRecLeft() );
2652 mbHasDefFontIdx = true;
2653 }
2654
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2655 void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2656 {
2657 switch( nSubRecId )
2658 {
2659 case EXC_ID_OBJLBSDATA:
2660 ReadFullLbsData( rStrm, nSubRecSize );
2661 break;
2662 default:
2663 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2664 }
2665 }
2666
DoProcessControl(ScfPropertySet & rPropSet) const2667 void XclImpListBoxObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2668 {
2669 // listbox formatting
2670 SetBoxFormatting( rPropSet );
2671
2672 // selection type
2673 sal_uInt8 nSelType = ::extract_value< sal_uInt8 >( mnListFlags, 4, 2 );
2674 bool bMultiSel = nSelType != EXC_OBJ_LISTBOX_SINGLE;
2675 rPropSet.SetBoolProperty( CREATE_OUSTRING( "MultiSelection" ), bMultiSel );
2676
2677 // selection (do not set, if listbox is linked to a cell)
2678 if( !HasCellLink() )
2679 {
2680 ScfInt16Vec aSelVec;
2681
2682 // multi selection: API expects sequence of list entry indexes
2683 if( bMultiSel )
2684 for( ScfUInt8Vec::const_iterator aBeg = maSelection.begin(), aIt = aBeg, aEnd = maSelection.end(); aIt != aEnd; ++aIt )
2685 if( *aIt != 0 )
2686 aSelVec.push_back( static_cast< sal_Int16 >( aIt - aBeg ) );
2687 // single selection: mnSelEntry is one-based, API expects zero-based
2688 else if( mnSelEntry > 0 )
2689 aSelVec.push_back( static_cast< sal_Int16 >( mnSelEntry - 1 ) );
2690
2691 if( !aSelVec.empty() )
2692 {
2693 Sequence< sal_Int16 > aSelSeq( &aSelVec.front(), static_cast< sal_Int32 >( aSelVec.size() ) );
2694 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
2695 }
2696 }
2697 }
2698
DoGetServiceName() const2699 OUString XclImpListBoxObj::DoGetServiceName() const
2700 {
2701 return CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2702 }
2703
DoGetEventType() const2704 XclTbxEventType XclImpListBoxObj::DoGetEventType() const
2705 {
2706 return EXC_TBX_EVENT_CHANGE;
2707 }
2708
2709 // ----------------------------------------------------------------------------
2710
XclImpDropDownObj(const XclImpRoot & rRoot)2711 XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot& rRoot ) :
2712 XclImpTbxObjListBase( rRoot ),
2713 mnLeft( 0 ),
2714 mnTop( 0 ),
2715 mnRight( 0 ),
2716 mnBottom( 0 ),
2717 mnDropDownFlags( 0 ),
2718 mnLineCount( 0 ),
2719 mnMinWidth( 0 )
2720 {
2721 }
2722
GetDropDownType() const2723 sal_uInt16 XclImpDropDownObj::GetDropDownType() const
2724 {
2725 return ::extract_value< sal_uInt8 >( mnDropDownFlags, 0, 2 );
2726 }
2727
ReadFullLbsData(XclImpStream & rStrm)2728 void XclImpDropDownObj::ReadFullLbsData( XclImpStream& rStrm )
2729 {
2730 ReadLbsData( rStrm );
2731 rStrm >> mnDropDownFlags >> mnLineCount >> mnMinWidth >> maTextData.maData.mnTextLen;
2732 maTextData.ReadByteString( rStrm );
2733 // dropdowns of auto-filters have 'simple' style, they don't have a text area
2734 if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE )
2735 SetProcessSdrObj( false );
2736 }
2737
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16)2738 void XclImpDropDownObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2739 {
2740 ReadFrameData( rStrm );
2741 ReadSbs( rStrm );
2742 rStrm.Ignore( 18 );
2743 rStrm >> maTextData.maData.mnDefFontIdx;
2744 rStrm.Ignore( 14 );
2745 rStrm >> mnLeft >> mnTop >> mnRight >> mnBottom;
2746 rStrm.Ignore( 4 );
2747 ReadName5( rStrm, nNameLen );
2748 ReadMacro5( rStrm, rStrm.ReaduInt16() ); // fist macro size invalid and unused
2749 ReadCellLinkFormula( rStrm, true );
2750 ReadFullLbsData( rStrm );
2751 mbHasDefFontIdx = true;
2752 }
2753
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2754 void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2755 {
2756 switch( nSubRecId )
2757 {
2758 case EXC_ID_OBJLBSDATA:
2759 ReadFullLbsData( rStrm );
2760 break;
2761 default:
2762 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2763 }
2764 }
2765
DoProcessControl(ScfPropertySet & rPropSet) const2766 void XclImpDropDownObj::DoProcessControl( ScfPropertySet& rPropSet ) const
2767 {
2768 // dropdown listbox formatting
2769 SetBoxFormatting( rPropSet );
2770 // enable dropdown button
2771 rPropSet.SetBoolProperty( CREATE_OUSTRING( "Dropdown" ), true );
2772 // dropdown line count
2773 rPropSet.SetProperty( CREATE_OUSTRING( "LineCount" ), mnLineCount );
2774
2775 if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX )
2776 {
2777 // text of editable combobox
2778 if( maTextData.mxString.is() )
2779 rPropSet.SetStringProperty( CREATE_OUSTRING( "DefaultText" ), maTextData.mxString->GetText() );
2780 }
2781 else
2782 {
2783 // selection (do not set, if dropdown is linked to a cell)
2784 if( !HasCellLink() && (mnSelEntry > 0) )
2785 {
2786 Sequence< sal_Int16 > aSelSeq( 1 );
2787 aSelSeq[ 0 ] = mnSelEntry - 1;
2788 rPropSet.SetProperty( CREATE_OUSTRING( "DefaultSelection" ), aSelSeq );
2789 }
2790 }
2791 }
2792
DoGetServiceName() const2793 OUString XclImpDropDownObj::DoGetServiceName() const
2794 {
2795 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ?
2796 CREATE_OUSTRING( "com.sun.star.form.component.ComboBox" ) :
2797 CREATE_OUSTRING( "com.sun.star.form.component.ListBox" );
2798 }
2799
DoGetEventType() const2800 XclTbxEventType XclImpDropDownObj::DoGetEventType() const
2801 {
2802 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX) ? EXC_TBX_EVENT_TEXT : EXC_TBX_EVENT_CHANGE;
2803 }
2804
2805 // ----------------------------------------------------------------------------
2806
XclImpPictureObj(const XclImpRoot & rRoot)2807 XclImpPictureObj::XclImpPictureObj( const XclImpRoot& rRoot ) :
2808 XclImpRectObj( rRoot ),
2809 XclImpControlHelper( rRoot, EXC_CTRL_BINDCONTENT ),
2810 mnStorageId( 0 ),
2811 mnCtlsStrmPos( 0 ),
2812 mnCtlsStrmSize( 0 ),
2813 mbEmbedded( false ),
2814 mbLinked( false ),
2815 mbSymbol( false ),
2816 mbControl( false ),
2817 mbUseCtlsStrm( false )
2818 {
2819 SetAreaObj( true );
2820 SetSimpleMacro( true );
2821 SetCustomDffObj( true );
2822 }
2823
GetOleStorageName() const2824 String XclImpPictureObj::GetOleStorageName() const
2825 {
2826 String aStrgName;
2827 if( (mbEmbedded || mbLinked) && !mbControl && (mnStorageId > 0) )
2828 {
2829 aStrgName = mbEmbedded ? EXC_STORAGE_OLE_EMBEDDED : EXC_STORAGE_OLE_LINKED;
2830 static const sal_Char spcHexChars[] = "0123456789ABCDEF";
2831 for( sal_uInt8 nIndex = 32; nIndex > 0; nIndex -= 4 )
2832 aStrgName.Append( sal_Unicode( spcHexChars[ ::extract_value< sal_uInt8 >( mnStorageId, nIndex - 4, 4 ) ] ) );
2833 }
2834 return aStrgName;
2835 }
2836
DoReadObj3(XclImpStream & rStrm,sal_uInt16 nMacroSize)2837 void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2838 {
2839 sal_uInt16 nLinkSize;
2840 ReadFrameData( rStrm );
2841 rStrm.Ignore( 6 );
2842 rStrm >> nLinkSize;
2843 rStrm.Ignore( 2 );
2844 ReadFlags3( rStrm );
2845 ReadMacro3( rStrm, nMacroSize );
2846 ReadPictFmla( rStrm, nLinkSize );
2847
2848 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2849 maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
2850 }
2851
DoReadObj4(XclImpStream & rStrm,sal_uInt16 nMacroSize)2852 void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2853 {
2854 sal_uInt16 nLinkSize;
2855 ReadFrameData( rStrm );
2856 rStrm.Ignore( 6 );
2857 rStrm >> nLinkSize;
2858 rStrm.Ignore( 2 );
2859 ReadFlags3( rStrm );
2860 ReadMacro4( rStrm, nMacroSize );
2861 ReadPictFmla( rStrm, nLinkSize );
2862
2863 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2864 maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
2865 }
2866
DoReadObj5(XclImpStream & rStrm,sal_uInt16 nNameLen,sal_uInt16 nMacroSize)2867 void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
2868 {
2869 sal_uInt16 nLinkSize;
2870 ReadFrameData( rStrm );
2871 rStrm.Ignore( 6 );
2872 rStrm >> nLinkSize;
2873 rStrm.Ignore( 2 );
2874 ReadFlags3( rStrm );
2875 rStrm.Ignore( 4 );
2876 ReadName5( rStrm, nNameLen );
2877 ReadMacro5( rStrm, nMacroSize );
2878 ReadPictFmla( rStrm, nLinkSize );
2879
2880 if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2881 {
2882 // page background is stored as hidden picture with name "__BkgndObj"
2883 if( IsHidden() && (GetObjName() == CREATE_STRING( "__BkgndObj" )) )
2884 GetPageSettings().ReadImgData( rStrm );
2885 else
2886 maGraphic = XclImpDrawing::ReadImgData( GetRoot(), rStrm );
2887 }
2888 }
2889
DoReadObj8SubRec(XclImpStream & rStrm,sal_uInt16 nSubRecId,sal_uInt16 nSubRecSize)2890 void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2891 {
2892 switch( nSubRecId )
2893 {
2894 case EXC_ID_OBJFLAGS:
2895 ReadFlags8( rStrm );
2896 break;
2897 case EXC_ID_OBJPICTFMLA:
2898 ReadPictFmla( rStrm, rStrm.ReaduInt16() );
2899 break;
2900 default:
2901 XclImpDrawObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2902 }
2903 }
2904
DoCreateSdrObj(XclImpDffConverter & rDffConv,const Rectangle & rAnchorRect) const2905 SdrObject* XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter& rDffConv, const Rectangle& rAnchorRect ) const
2906 {
2907 // try to create an OLE object or form control
2908 SdrObjectPtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
2909
2910 // no OLE - create a plain picture from IMGDATA record data
2911 if( !xSdrObj && (maGraphic.GetType() != GRAPHIC_NONE) )
2912 {
2913 xSdrObj.reset( new SdrGrafObj( maGraphic, rAnchorRect ) );
2914 ConvertRectStyle( *xSdrObj );
2915 }
2916
2917 rDffConv.Progress();
2918 return xSdrObj.release();
2919 }
2920
DoPreProcessSdrObj(XclImpDffConverter & rDffConv,SdrObject & rSdrObj) const2921 void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter& rDffConv, SdrObject& rSdrObj ) const
2922 {
2923 if( IsOcxControl() )
2924 {
2925 // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature
2926 ProcessControl( *this );
2927 }
2928 else if( mbEmbedded || mbLinked )
2929 {
2930 // trace missing "printable" feature
2931 XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
2932
2933 SfxObjectShell* pDocShell = GetDocShell();
2934 SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj );
2935 if( pOleSdrObj && pDocShell )
2936 {
2937 comphelper::EmbeddedObjectContainer& rEmbObjCont = pDocShell->GetEmbeddedObjectContainer();
2938 Reference< XEmbeddedObject > xEmbObj = pOleSdrObj->GetObjRef();
2939 OUString aOldName( pOleSdrObj->GetPersistName() );
2940
2941 /* The object persistence should be already in the storage, but
2942 the object still might not be inserted into the container. */
2943 if( rEmbObjCont.HasEmbeddedObject( aOldName ) )
2944 {
2945 if( !rEmbObjCont.HasEmbeddedObject( xEmbObj ) )
2946 // filter code is allowed to call the following method
2947 rEmbObjCont.AddEmbeddedObject( xEmbObj, aOldName );
2948 }
2949 else
2950 {
2951 /* If the object is still not in container it must be inserted
2952 there, the name must be generated in this case. */
2953 OUString aNewName;
2954 rEmbObjCont.InsertEmbeddedObject( xEmbObj, aNewName );
2955 if( aOldName != aNewName )
2956 // #95381# SetPersistName, not SetName
2957 pOleSdrObj->SetPersistName( aNewName );
2958 }
2959 }
2960 }
2961 }
2962
ReadFlags3(XclImpStream & rStrm)2963 void XclImpPictureObj::ReadFlags3( XclImpStream& rStrm )
2964 {
2965 sal_uInt16 nFlags;
2966 rStrm >> nFlags;
2967 mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
2968 }
2969
ReadFlags8(XclImpStream & rStrm)2970 void XclImpPictureObj::ReadFlags8( XclImpStream& rStrm )
2971 {
2972 sal_uInt16 nFlags;
2973 rStrm >> nFlags;
2974 mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
2975 mbControl = ::get_flag( nFlags, EXC_OBJ_PIC_CONTROL );
2976 mbUseCtlsStrm = ::get_flag( nFlags, EXC_OBJ_PIC_CTLSSTREAM );
2977 DBG_ASSERT( mbControl || !mbUseCtlsStrm, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
2978 SetProcessSdrObj( mbControl || !mbUseCtlsStrm );
2979 }
2980
ReadPictFmla(XclImpStream & rStrm,sal_uInt16 nLinkSize)2981 void XclImpPictureObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize )
2982 {
2983 sal_Size nLinkEnd = rStrm.GetRecPos() + nLinkSize;
2984 if( nLinkSize >= 6 )
2985 {
2986 sal_uInt16 nFmlaSize;
2987 rStrm >> nFmlaSize;
2988 DBG_ASSERT( nFmlaSize > 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
2989 // BIFF3/BIFF4 do not support storages, nothing to do here
2990 if( (nFmlaSize > 0) && (GetBiff() >= EXC_BIFF5) )
2991 {
2992 rStrm.Ignore( 4 );
2993 sal_uInt8 nToken;
2994 rStrm >> nToken;
2995
2996 // different processing for linked vs. embedded OLE objects
2997 if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) )
2998 {
2999 mbLinked = true;
3000 switch( GetBiff() )
3001 {
3002 case EXC_BIFF5:
3003 {
3004 sal_Int16 nRefIdx;
3005 sal_uInt16 nNameIdx;
3006 rStrm >> nRefIdx;
3007 rStrm.Ignore( 8 );
3008 rStrm >> nNameIdx;
3009 rStrm.Ignore( 12 );
3010 const ExtName* pExtName = GetOldRoot().pExtNameBuff->GetNameByIndex( nRefIdx, nNameIdx );
3011 if( pExtName && pExtName->IsOLE() )
3012 mnStorageId = pExtName->nStorageId;
3013 }
3014 break;
3015 case EXC_BIFF8:
3016 {
3017 sal_uInt16 nXti, nExtName;
3018 rStrm >> nXti >> nExtName;
3019 const XclImpExtName* pExtName = GetLinkManager().GetExternName( nXti, nExtName );
3020 if( pExtName && (pExtName->GetType() == xlExtOLE) )
3021 mnStorageId = pExtName->GetStorageId();
3022 }
3023 break;
3024 default:
3025 DBG_ERROR_BIFF();
3026 }
3027 }
3028 else if( nToken == XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL, EXC_TOKCLASS_NONE ) )
3029 {
3030 mbEmbedded = true;
3031 DBG_ASSERT( nFmlaSize == 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
3032 rStrm.Ignore( nFmlaSize - 1 ); // token ID already read
3033 if( nFmlaSize & 1 )
3034 rStrm.Ignore( 1 ); // padding byte
3035
3036 // a class name may follow inside the picture link
3037 if( rStrm.GetRecPos() + 2 <= nLinkEnd )
3038 {
3039 sal_uInt16 nLen;
3040 rStrm >> nLen;
3041 if( nLen > 0 )
3042 maClassName = (GetBiff() == EXC_BIFF8) ? rStrm.ReadUniString( nLen ) : rStrm.ReadRawByteString( nLen );
3043 }
3044 }
3045 // else: ignore other formulas, e.g. pictures linked to cell ranges
3046 }
3047 }
3048
3049 // seek behind picture link data
3050 rStrm.Seek( nLinkEnd );
3051
3052 // read additional data for embedded OLE objects following the picture link
3053 if( IsOcxControl() )
3054 {
3055 // #i26521# form controls to be ignored
3056 if( maClassName.EqualsAscii( "Forms.HTML:Hidden.1" ) )
3057 {
3058 SetProcessSdrObj( false );
3059 return;
3060 }
3061
3062 if( rStrm.GetRecLeft() <= 8 ) return;
3063
3064 // position and size of control data in 'Ctls' stream
3065 mnCtlsStrmPos = static_cast< sal_Size >( rStrm.ReaduInt32() );
3066 mnCtlsStrmSize = static_cast< sal_Size >( rStrm.ReaduInt32() );
3067
3068 if( rStrm.GetRecLeft() <= 8 ) return;
3069
3070 // additional string (16-bit characters), e.g. for progress bar control
3071 sal_uInt32 nAddStrSize;
3072 rStrm >> nAddStrSize;
3073 DBG_ASSERT( rStrm.GetRecLeft() >= nAddStrSize + 4, "XclImpPictureObj::ReadPictFmla - missing data" );
3074 if( rStrm.GetRecLeft() >= nAddStrSize + 4 )
3075 {
3076 rStrm.Ignore( nAddStrSize );
3077 // cell link and source range
3078 ReadCellLinkFormula( rStrm, true );
3079 ReadSourceRangeFormula( rStrm, true );
3080 }
3081 }
3082 else if( mbEmbedded && (rStrm.GetRecLeft() >= 4) )
3083 {
3084 rStrm >> mnStorageId;
3085 }
3086 }
3087
3088 // DFF stream conversion ======================================================
3089
3090 //UNUSED2009-05 void XclImpSolverContainer::ReadSolverContainer( SvStream& rDffStrm )
3091 //UNUSED2009-05 {
3092 //UNUSED2009-05 rDffStrm >> *this;
3093 //UNUSED2009-05 }
3094
InsertSdrObjectInfo(SdrObject & rSdrObj,sal_uInt32 nDffShapeId,sal_uInt32 nDffFlags)3095 void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, sal_uInt32 nDffFlags )
3096 {
3097 if( nDffShapeId > 0 )
3098 {
3099 maSdrInfoMap[ nDffShapeId ].Set( &rSdrObj, nDffFlags );
3100 maSdrObjMap[ &rSdrObj ] = nDffShapeId;
3101 }
3102 }
3103
RemoveSdrObjectInfo(SdrObject & rSdrObj)3104 void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject& rSdrObj )
3105 {
3106 // remove info of passed object from the maps
3107 XclImpSdrObjMap::iterator aIt = maSdrObjMap.find( &rSdrObj );
3108 if( aIt != maSdrObjMap.end() )
3109 {
3110 maSdrInfoMap.erase( aIt->second );
3111 maSdrObjMap.erase( aIt );
3112 }
3113
3114 // remove info of all child objects of a group object
3115 if( SdrObjGroup* pGroupObj = dynamic_cast< SdrObjGroup* >( &rSdrObj ) )
3116 {
3117 if( SdrObjList* pSubList = pGroupObj->GetSubList() )
3118 {
3119 // iterate flat over the list because this function already works recursively
3120 SdrObjListIter aObjIt( *pSubList, IM_FLAT );
3121 for( SdrObject* pChildObj = aObjIt.Next(); pChildObj; pChildObj = aObjIt.Next() )
3122 RemoveSdrObjectInfo( *pChildObj );
3123 }
3124 }
3125 }
3126
UpdateConnectorRules()3127 void XclImpSolverContainer::UpdateConnectorRules()
3128 {
3129 for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
3130 {
3131 UpdateConnection( pRule->nShapeA, pRule->pAObj, &pRule->nSpFlagsA );
3132 UpdateConnection( pRule->nShapeB, pRule->pBObj, &pRule->nSpFlagsB );
3133 UpdateConnection( pRule->nShapeC, pRule->pCObj );
3134 }
3135 }
3136
RemoveConnectorRules()3137 void XclImpSolverContainer::RemoveConnectorRules()
3138 {
3139 // base class from SVX uses plain untyped tools/List
3140 for( SvxMSDffConnectorRule* pRule = GetFirstRule(); pRule; pRule = GetNextRule() )
3141 delete pRule;
3142 aCList.Clear();
3143
3144 maSdrInfoMap.clear();
3145 maSdrObjMap.clear();
3146 }
3147
GetFirstRule()3148 SvxMSDffConnectorRule* XclImpSolverContainer::GetFirstRule()
3149 {
3150 return static_cast< SvxMSDffConnectorRule* >( aCList.First() );
3151 }
3152
GetNextRule()3153 SvxMSDffConnectorRule* XclImpSolverContainer::GetNextRule()
3154 {
3155 return static_cast< SvxMSDffConnectorRule* >( aCList.Next() );
3156 }
3157
UpdateConnection(sal_uInt32 nDffShapeId,SdrObject * & rpSdrObj,sal_uInt32 * pnDffFlags)3158 void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, sal_uInt32* pnDffFlags )
3159 {
3160 XclImpSdrInfoMap::const_iterator aIt = maSdrInfoMap.find( nDffShapeId );
3161 if( aIt != maSdrInfoMap.end() )
3162 {
3163 rpSdrObj = aIt->second.mpSdrObj;
3164 if( pnDffFlags )
3165 *pnDffFlags = aIt->second.mnDffFlags;
3166 }
3167 }
3168
3169 // ----------------------------------------------------------------------------
3170
XclImpSimpleDffConverter(const XclImpRoot & rRoot,SvStream & rDffStrm)3171 XclImpSimpleDffConverter::XclImpSimpleDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
3172 SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, 0, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, 24, 0, &rRoot.GetTracer().GetBaseTracer() ),
3173 XclImpRoot( rRoot )
3174 {
3175 SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS | SVXMSDFF_SETTINGS_IMPORT_EXCEL );
3176 }
3177
~XclImpSimpleDffConverter()3178 XclImpSimpleDffConverter::~XclImpSimpleDffConverter()
3179 {
3180 }
3181
GetColorFromPalette(sal_uInt16 nIndex,Color & rColor) const3182 FASTBOOL XclImpSimpleDffConverter::GetColorFromPalette( sal_uInt16 nIndex, Color& rColor ) const
3183 {
3184 ColorData nColor = GetPalette().GetColorData( static_cast< sal_uInt16 >( nIndex ) );
3185
3186 if( nColor == COL_AUTO )
3187 return sal_False;
3188
3189 rColor.SetColor( nColor );
3190 return sal_True;
3191 }
3192
3193 // ----------------------------------------------------------------------------
3194
XclImpDffConvData(XclImpDrawing & rDrawing,SdrModel & rSdrModel,SdrPage & rSdrPage)3195 XclImpDffConverter::XclImpDffConvData::XclImpDffConvData(
3196 XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) :
3197 mrDrawing( rDrawing ),
3198 mrSdrModel( rSdrModel ),
3199 mrSdrPage( rSdrPage ),
3200 mnLastCtrlIndex( -1 ),
3201 mbHasCtrlForm( false )
3202 {
3203 }
3204
3205 // ----------------------------------------------------------------------------
3206
XclImpDffConverter(const XclImpRoot & rRoot,SvStream & rDffStrm)3207 XclImpDffConverter::XclImpDffConverter( const XclImpRoot& rRoot, SvStream& rDffStrm ) :
3208 XclImpSimpleDffConverter( rRoot, rDffStrm ),
3209 SvxMSConvertOCXControls( rRoot.GetDocShell(), 0 ),
3210 maStdFormName( CREATE_OUSTRING( "Standard" ) ),
3211 mnOleImpFlags( 0 )
3212 {
3213 if( SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get() )
3214 {
3215 if( pFilterOpt->IsMathType2Math() )
3216 mnOleImpFlags |= OLE_MATHTYPE_2_STARMATH;
3217 if( pFilterOpt->IsWinWord2Writer() )
3218 mnOleImpFlags |= OLE_WINWORD_2_STARWRITER;
3219 if( pFilterOpt->IsPowerPoint2Impress() )
3220 mnOleImpFlags |= OLE_POWERPOINT_2_STARIMPRESS;
3221 }
3222
3223 // try to open the 'Ctls' storage stream containing OCX control properties
3224 mxCtlsStrm = OpenStream( EXC_STREAM_CTLS );
3225
3226 // default text margin (convert EMU to drawing layer units)
3227 mnDefTextMargin = EXC_OBJ_TEXT_MARGIN;
3228 ScaleEmu( mnDefTextMargin );
3229 }
3230
~XclImpDffConverter()3231 XclImpDffConverter::~XclImpDffConverter()
3232 {
3233 }
3234
StartProgressBar(sal_Size nProgressSize)3235 void XclImpDffConverter::StartProgressBar( sal_Size nProgressSize )
3236 {
3237 mxProgress.reset( new ScfProgressBar( GetDocShell(), STR_PROGRESS_CALCULATING ) );
3238 mxProgress->AddSegment( nProgressSize );
3239 mxProgress->Activate();
3240 }
3241
Progress(sal_Size nDelta)3242 void XclImpDffConverter::Progress( sal_Size nDelta )
3243 {
3244 DBG_ASSERT( mxProgress.is(), "XclImpDffConverter::Progress - invalid call, no progress bar" );
3245 mxProgress->Progress( nDelta );
3246 }
3247
InitializeDrawing(XclImpDrawing & rDrawing,SdrModel & rSdrModel,SdrPage & rSdrPage)3248 void XclImpDffConverter::InitializeDrawing( XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage )
3249 {
3250 XclImpDffConvDataRef xConvData( new XclImpDffConvData( rDrawing, rSdrModel, rSdrPage ) );
3251 maDataStack.push_back( xConvData );
3252 SetModel( &xConvData->mrSdrModel, 1440 );
3253 }
3254
ProcessObject(SdrObjList & rObjList,const XclImpDrawObjBase & rDrawObj)3255 void XclImpDffConverter::ProcessObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj )
3256 {
3257 if( rDrawObj.IsProcessSdrObj() )
3258 {
3259 if( const XclObjAnchor* pAnchor = rDrawObj.GetAnchor() )
3260 {
3261 Rectangle aAnchorRect = GetConvData().mrDrawing.CalcAnchorRect( *pAnchor, false );
3262 if( rDrawObj.IsValidSize( aAnchorRect ) )
3263 {
3264 // CreateSdrObject() recursively creates embedded child objects
3265 SdrObjectPtr xSdrObj( rDrawObj.CreateSdrObject( *this, aAnchorRect, false ) );
3266 if( xSdrObj.is() )
3267 rDrawObj.PreProcessSdrObject( *this, *xSdrObj );
3268 // call InsertSdrObject() also, if SdrObject is missing
3269 InsertSdrObject( rObjList, rDrawObj, xSdrObj.release() );
3270 }
3271 }
3272 }
3273 }
3274
ProcessDrawing(const XclImpDrawObjVector & rDrawObjs)3275 void XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector& rDrawObjs )
3276 {
3277 SdrPage& rSdrPage = GetConvData().mrSdrPage;
3278 for( XclImpDrawObjVector::const_iterator aIt = rDrawObjs.begin(), aEnd = rDrawObjs.end(); aIt != aEnd; ++aIt )
3279 ProcessObject( rSdrPage, **aIt );
3280 }
3281
ProcessDrawing(SvStream & rDffStrm)3282 void XclImpDffConverter::ProcessDrawing( SvStream& rDffStrm )
3283 {
3284 rDffStrm.Seek( STREAM_SEEK_TO_END );
3285 if( rDffStrm.Tell() > 0 )
3286 {
3287 rDffStrm.Seek( STREAM_SEEK_TO_BEGIN );
3288 DffRecordHeader aHeader;
3289 rDffStrm >> aHeader;
3290 DBG_ASSERT( aHeader.nRecType == DFF_msofbtDgContainer, "XclImpDffConverter::ProcessDrawing - unexpected record" );
3291 if( aHeader.nRecType == DFF_msofbtDgContainer )
3292 ProcessDgContainer( rDffStrm, aHeader );
3293 }
3294 }
3295
FinalizeDrawing()3296 void XclImpDffConverter::FinalizeDrawing()
3297 {
3298 DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" );
3299 maDataStack.pop_back();
3300 // restore previous model at core DFF converter
3301 if( !maDataStack.empty() )
3302 SetModel( &maDataStack.back()->mrSdrModel, 1440 );
3303 }
3304
CreateSdrObject(const XclImpTbxObjBase & rTbxObj,const Rectangle & rAnchorRect)3305 SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase& rTbxObj, const Rectangle& rAnchorRect )
3306 {
3307 SdrObjectPtr xSdrObj;
3308
3309 OUString aServiceName = rTbxObj.GetServiceName();
3310 if( SupportsOleObjects() && (aServiceName.getLength() > 0) ) try
3311 {
3312 // create the form control from scratch
3313 Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW );
3314 // set controls form, needed in virtual function InsertControl()
3315 InitControlForm();
3316 // try to insert the control into the form
3317 ::com::sun::star::awt::Size aDummySize;
3318 Reference< XShape > xShape;
3319 XclImpDffConvData& rConvData = GetConvData();
3320 if( rConvData.mxCtrlForm.is() && InsertControl( xFormComp, aDummySize, &xShape, sal_True ) )
3321 {
3322 xSdrObj.reset( rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
3323 // try to attach a macro to the control
3324 ScriptEventDescriptor aDescriptor;
3325 if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) )
3326 {
3327 Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW );
3328 xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor );
3329 }
3330 }
3331 }
3332 catch( Exception& )
3333 {
3334 }
3335
3336 return xSdrObj.release();
3337 }
3338
CreateSdrObject(const XclImpPictureObj & rPicObj,const Rectangle & rAnchorRect)3339 SdrObject* XclImpDffConverter::CreateSdrObject( const XclImpPictureObj& rPicObj, const Rectangle& rAnchorRect )
3340 {
3341 SdrObjectPtr xSdrObj;
3342
3343 if( SupportsOleObjects() )
3344 {
3345 if( rPicObj.IsOcxControl() )
3346 {
3347 if( mxCtlsStrm.Is() ) try
3348 {
3349 /* set controls form, needed in virtual function InsertControl()
3350 called from ReadOCXExcelKludgeStream() */
3351 InitControlForm();
3352 // seek to stream position of the extra data for this control
3353 mxCtlsStrm->Seek( rPicObj.GetCtlsStreamPos() );
3354 // read from mxCtlsStrm into xShape, insert the control model into the form
3355 Reference< XShape > xShape;
3356 if( GetConvData().mxCtrlForm.is() && ReadOCXExcelKludgeStream( mxCtlsStrm, &xShape, sal_True ) )
3357 xSdrObj.reset( rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect ) );
3358 }
3359 catch( Exception& )
3360 {
3361 }
3362 }
3363 else
3364 {
3365 SfxObjectShell* pDocShell = GetDocShell();
3366 SotStorageRef xSrcStrg = GetRootStorage();
3367 String aStrgName = rPicObj.GetOleStorageName();
3368 if( pDocShell && xSrcStrg.Is() && (aStrgName.Len() > 0) )
3369 {
3370 // first try to resolve graphic from DFF storage
3371 Graphic aGraphic;
3372 Rectangle aVisArea;
3373 if( !GetBLIP( GetPropertyValue( DFF_Prop_pib ), aGraphic, &aVisArea ) )
3374 {
3375 // if not found, use graphic from object (imported from IMGDATA record)
3376 aGraphic = rPicObj.GetGraphic();
3377 aVisArea = rPicObj.GetVisArea();
3378 }
3379 if( aGraphic.GetType() != GRAPHIC_NONE )
3380 {
3381 ErrCode nError = ERRCODE_NONE;
3382 namespace cssea = ::com::sun::star::embed::Aspects;
3383 sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT;
3384 xSdrObj.reset( CreateSdrOLEFromStorage(
3385 aStrgName, xSrcStrg, pDocShell->GetStorage(), aGraphic,
3386 rAnchorRect, aVisArea, 0, nError, mnOleImpFlags, nAspects ) );
3387 }
3388 }
3389 }
3390 }
3391
3392 return xSdrObj.release();
3393 }
3394
SupportsOleObjects() const3395 bool XclImpDffConverter::SupportsOleObjects() const
3396 {
3397 return GetConvData().mrDrawing.SupportsOleObjects();
3398 }
3399
3400 // virtual functions ----------------------------------------------------------
3401
ProcessClientAnchor2(SvStream & rDffStrm,DffRecordHeader & rHeader,void *,DffObjData & rObjData)3402 void XclImpDffConverter::ProcessClientAnchor2( SvStream& rDffStrm,
3403 DffRecordHeader& rHeader, void* /*pClientData*/, DffObjData& rObjData )
3404 {
3405 // find the OBJ record data related to the processed shape
3406 XclImpDffConvData& rConvData = GetConvData();
3407 if( XclImpDrawObjBase* pDrawObj = rConvData.mrDrawing.FindDrawObj( rObjData.rSpHd ).get() )
3408 {
3409 DBG_ASSERT( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" );
3410 XclObjAnchor aAnchor;
3411 rHeader.SeekToContent( rDffStrm );
3412 rDffStrm.SeekRel( 2 ); // flags
3413 rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records
3414 pDrawObj->SetAnchor( aAnchor );
3415 rObjData.aChildAnchor = rConvData.mrDrawing.CalcAnchorRect( aAnchor, true );
3416 rObjData.bChildAnchor = sal_True;
3417 }
3418 }
3419
ProcessObj(SvStream & rDffStrm,DffObjData & rDffObjData,void * pClientData,Rectangle &,SdrObject * pOldSdrObj)3420 SdrObject* XclImpDffConverter::ProcessObj( SvStream& rDffStrm, DffObjData& rDffObjData,
3421 void* pClientData, Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj )
3422 {
3423 XclImpDffConvData& rConvData = GetConvData();
3424
3425 /* pOldSdrObj passes a generated SdrObject. This function owns this object
3426 and can modify it. The function has either to return it back to caller
3427 or to delete it by itself. */
3428 SdrObjectPtr xSdrObj( pOldSdrObj );
3429
3430 // find the OBJ record data related to the processed shape
3431 XclImpDrawObjRef xDrawObj = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd );
3432 const Rectangle& rAnchorRect = rDffObjData.aChildAnchor;
3433
3434 // #102378# Do not process the global page group shape (flag SP_FPATRIARCH)
3435 bool bGlobalPageGroup = ::get_flag< sal_uInt32 >( rDffObjData.nSpFlags, SP_FPATRIARCH );
3436 if( !xDrawObj || !xDrawObj->IsProcessSdrObj() || bGlobalPageGroup )
3437 return 0; // simply return, xSdrObj will be destroyed
3438
3439 /* Pass pointer to top-level object back to caller. If the processed
3440 object is embedded in a group, the pointer is already set to the
3441 top-level parent object. */
3442 XclImpDrawObjBase** ppTopLevelObj = reinterpret_cast< XclImpDrawObjBase** >( pClientData );
3443 bool bIsTopLevel = !ppTopLevelObj || !*ppTopLevelObj;
3444 if( ppTopLevelObj && bIsTopLevel )
3445 *ppTopLevelObj = xDrawObj.get();
3446
3447 // #119010# connectors don't have to be area objects
3448 if( dynamic_cast< SdrEdgeObj* >( xSdrObj.get() ) )
3449 xDrawObj->SetAreaObj( false );
3450
3451 /* Check for valid size for all objects. Needed to ignore lots of invisible
3452 phantom objects from deleted rows or columns (for performance reasons).
3453 #i30816# Include objects embedded in groups.
3454 #i58780# Ignore group shapes, size is not initialized. */
3455 bool bEmbeddedGroup = !bIsTopLevel && dynamic_cast< SdrObjGroup* >( xSdrObj.get() );
3456 if( !bEmbeddedGroup && !xDrawObj->IsValidSize( rAnchorRect ) )
3457 return 0; // simply return, xSdrObj will be destroyed
3458
3459 // set shape information from DFF stream
3460 String aObjName = GetPropertyString( DFF_Prop_wzName, rDffStrm );
3461 String aHyperlink = ReadHlinkProperty( rDffStrm );
3462 bool bVisible = !GetPropertyBool( DFF_Prop_fHidden );
3463 bool bAutoMargin = GetPropertyBool( DFF_Prop_AutoTextMargin );
3464 xDrawObj->SetDffData( rDffObjData, aObjName, aHyperlink, bVisible, bAutoMargin );
3465
3466 /* Connect textbox data (string, alignment, text orientation) to object.
3467 #98132# don't ask for a text-ID, DFF export doesn't set one. */
3468 if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) )
3469 if( const XclImpObjTextData* pTextData = rConvData.mrDrawing.FindTextData( rDffObjData.rSpHd ) )
3470 pTextObj->SetTextData( *pTextData );
3471
3472 // copy line and fill formatting of TBX form controls from DFF properties
3473 if( XclImpTbxObjBase* pTbxObj = dynamic_cast< XclImpTbxObjBase* >( xDrawObj.get() ) )
3474 pTbxObj->SetDffProperties( *this );
3475
3476 // try to create a custom SdrObject that overwrites the passed object
3477 SdrObjectPtr xNewSdrObj( xDrawObj->CreateSdrObject( *this, rAnchorRect, true ) );
3478 if( xNewSdrObj.is() )
3479 xSdrObj.reset( xNewSdrObj.release() );
3480
3481 // process the SdrObject
3482 if( xSdrObj.is() )
3483 {
3484 // filled without color -> set system window color
3485 if( GetPropertyBool( DFF_Prop_fFilled ) && !IsProperty( DFF_Prop_fillColor ) )
3486 xSdrObj->SetMergedItem( XFillColorItem( EMPTY_STRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) );
3487
3488 // additional processing on the SdrObject
3489 xDrawObj->PreProcessSdrObject( *this, *xSdrObj );
3490
3491 /* If the SdrObject will not be inserted into the draw page, delete it
3492 here. Happens e.g. for notes: The PreProcessSdrObject() call above
3493 has inserted the note into the document, and the SdrObject is not
3494 needed anymore. */
3495 if( !xDrawObj->IsInsertSdrObj() )
3496 xSdrObj.reset();
3497 }
3498
3499 if( xSdrObj.is() )
3500 {
3501 /* Store the relation between shape ID and SdrObject for connectors.
3502 Must be done here (and not in InsertSdrObject() function),
3503 otherwise all SdrObjects embedded in groups would be lost. */
3504 rConvData.maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() );
3505
3506 /* If the drawing object is embedded in a group object, call
3507 PostProcessSdrObject() here. For top-level objects this will be
3508 done automatically in InsertSdrObject() but grouped shapes are
3509 inserted into their groups somewhere in the SvxMSDffManager base
3510 class without chance of notification. Unfortunately, now this is
3511 called before the object is really inserted into its group object,
3512 but that should not have any effect for grouped objects. */
3513 if( !bIsTopLevel )
3514 xDrawObj->PostProcessSdrObject( *this, *xSdrObj );
3515 }
3516
3517 return xSdrObj.release();
3518 }
3519
Calc_nBLIPPos(sal_uLong,sal_uLong nStreamPos) const3520 sal_uLong XclImpDffConverter::Calc_nBLIPPos( sal_uLong /*nOrgVal*/, sal_uLong nStreamPos ) const
3521 {
3522 return nStreamPos + 4;
3523 }
3524
InsertControl(const Reference<XFormComponent> & rxFormComp,const::com::sun::star::awt::Size &,Reference<XShape> * pxShape,sal_Bool)3525 sal_Bool XclImpDffConverter::InsertControl( const Reference< XFormComponent >& rxFormComp,
3526 const ::com::sun::star::awt::Size& /*rSize*/, Reference< XShape >* pxShape,
3527 sal_Bool /*bFloatingCtrl*/ )
3528 {
3529 if( GetDocShell() ) try
3530 {
3531 XclImpDffConvData& rConvData = GetConvData();
3532 Reference< XIndexContainer > xFormIC( rConvData.mxCtrlForm, UNO_QUERY_THROW );
3533 Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW );
3534
3535 // create the control shape
3536 Reference< XShape > xShape( ScfApiHelper::CreateInstance( GetDocShell(), CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ) ), UNO_QUERY_THROW );
3537 Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY_THROW );
3538
3539 // insert the new control into the form
3540 sal_Int32 nNewIndex = xFormIC->getCount();
3541 xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) );
3542 // on success: store new index of the control for later use (macro events)
3543 rConvData.mnLastCtrlIndex = nNewIndex;
3544
3545 // set control model at control shape and pass back shape to caller
3546 xCtrlShape->setControl( xCtrlModel );
3547 if( pxShape ) *pxShape = xShape;
3548 return sal_True;
3549 }
3550 catch( Exception& )
3551 {
3552 DBG_ERRORFILE( "XclImpDffConverter::InsertControl - cannot create form control" );
3553 }
3554
3555 return sal_False;
3556 }
3557
3558 // private --------------------------------------------------------------------
3559
GetConvData()3560 XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData()
3561 {
3562 DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3563 return *maDataStack.back();
3564 }
3565
GetConvData() const3566 const XclImpDffConverter::XclImpDffConvData& XclImpDffConverter::GetConvData() const
3567 {
3568 DBG_ASSERT( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3569 return *maDataStack.back();
3570 }
3571
ReadHlinkProperty(SvStream & rDffStrm) const3572 String XclImpDffConverter::ReadHlinkProperty( SvStream& rDffStrm ) const
3573 {
3574 /* Reads hyperlink data from a complex DFF property. Contents of this
3575 property are equal to the HLINK record, import of this record is
3576 implemented in class XclImpHyperlink. This function has to create an
3577 instance of the XclImpStream class to be able to reuse the
3578 functionality of XclImpHyperlink. */
3579 String aString;
3580 sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape );
3581 if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rDffStrm ) )
3582 {
3583 // create a faked BIFF record that can be read by XclImpStream class
3584 SvMemoryStream aMemStream;
3585 aMemStream << sal_uInt16( 0 ) << static_cast< sal_uInt16 >( nBufferSize );
3586
3587 // copy from DFF stream to memory stream
3588 ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
3589 sal_uInt8* pnData = &aBuffer.front();
3590 if( rDffStrm.Read( pnData, nBufferSize ) == nBufferSize )
3591 {
3592 aMemStream.Write( pnData, nBufferSize );
3593
3594 // create BIFF import stream to be able to use XclImpHyperlink class
3595 XclImpStream aXclStrm( aMemStream, GetRoot() );
3596 if( aXclStrm.StartNextRecord() )
3597 aString = XclImpHyperlink::ReadEmbeddedData( aXclStrm );
3598 }
3599 }
3600 return aString;
3601 }
3602
ProcessDgContainer(SvStream & rDffStrm,const DffRecordHeader & rDgHeader)3603 void XclImpDffConverter::ProcessDgContainer( SvStream& rDffStrm, const DffRecordHeader& rDgHeader )
3604 {
3605 sal_Size nEndPos = rDgHeader.GetRecEndFilePos();
3606 while( rDffStrm.Tell() < nEndPos )
3607 {
3608 DffRecordHeader aHeader;
3609 rDffStrm >> aHeader;
3610 switch( aHeader.nRecType )
3611 {
3612 case DFF_msofbtSolverContainer:
3613 ProcessSolverContainer( rDffStrm, aHeader );
3614 break;
3615 case DFF_msofbtSpgrContainer:
3616 ProcessShGrContainer( rDffStrm, aHeader );
3617 break;
3618 default:
3619 aHeader.SeekToEndOfRecord( rDffStrm );
3620 }
3621 }
3622 // seek to end of drawing page container
3623 rDgHeader.SeekToEndOfRecord( rDffStrm );
3624
3625 // #i12638# #i37900# connector rules
3626 XclImpSolverContainer& rSolverCont = GetConvData().maSolverCont;
3627 rSolverCont.UpdateConnectorRules();
3628 SolveSolver( rSolverCont );
3629 rSolverCont.RemoveConnectorRules();
3630 }
3631
ProcessShGrContainer(SvStream & rDffStrm,const DffRecordHeader & rShGrHeader)3632 void XclImpDffConverter::ProcessShGrContainer( SvStream& rDffStrm, const DffRecordHeader& rShGrHeader )
3633 {
3634 sal_Size nEndPos = rShGrHeader.GetRecEndFilePos();
3635 while( rDffStrm.Tell() < nEndPos )
3636 {
3637 DffRecordHeader aHeader;
3638 rDffStrm >> aHeader;
3639 switch( aHeader.nRecType )
3640 {
3641 case DFF_msofbtSpgrContainer:
3642 case DFF_msofbtSpContainer:
3643 ProcessShContainer( rDffStrm, aHeader );
3644 break;
3645 default:
3646 aHeader.SeekToEndOfRecord( rDffStrm );
3647 }
3648 }
3649 // seek to end of shape group container
3650 rShGrHeader.SeekToEndOfRecord( rDffStrm );
3651 }
3652
ProcessSolverContainer(SvStream & rDffStrm,const DffRecordHeader & rSolverHeader)3653 void XclImpDffConverter::ProcessSolverContainer( SvStream& rDffStrm, const DffRecordHeader& rSolverHeader )
3654 {
3655 // solver container wants to read the solver container header again
3656 rSolverHeader.SeekToBegOfRecord( rDffStrm );
3657 // read the entire solver container
3658 rDffStrm >> GetConvData().maSolverCont;
3659 // seek to end of solver container
3660 rSolverHeader.SeekToEndOfRecord( rDffStrm );
3661 }
3662
ProcessShContainer(SvStream & rDffStrm,const DffRecordHeader & rShHeader)3663 void XclImpDffConverter::ProcessShContainer( SvStream& rDffStrm, const DffRecordHeader& rShHeader )
3664 {
3665 rShHeader.SeekToBegOfRecord( rDffStrm );
3666 Rectangle aDummy;
3667 const XclImpDrawObjBase* pDrawObj = 0;
3668 /* The call to ImportObj() creates and returns a new SdrObject for the
3669 processed shape. We take ownership of the returned object here. If the
3670 shape is a group object, all embedded objects are created recursively,
3671 and the returned group object contains them all. ImportObj() calls the
3672 virtual functions ProcessClientAnchor2() and ProcessObj() and writes
3673 the pointer to the related draw object data (OBJ record) into pDrawObj. */
3674 SdrObjectPtr xSdrObj( ImportObj( rDffStrm, &pDrawObj, aDummy, aDummy, 0, 0 ) );
3675 if( pDrawObj && xSdrObj.is() )
3676 InsertSdrObject( GetConvData().mrSdrPage, *pDrawObj, xSdrObj.release() );
3677 rShHeader.SeekToEndOfRecord( rDffStrm );
3678 }
3679
InsertSdrObject(SdrObjList & rObjList,const XclImpDrawObjBase & rDrawObj,SdrObject * pSdrObj)3680 void XclImpDffConverter::InsertSdrObject( SdrObjList& rObjList, const XclImpDrawObjBase& rDrawObj, SdrObject* pSdrObj )
3681 {
3682 XclImpDffConvData& rConvData = GetConvData();
3683 /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
3684 states to skip insertion), the object is automatically deleted. */
3685 SdrObjectPtr xSdrObj( pSdrObj );
3686 if( xSdrObj.is() && rDrawObj.IsInsertSdrObj() )
3687 {
3688 rObjList.NbcInsertObject( xSdrObj.release() );
3689 // callback to drawing manager for e.g. tracking of used sheet area
3690 rConvData.mrDrawing.OnObjectInserted( rDrawObj );
3691 // callback to drawing object for post processing (use pSdrObj, xSdrObj already released)
3692 rDrawObj.PostProcessSdrObject( *this, *pSdrObj );
3693 }
3694 /* SdrObject still here? Insertion failed, remove data from shape ID map.
3695 The SdrObject will be destructed then. */
3696 if( xSdrObj.is() )
3697 rConvData.maSolverCont.RemoveSdrObjectInfo( *xSdrObj );
3698 }
3699
InitControlForm()3700 void XclImpDffConverter::InitControlForm()
3701 {
3702 XclImpDffConvData& rConvData = GetConvData();
3703 if( rConvData.mbHasCtrlForm )
3704 return;
3705
3706 rConvData.mbHasCtrlForm = true;
3707 if( SupportsOleObjects() ) try
3708 {
3709 Reference< XFormsSupplier > xFormsSupplier( rConvData.mrSdrPage.getUnoPage(), UNO_QUERY_THROW );
3710 Reference< XNameContainer > xFormsNC( xFormsSupplier->getForms(), UNO_SET_THROW );
3711 // find or create the Standard form used to insert the imported controls
3712 if( xFormsNC->hasByName( maStdFormName ) )
3713 {
3714 xFormsNC->getByName( maStdFormName ) >>= rConvData.mxCtrlForm;
3715 }
3716 else if( SfxObjectShell* pDocShell = GetDocShell() )
3717 {
3718 rConvData.mxCtrlForm.set( ScfApiHelper::CreateInstance( pDocShell, CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), UNO_QUERY_THROW );
3719 xFormsNC->insertByName( maStdFormName, Any( rConvData.mxCtrlForm ) );
3720 }
3721 }
3722 catch( Exception& )
3723 {
3724 }
3725 }
3726
3727 // Drawing manager ============================================================
3728
XclImpDrawing(const XclImpRoot & rRoot,bool bOleObjects)3729 XclImpDrawing::XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ) :
3730 XclImpRoot( rRoot ),
3731 mbOleObjs( bOleObjects )
3732 {
3733 }
3734
~XclImpDrawing()3735 XclImpDrawing::~XclImpDrawing()
3736 {
3737 }
3738
ReadImgData(const XclImpRoot & rRoot,XclImpStream & rStrm)3739 /*static*/ Graphic XclImpDrawing::ReadImgData( const XclImpRoot& rRoot, XclImpStream& rStrm )
3740 {
3741 Graphic aGraphic;
3742 sal_uInt16 nFormat, nEnv;
3743 sal_uInt32 nDataSize;
3744 rStrm >> nFormat >> nEnv >> nDataSize;
3745 if( nDataSize <= rStrm.GetRecLeft() )
3746 {
3747 switch( nFormat )
3748 {
3749 case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rRoot, rStrm ); break;
3750 case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rRoot, rStrm ); break;
3751 default: DBG_ERRORFILE( "XclImpDrawing::ReadImgData - unknown image format" );
3752 }
3753 }
3754 return aGraphic;
3755 }
3756
ReadObj(XclImpStream & rStrm)3757 void XclImpDrawing::ReadObj( XclImpStream& rStrm )
3758 {
3759 XclImpDrawObjRef xDrawObj;
3760
3761 /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
3762 records. In this case, the OBJ records are in BIFF5 format. Do a sanity
3763 check here that there is no DFF data loaded before. */
3764 DBG_ASSERT( maDffStrm.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
3765 if( maDffStrm.Tell() == 0 ) switch( GetBiff() )
3766 {
3767 case EXC_BIFF3:
3768 xDrawObj = XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm );
3769 break;
3770 case EXC_BIFF4:
3771 xDrawObj = XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm );
3772 break;
3773 case EXC_BIFF5:
3774 case EXC_BIFF8:
3775 xDrawObj = XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm );
3776 break;
3777 default:
3778 DBG_ERROR_BIFF();
3779 }
3780
3781 if( xDrawObj.is() )
3782 {
3783 // insert into maRawObjs or into the last open group object
3784 maRawObjs.InsertGrouped( xDrawObj );
3785 // to be able to find objects by ID
3786 maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
3787 }
3788 }
3789
ReadMsoDrawing(XclImpStream & rStrm)3790 void XclImpDrawing::ReadMsoDrawing( XclImpStream& rStrm )
3791 {
3792 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
3793 // disable internal CONTINUE handling
3794 rStrm.ResetRecord( false );
3795 // read leading MSODRAWING record
3796 ReadDffRecord( rStrm );
3797
3798 // read following drawing records, but do not start following unrelated record
3799 bool bLoop = true;
3800 while( bLoop ) switch( rStrm.GetNextRecId() )
3801 {
3802 case EXC_ID_MSODRAWING:
3803 case EXC_ID_MSODRAWINGSEL:
3804 case EXC_ID_CONT:
3805 rStrm.StartNextRecord();
3806 ReadDffRecord( rStrm );
3807 break;
3808 case EXC_ID_OBJ:
3809 rStrm.StartNextRecord();
3810 ReadObj8( rStrm );
3811 break;
3812 case EXC_ID_TXO:
3813 rStrm.StartNextRecord();
3814 ReadTxo( rStrm );
3815 break;
3816 default:
3817 bLoop = false;
3818 }
3819
3820 // re-enable internal CONTINUE handling
3821 rStrm.ResetRecord( true );
3822 }
3823
FindDrawObj(const DffRecordHeader & rHeader) const3824 XclImpDrawObjRef XclImpDrawing::FindDrawObj( const DffRecordHeader& rHeader ) const
3825 {
3826 /* maObjMap stores objects by position of the client data (OBJ record) in
3827 the DFF stream, which is always behind shape start position of the
3828 passed header. The function upper_bound() finds the first element in
3829 the map whose key is greater than the start position of the header. Its
3830 end position is used to test whether the found object is really related
3831 to the shape. */
3832 XclImpDrawObjRef xDrawObj;
3833 XclImpObjMap::const_iterator aIt = maObjMap.upper_bound( rHeader.GetRecBegFilePos() );
3834 if( (aIt != maObjMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
3835 xDrawObj = aIt->second;
3836 return xDrawObj;
3837 }
3838
FindDrawObj(sal_uInt16 nObjId) const3839 XclImpDrawObjRef XclImpDrawing::FindDrawObj( sal_uInt16 nObjId ) const
3840 {
3841 XclImpDrawObjRef xDrawObj;
3842 XclImpObjMapById::const_iterator aIt = maObjMapId.find( nObjId );
3843 if( aIt != maObjMapId.end() )
3844 xDrawObj = aIt->second;
3845 return xDrawObj;
3846 }
3847
FindTextData(const DffRecordHeader & rHeader) const3848 const XclImpObjTextData* XclImpDrawing::FindTextData( const DffRecordHeader& rHeader ) const
3849 {
3850 /* maTextMap stores textbox data by position of the client data (TXO
3851 record) in the DFF stream, which is always behind shape start position
3852 of the passed header. The function upper_bound() finds the first
3853 element in the map whose key is greater than the start position of the
3854 header. Its end position is used to test whether the found object is
3855 really related to the shape. */
3856 XclImpObjTextMap::const_iterator aIt = maTextMap.upper_bound( rHeader.GetRecBegFilePos() );
3857 if( (aIt != maTextMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
3858 return aIt->second.get();
3859 return 0;
3860 }
3861
SetSkipObj(sal_uInt16 nObjId)3862 void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId )
3863 {
3864 maSkipObjs.push_back( nObjId );
3865 }
3866
GetProgressSize() const3867 sal_Size XclImpDrawing::GetProgressSize() const
3868 {
3869 sal_Size nProgressSize = maRawObjs.GetProgressSize();
3870 for( XclImpObjMap::const_iterator aIt = maObjMap.begin(), aEnd = maObjMap.end(); aIt != aEnd; ++aIt )
3871 nProgressSize += aIt->second->GetProgressSize();
3872 return nProgressSize;
3873 }
3874
ImplConvertObjects(XclImpDffConverter & rDffConv,SdrModel & rSdrModel,SdrPage & rSdrPage)3875 void XclImpDrawing::ImplConvertObjects( XclImpDffConverter& rDffConv, SdrModel& rSdrModel, SdrPage& rSdrPage )
3876 {
3877 // register this drawing manager at the passed (global) DFF manager
3878 rDffConv.InitializeDrawing( *this, rSdrModel, rSdrPage );
3879 // process list of objects to be skipped
3880 for( ScfUInt16Vec::const_iterator aIt = maSkipObjs.begin(), aEnd = maSkipObjs.end(); aIt != aEnd; ++aIt )
3881 if( XclImpDrawObjBase* pDrawObj = FindDrawObj( *aIt ).get() )
3882 pDrawObj->SetProcessSdrObj( false );
3883 // process drawing objects without DFF data
3884 rDffConv.ProcessDrawing( maRawObjs );
3885 // process all objects in the DFF stream
3886 rDffConv.ProcessDrawing( maDffStrm );
3887 // unregister this drawing manager at the passed (global) DFF manager
3888 rDffConv.FinalizeDrawing();
3889 }
3890
3891 // protected ------------------------------------------------------------------
3892
AppendRawObject(const XclImpDrawObjRef & rxDrawObj)3893 void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef& rxDrawObj )
3894 {
3895 DBG_ASSERT( rxDrawObj.is(), "XclImpDrawing::AppendRawObject - unexpected empty reference" );
3896 maRawObjs.push_back( rxDrawObj );
3897 }
3898
3899 // private --------------------------------------------------------------------
3900
ReadWmf(Graphic & rGraphic,const XclImpRoot &,XclImpStream & rStrm)3901 void XclImpDrawing::ReadWmf( Graphic& rGraphic, const XclImpRoot&, XclImpStream& rStrm ) // static helper
3902 {
3903 // extract graphic data from IMGDATA and following CONTINUE records
3904 rStrm.Ignore( 8 );
3905 SvMemoryStream aMemStrm;
3906 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3907 aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
3908 // import the graphic from memory stream
3909 GDIMetaFile aGDIMetaFile;
3910 if( ::ReadWindowMetafile( aMemStrm, aGDIMetaFile, 0 ) )
3911 rGraphic = aGDIMetaFile;
3912 }
3913
ReadBmp(Graphic & rGraphic,const XclImpRoot & rRoot,XclImpStream & rStrm)3914 void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ) // static helper
3915 {
3916 // extract graphic data from IMGDATA and following CONTINUE records
3917 SvMemoryStream aMemStrm;
3918
3919 /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
3920 DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
3921 pixel depth = 32 bit. After that, 3 unused bytes are added before the
3922 actual pixel data. This does even confuse Excel 5 and later, which
3923 cannot read the image data correctly. */
3924 if( rRoot.GetBiff() <= EXC_BIFF4 )
3925 {
3926 rStrm.PushPosition();
3927 sal_uInt32 nHdrSize;
3928 sal_uInt16 nWidth, nHeight, nPlanes, nDepth;
3929 rStrm >> nHdrSize >> nWidth >> nHeight >> nPlanes >> nDepth;
3930 if( (nHdrSize == 12) && (nPlanes == 1) && (nDepth == 32) )
3931 {
3932 rStrm.Ignore( 3 );
3933 aMemStrm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
3934 aMemStrm << nHdrSize << nWidth << nHeight << nPlanes << nDepth;
3935 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3936 }
3937 rStrm.PopPosition();
3938 }
3939
3940 // no special handling above -> just copy the remaining record data
3941 if( aMemStrm.Tell() == 0 )
3942 rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
3943
3944 // import the graphic from memory stream
3945 aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
3946 Bitmap aBitmap;
3947 if( ReadDIB(aBitmap, aMemStrm, false) ) // read DIB without file header
3948 rGraphic = aBitmap;
3949 }
3950
ReadDffRecord(XclImpStream & rStrm)3951 void XclImpDrawing::ReadDffRecord( XclImpStream& rStrm )
3952 {
3953 maDffStrm.Seek( STREAM_SEEK_TO_END );
3954 rStrm.CopyRecordToStream( maDffStrm );
3955 }
3956
ReadObj8(XclImpStream & rStrm)3957 void XclImpDrawing::ReadObj8( XclImpStream& rStrm )
3958 {
3959 XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm );
3960
3961 if(xDrawObj.is())
3962 {
3963 // store the new object in the internal containers
3964 maObjMap[ maDffStrm.Tell() ] = xDrawObj;
3965 maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
3966 }
3967 else
3968 {
3969 OSL_ENSURE(false, "DrawObj could not be loaded (!)");
3970 }
3971 }
3972
ReadTxo(XclImpStream & rStrm)3973 void XclImpDrawing::ReadTxo( XclImpStream& rStrm )
3974 {
3975 XclImpObjTextRef xTextData( new XclImpObjTextData );
3976 maTextMap[ maDffStrm.Tell() ] = xTextData;
3977
3978 // 1) read the TXO record
3979 xTextData->maData.ReadTxo8( rStrm );
3980
3981 // 2) first CONTINUE with string
3982 xTextData->mxString.reset();
3983 bool bValid = true;
3984 if( xTextData->maData.mnTextLen > 0 )
3985 {
3986 bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
3987 DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
3988 if( bValid )
3989 xTextData->mxString.reset( new XclImpString( rStrm.ReadUniString( xTextData->maData.mnTextLen ) ) );
3990 }
3991
3992 // 3) second CONTINUE with formatting runs
3993 if( xTextData->maData.mnFormatSize > 0 )
3994 {
3995 bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
3996 DBG_ASSERT( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
3997 if( bValid )
3998 xTextData->ReadFormats( rStrm );
3999 }
4000 }
4001
4002 // ----------------------------------------------------------------------------
4003
XclImpSheetDrawing(const XclImpRoot & rRoot,SCTAB nScTab)4004 XclImpSheetDrawing::XclImpSheetDrawing( const XclImpRoot& rRoot, SCTAB nScTab ) :
4005 XclImpDrawing( rRoot, true ),
4006 maScUsedArea( ScAddress::INITIALIZE_INVALID )
4007 {
4008 maScUsedArea.aStart.SetTab( nScTab );
4009 maScUsedArea.aEnd.SetTab( nScTab );
4010 }
4011
ReadNote(XclImpStream & rStrm)4012 void XclImpSheetDrawing::ReadNote( XclImpStream& rStrm )
4013 {
4014 switch( GetBiff() )
4015 {
4016 case EXC_BIFF2:
4017 case EXC_BIFF3:
4018 case EXC_BIFF4:
4019 case EXC_BIFF5:
4020 ReadNote3( rStrm );
4021 break;
4022 case EXC_BIFF8:
4023 ReadNote8( rStrm );
4024 break;
4025 default:
4026 DBG_ERROR_BIFF();
4027 }
4028 }
4029
ReadTabChart(XclImpStream & rStrm)4030 void XclImpSheetDrawing::ReadTabChart( XclImpStream& rStrm )
4031 {
4032 DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF5 );
4033 ScfRef< XclImpChartObj > xChartObj( new XclImpChartObj( GetRoot(), true ) );
4034 xChartObj->ReadChartSubStream( rStrm );
4035 // insert the chart as raw object without connected DFF data
4036 AppendRawObject( xChartObj );
4037 }
4038
ConvertObjects(XclImpDffConverter & rDffConv)4039 void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter& rDffConv )
4040 {
4041 if( SdrModel* pSdrModel = GetDoc().GetDrawLayer() )
4042 if( SdrPage* pSdrPage = GetSdrPage( maScUsedArea.aStart.Tab() ) )
4043 ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
4044 }
4045
CalcAnchorRect(const XclObjAnchor & rAnchor,bool) const4046 Rectangle XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool /*bDffAnchor*/ ) const
4047 {
4048 return rAnchor.GetRect( GetRoot(), maScUsedArea.aStart.Tab(), MAP_100TH_MM );
4049 }
4050
OnObjectInserted(const XclImpDrawObjBase & rDrawObj)4051 void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase& rDrawObj )
4052 {
4053 ScRange aScObjArea = rDrawObj.GetUsedArea( maScUsedArea.aStart.Tab() );
4054 if( aScObjArea.IsValid() )
4055 maScUsedArea.ExtendTo( aScObjArea );
4056 }
4057
4058 // private --------------------------------------------------------------------
4059
ReadNote3(XclImpStream & rStrm)4060 void XclImpSheetDrawing::ReadNote3( XclImpStream& rStrm )
4061 {
4062 XclAddress aXclPos;
4063 sal_uInt16 nTotalLen;
4064 rStrm >> aXclPos >> nTotalLen;
4065
4066 ScAddress aScNotePos( ScAddress::UNINITIALIZED );
4067 if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
4068 {
4069 sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) );
4070 String aNoteText = rStrm.ReadRawByteString( nPartLen );
4071 nTotalLen = nTotalLen - nPartLen;
4072 while( (nTotalLen > 0) && (rStrm.GetNextRecId() == EXC_ID_NOTE) && rStrm.StartNextRecord() )
4073 {
4074 rStrm >> aXclPos >> nPartLen;
4075 DBG_ASSERT( aXclPos.mnRow == 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
4076 if( aXclPos.mnRow == 0xFFFF )
4077 {
4078 DBG_ASSERT( nPartLen <= nTotalLen, "XclImpObjectManager::ReadNote3 - string too long" );
4079 aNoteText.Append( rStrm.ReadRawByteString( nPartLen ) );
4080 nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen );
4081 }
4082 else
4083 {
4084 // seems to be a new note, record already started -> load the note
4085 rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
4086 ReadNote( rStrm );
4087 nTotalLen = 0;
4088 }
4089 }
4090 ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText, false, false );
4091 }
4092 }
4093
ReadNote8(XclImpStream & rStrm)4094 void XclImpSheetDrawing::ReadNote8( XclImpStream& rStrm )
4095 {
4096 XclAddress aXclPos;
4097 sal_uInt16 nFlags, nObjId;
4098 rStrm >> aXclPos >> nFlags >> nObjId;
4099
4100 ScAddress aScNotePos( ScAddress::UNINITIALIZED );
4101 if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
4102 if( nObjId != EXC_OBJ_INVALID_ID )
4103 if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( nObjId ).get() ) )
4104 pNoteObj->SetNoteData( aScNotePos, nFlags );
4105 }
4106
4107 // The object manager =========================================================
4108
XclImpObjectManager(const XclImpRoot & rRoot)4109 XclImpObjectManager::XclImpObjectManager( const XclImpRoot& rRoot ) :
4110 XclImpRoot( rRoot )
4111 {
4112 maDefObjNames[ EXC_OBJTYPE_GROUP ] = CREATE_STRING( "Group" );
4113 maDefObjNames[ EXC_OBJTYPE_LINE ] = CREATE_STRING( "Line" );
4114 maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = CREATE_STRING( "Rectangle" );
4115 maDefObjNames[ EXC_OBJTYPE_OVAL ] = CREATE_STRING( "Oval" );
4116 maDefObjNames[ EXC_OBJTYPE_ARC ] = CREATE_STRING( "Arc" );
4117 maDefObjNames[ EXC_OBJTYPE_CHART ] = CREATE_STRING( "Chart" );
4118 maDefObjNames[ EXC_OBJTYPE_TEXT ] = CREATE_STRING( "Text" );
4119 maDefObjNames[ EXC_OBJTYPE_BUTTON ] = CREATE_STRING( "Button" );
4120 maDefObjNames[ EXC_OBJTYPE_PICTURE ] = CREATE_STRING( "Picture" );
4121 maDefObjNames[ EXC_OBJTYPE_POLYGON ] = CREATE_STRING( "Freeform" );
4122 maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = CREATE_STRING( "Check Box" );
4123 maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = CREATE_STRING( "Option Button" );
4124 maDefObjNames[ EXC_OBJTYPE_EDIT ] = CREATE_STRING( "Edit Box" );
4125 maDefObjNames[ EXC_OBJTYPE_LABEL ] = CREATE_STRING( "Label" );
4126 maDefObjNames[ EXC_OBJTYPE_DIALOG ] = CREATE_STRING( "Dialog Frame" );
4127 maDefObjNames[ EXC_OBJTYPE_SPIN ] = CREATE_STRING( "Spinner" );
4128 maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = CREATE_STRING( "Scroll Bar" );
4129 maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = CREATE_STRING( "List Box" );
4130 maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = CREATE_STRING( "Group Box" );
4131 maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = CREATE_STRING( "Drop Down" );
4132 maDefObjNames[ EXC_OBJTYPE_NOTE ] = CREATE_STRING( "Comment" );
4133 maDefObjNames[ EXC_OBJTYPE_DRAWING ] = CREATE_STRING( "AutoShape" );
4134 }
4135
~XclImpObjectManager()4136 XclImpObjectManager::~XclImpObjectManager()
4137 {
4138 }
4139
ReadMsoDrawingGroup(XclImpStream & rStrm)4140 void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream& rStrm )
4141 {
4142 DBG_ASSERT_BIFF( GetBiff() == EXC_BIFF8 );
4143 // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
4144 rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP );
4145 maDggStrm.Seek( STREAM_SEEK_TO_END );
4146 rStrm.CopyRecordToStream( maDggStrm );
4147 }
4148
GetSheetDrawing(SCTAB nScTab)4149 XclImpSheetDrawing& XclImpObjectManager::GetSheetDrawing( SCTAB nScTab )
4150 {
4151 XclImpSheetDrawingRef& rxDrawing = maSheetDrawings[ nScTab ];
4152 if( !rxDrawing )
4153 rxDrawing.reset( new XclImpSheetDrawing( GetRoot(), nScTab ) );
4154 return *rxDrawing;
4155 }
4156
ConvertObjects()4157 void XclImpObjectManager::ConvertObjects()
4158 {
4159 RTL_LOGFILE_CONTEXT_AUTHOR( aLog, "sc", "dr104026", "XclImpObjectManager::ConvertObjects" );
4160
4161 // do nothing if the document does not contain a drawing layer
4162 if( !GetDoc().GetDrawLayer() )
4163 return;
4164
4165 // get total progress bar size for all sheet drawing managers
4166 sal_Size nProgressSize = 0;
4167 for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt )
4168 nProgressSize += aIt->second->GetProgressSize();
4169 // nothing to do if progress bar is zero (no objects present)
4170 if( nProgressSize == 0 )
4171 return;
4172
4173 XclImpDffConverter aDffConv( GetRoot(), maDggStrm );
4174 aDffConv.StartProgressBar( nProgressSize );
4175 for( XclImpSheetDrawingMap::iterator aIt = maSheetDrawings.begin(), aEnd = maSheetDrawings.end(); aIt != aEnd; ++aIt )
4176 aIt->second->ConvertObjects( aDffConv );
4177
4178 // #i112436# don't call ScChartListenerCollection::SetDirty here,
4179 // instead use InterpretDirtyCells in ScDocument::CalcAfterLoad.
4180 }
4181
GetDefaultObjName(const XclImpDrawObjBase & rDrawObj) const4182 String XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase& rDrawObj ) const
4183 {
4184 String aDefName;
4185 DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() );
4186 if( aIt != maDefObjNames.end() )
4187 aDefName.Append( aIt->second );
4188 return aDefName.Append( sal_Unicode( ' ' ) ).Append( String::CreateFromInt32( rDrawObj.GetObjId() ) );
4189 }
4190
GetUsedArea(SCTAB nScTab) const4191 ScRange XclImpObjectManager::GetUsedArea( SCTAB nScTab ) const
4192 {
4193 XclImpSheetDrawingMap::const_iterator aIt = maSheetDrawings.find( nScTab );
4194 if( aIt != maSheetDrawings.end() )
4195 return aIt->second->GetUsedArea();
4196 return ScRange( ScAddress::INITIALIZE_INVALID );
4197 }
4198
4199 // DFF property set helper ====================================================
4200
XclImpDffPropSet(const XclImpRoot & rRoot)4201 XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot& rRoot ) :
4202 XclImpRoot( rRoot ),
4203 maDffConv( rRoot, maDummyStrm )
4204 {
4205 }
4206
Read(XclImpStream & rStrm)4207 void XclImpDffPropSet::Read( XclImpStream& rStrm )
4208 {
4209 sal_uInt32 nPropSetSize;
4210
4211 rStrm.PushPosition();
4212 rStrm.Ignore( 4 );
4213 rStrm >> nPropSetSize;
4214 rStrm.PopPosition();
4215
4216 mxMemStrm.reset( new SvMemoryStream );
4217 rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize );
4218 mxMemStrm->Seek( STREAM_SEEK_TO_BEGIN );
4219 maDffConv.ReadPropSet( *mxMemStrm, 0 );
4220 }
4221
GetPropertyValue(sal_uInt16 nPropId,sal_uInt32 nDefault) const4222 sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId, sal_uInt32 nDefault ) const
4223 {
4224 return maDffConv.GetPropertyValue( nPropId, nDefault );
4225 }
4226
FillToItemSet(SfxItemSet & rItemSet) const4227 void XclImpDffPropSet::FillToItemSet( SfxItemSet& rItemSet ) const
4228 {
4229 if( mxMemStrm.get() )
4230 maDffConv.ApplyAttributes( *mxMemStrm, rItemSet );
4231 }
4232
operator >>(XclImpStream & rStrm,XclImpDffPropSet & rPropSet)4233 XclImpStream& operator>>( XclImpStream& rStrm, XclImpDffPropSet& rPropSet )
4234 {
4235 rPropSet.Read( rStrm );
4236 return rStrm;
4237 }
4238
4239 // ============================================================================
4240
4241