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