xref: /aoo4110/main/sc/source/filter/excel/xiescher.cxx (revision b1cdbd2c)
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