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