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