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