1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <xiescher.hxx>
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/VerticalAlignment.hpp>
32 #include <com/sun/star/drawing/XControlShape.hpp>
33 #include <com/sun/star/form/XForm.hpp>
34 #include <com/sun/star/form/XFormsSupplier.hpp>
35 #include <com/sun/star/form/binding/XBindableValue.hpp>
36 #include <com/sun/star/form/binding/XValueBinding.hpp>
37 #include <com/sun/star/form/binding/XListEntrySink.hpp>
38 #include <com/sun/star/form/binding/XListEntrySource.hpp>
39 #include <com/sun/star/script/ScriptEventDescriptor.hpp>
40 #include <com/sun/star/script/XEventAttacherManager.hpp>
41 #include <com/sun/star/beans/XPropertySet.hpp>
42 #include <com/sun/star/frame/XModel.hpp>
44 #include <sfx2/objsh.hxx>
45 #include <unotools/moduleoptions.hxx>
46 #include <unotools/configmgr.hxx>
47 #include <unotools/fltrcfg.hxx>
48 #include <vcl/dibtools.hxx>
49 #include <vcl/gdimtf.hxx>
50 #include <vcl/outdev.hxx>
51 #include <vcl/wmf.hxx>
52 #include <comphelper/classids.hxx>
53 #include <comphelper/documentinfo.hxx>
54 #include <o3tl/safeint.hxx>
55 #include <toolkit/helper/vclunohelper.hxx>
56 #include <basegfx/point/b2dpoint.hxx>
57 #include <basegfx/polygon/b2dpolygon.hxx>
58 #include <sal/log.hxx>
60 #include <svx/svdopath.hxx>
61 #include <svx/svdocirc.hxx>
62 #include <svx/svdoedge.hxx>
63 #include <svx/svdogrp.hxx>
64 #include <svx/svdoashp.hxx>
65 #include <svx/svdograf.hxx>
66 #include <svx/svdoole2.hxx>
67 #include <svx/svdouno.hxx>
68 #include <svx/svdpage.hxx>
69 #include <editeng/editobj.hxx>
70 #include <editeng/outliner.hxx>
71 #include <editeng/outlobj.hxx>
72 #include <svx/svditer.hxx>
73 #include <editeng/writingmodeitem.hxx>
74 #include <svx/xlnclit.hxx>
75 #include <svx/xlndsit.hxx>
76 #include <svx/xlnedcit.hxx>
77 #include <svx/xlnedit.hxx>
78 #include <svx/xlnedwit.hxx>
79 #include <svx/xlnstcit.hxx>
80 #include <svx/xlnstit.hxx>
81 #include <svx/xlnstwit.hxx>
82 #include <svx/xlnwtit.hxx>
83 #include <svx/sdasitm.hxx>
84 #include <svx/sdshcitm.hxx>
85 #include <svx/sdshitm.hxx>
86 #include <svx/sdsxyitm.hxx>
87 #include <svx/sdtagitm.hxx>
88 #include <svx/sdtditm.hxx>
90 #include <editeng/eeitem.hxx>
91 #include <svx/xflclit.hxx>
92 #include <sal/macros.h>
93 #include <editeng/adjustitem.hxx>
94 #include <svx/xfillit0.hxx>
95 #include <svx/xlineit0.hxx>
96 #include <svx/xlinjoit.hxx>
97 #include <svx/xlntrit.hxx>
98 #include <svx/xbtmpit.hxx>
99 #include <svx/xbitmap.hxx>
100 #include <svtools/embedhlp.hxx>
101 #include <sot/storage.hxx>
103 #include <document.hxx>
104 #include <drwlayer.hxx>
105 #include <userdat.hxx>
106 #include <unonames.hxx>
107 #include <convuno.hxx>
108 #include <postit.hxx>
109 #include <globstr.hrc>
110 #include <scresid.hxx>
112 #include <fprogressbar.hxx>
113 #include <xltracer.hxx>
114 #include <xistream.hxx>
115 #include <xihelper.hxx>
116 #include <xiformula.hxx>
117 #include <xilink.hxx>
118 #include <xistyle.hxx>
119 #include <xipage.hxx>
120 #include <xichart.hxx>
121 #include <xicontent.hxx>
122 #include <scextopt.hxx>
124 #include <namebuff.hxx>
125 #include <sfx2/docfile.hxx>
128 #include <string_view>
131 using namespace com::sun::star
;
132 using ::com::sun::star::uno::makeAny
;
133 using ::com::sun::star::uno::Any
;
134 using ::com::sun::star::beans::XPropertySet
;
135 using ::com::sun::star::uno::makeAny
;
136 using ::com::sun::star::uno::Exception
;
137 using ::com::sun::star::uno::Reference
;
138 using ::com::sun::star::uno::Sequence
;
139 using ::com::sun::star::uno::UNO_QUERY
;
140 using ::com::sun::star::uno::UNO_QUERY_THROW
;
141 using ::com::sun::star::uno::UNO_SET_THROW
;
142 using ::com::sun::star::beans::NamedValue
;
143 using ::com::sun::star::lang::XMultiServiceFactory
;
144 using ::com::sun::star::container::XIndexContainer
;
145 using ::com::sun::star::container::XNameContainer
;
146 using ::com::sun::star::frame::XModel
;
147 using ::com::sun::star::awt::XControlModel
;
148 using ::com::sun::star::embed::XEmbeddedObject
;
149 using ::com::sun::star::embed::XEmbedPersist
;
150 using ::com::sun::star::drawing::XControlShape
;
151 using ::com::sun::star::drawing::XShape
;
152 using ::com::sun::star::form::XFormComponent
;
153 using ::com::sun::star::form::XFormsSupplier
;
154 using ::com::sun::star::form::binding::XBindableValue
;
155 using ::com::sun::star::form::binding::XValueBinding
;
156 using ::com::sun::star::form::binding::XListEntrySink
;
157 using ::com::sun::star::form::binding::XListEntrySource
;
158 using ::com::sun::star::script::ScriptEventDescriptor
;
159 using ::com::sun::star::script::XEventAttacherManager
;
160 using ::com::sun::star::table::CellAddress
;
161 using ::com::sun::star::table::CellRangeAddress
;
163 // Drawing objects ============================================================
165 XclImpDrawObjBase::XclImpDrawObjBase( const XclImpRoot
& rRoot
) :
167 mnObjId( EXC_OBJ_INVALID_ID
),
169 mnObjType( EXC_OBJTYPE_UNKNOWN
),
171 mnDffFlags( ShapeFlag::NONE
),
172 mbHasAnchor( false ),
177 mbAutoMargin( true ),
178 mbSimpleMacro( true ),
179 mbProcessSdr( true ),
181 mbCustomDff( false ),
182 mbNotifyMacroEventRead( false )
186 XclImpDrawObjBase::~XclImpDrawObjBase()
190 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj3( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
192 XclImpDrawObjRef xDrawObj
;
194 if( rStrm
.GetRecLeft() >= 30 )
198 nObjType
= rStrm
.ReaduInt16();
201 case EXC_OBJTYPE_GROUP
: xDrawObj
= std::make_shared
<XclImpGroupObj
>( rRoot
); break;
202 case EXC_OBJTYPE_LINE
: xDrawObj
= std::make_shared
<XclImpLineObj
>( rRoot
); break;
203 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
= std::make_shared
<XclImpRectObj
>( rRoot
); break;
204 case EXC_OBJTYPE_OVAL
: xDrawObj
= std::make_shared
<XclImpOvalObj
>( rRoot
); break;
205 case EXC_OBJTYPE_ARC
: xDrawObj
= std::make_shared
<XclImpArcObj
>( rRoot
); break;
206 case EXC_OBJTYPE_CHART
: xDrawObj
= std::make_shared
<XclImpChartObj
>( rRoot
); break;
207 case EXC_OBJTYPE_TEXT
: xDrawObj
= std::make_shared
<XclImpTextObj
>( rRoot
); break;
208 case EXC_OBJTYPE_BUTTON
: xDrawObj
= std::make_shared
<XclImpButtonObj
>( rRoot
); break;
209 case EXC_OBJTYPE_PICTURE
: xDrawObj
= std::make_shared
<XclImpPictureObj
>( rRoot
); break;
211 SAL_WARN("sc.filter", "XclImpDrawObjBase::ReadObj3 - unknown object type 0x" << std::hex
<< nObjType
);
212 rRoot
.GetTracer().TraceUnsupportedObjects();
218 xDrawObj
= std::make_shared
<XclImpPhObj
>(rRoot
);
221 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
222 xDrawObj
->ImplReadObj3( rStrm
);
226 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj4( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
228 XclImpDrawObjRef xDrawObj
;
230 if( rStrm
.GetRecLeft() >= 30 )
234 nObjType
= rStrm
.ReaduInt16();
237 case EXC_OBJTYPE_GROUP
: xDrawObj
= std::make_shared
<XclImpGroupObj
>( rRoot
); break;
238 case EXC_OBJTYPE_LINE
: xDrawObj
= std::make_shared
<XclImpLineObj
>( rRoot
); break;
239 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
= std::make_shared
<XclImpRectObj
>( rRoot
); break;
240 case EXC_OBJTYPE_OVAL
: xDrawObj
= std::make_shared
<XclImpOvalObj
>( rRoot
); break;
241 case EXC_OBJTYPE_ARC
: xDrawObj
= std::make_shared
<XclImpArcObj
>( rRoot
); break;
242 case EXC_OBJTYPE_CHART
: xDrawObj
= std::make_shared
<XclImpChartObj
>( rRoot
); break;
243 case EXC_OBJTYPE_TEXT
: xDrawObj
= std::make_shared
<XclImpTextObj
>( rRoot
); break;
244 case EXC_OBJTYPE_BUTTON
: xDrawObj
= std::make_shared
<XclImpButtonObj
>( rRoot
); break;
245 case EXC_OBJTYPE_PICTURE
: xDrawObj
= std::make_shared
<XclImpPictureObj
>( rRoot
); break;
246 case EXC_OBJTYPE_POLYGON
: xDrawObj
= std::make_shared
<XclImpPolygonObj
>( rRoot
); break;
248 SAL_WARN("sc.filter", "XclImpDrawObjBase::ReadObj4 - unknown object type 0x" << std::hex
<< nObjType
);
249 rRoot
.GetTracer().TraceUnsupportedObjects();
255 xDrawObj
= std::make_shared
<XclImpPhObj
>(rRoot
);
258 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
259 xDrawObj
->ImplReadObj4( rStrm
);
263 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj5( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
265 XclImpDrawObjRef xDrawObj
;
267 if( rStrm
.GetRecLeft() >= 34 )
269 sal_uInt16
nObjType(EXC_OBJTYPE_UNKNOWN
);
271 nObjType
= rStrm
.ReaduInt16();
274 case EXC_OBJTYPE_GROUP
: xDrawObj
= std::make_shared
<XclImpGroupObj
>( rRoot
); break;
275 case EXC_OBJTYPE_LINE
: xDrawObj
= std::make_shared
<XclImpLineObj
>( rRoot
); break;
276 case EXC_OBJTYPE_RECTANGLE
: xDrawObj
= std::make_shared
<XclImpRectObj
>( rRoot
); break;
277 case EXC_OBJTYPE_OVAL
: xDrawObj
= std::make_shared
<XclImpOvalObj
>( rRoot
); break;
278 case EXC_OBJTYPE_ARC
: xDrawObj
= std::make_shared
<XclImpArcObj
>( rRoot
); break;
279 case EXC_OBJTYPE_CHART
: xDrawObj
= std::make_shared
<XclImpChartObj
>( rRoot
); break;
280 case EXC_OBJTYPE_TEXT
: xDrawObj
= std::make_shared
<XclImpTextObj
>( rRoot
); break;
281 case EXC_OBJTYPE_BUTTON
: xDrawObj
= std::make_shared
<XclImpButtonObj
>( rRoot
); break;
282 case EXC_OBJTYPE_PICTURE
: xDrawObj
= std::make_shared
<XclImpPictureObj
>( rRoot
); break;
283 case EXC_OBJTYPE_POLYGON
: xDrawObj
= std::make_shared
<XclImpPolygonObj
>( rRoot
); break;
284 case EXC_OBJTYPE_CHECKBOX
: xDrawObj
= std::make_shared
<XclImpCheckBoxObj
>( rRoot
); break;
285 case EXC_OBJTYPE_OPTIONBUTTON
: xDrawObj
= std::make_shared
<XclImpOptionButtonObj
>( rRoot
); break;
286 case EXC_OBJTYPE_EDIT
: xDrawObj
= std::make_shared
<XclImpEditObj
>( rRoot
); break;
287 case EXC_OBJTYPE_LABEL
: xDrawObj
= std::make_shared
<XclImpLabelObj
>( rRoot
); break;
288 case EXC_OBJTYPE_DIALOG
: xDrawObj
= std::make_shared
<XclImpDialogObj
>( rRoot
); break;
289 case EXC_OBJTYPE_SPIN
: xDrawObj
= std::make_shared
<XclImpSpinButtonObj
>( rRoot
); break;
290 case EXC_OBJTYPE_SCROLLBAR
: xDrawObj
= std::make_shared
<XclImpScrollBarObj
>( rRoot
); break;
291 case EXC_OBJTYPE_LISTBOX
: xDrawObj
= std::make_shared
<XclImpListBoxObj
>( rRoot
); break;
292 case EXC_OBJTYPE_GROUPBOX
: xDrawObj
= std::make_shared
<XclImpGroupBoxObj
>( rRoot
); break;
293 case EXC_OBJTYPE_DROPDOWN
: xDrawObj
= std::make_shared
<XclImpDropDownObj
>( rRoot
); break;
295 SAL_WARN("sc.filter", "XclImpDrawObjBase::ReadObj5 - unknown object type 0x" << std::hex
<< nObjType
);
296 rRoot
.GetTracer().TraceUnsupportedObjects();
297 xDrawObj
= std::make_shared
<XclImpPhObj
>( rRoot
);
301 OSL_ENSURE(xDrawObj
, "object import failed");
305 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
306 xDrawObj
->ImplReadObj5( rStrm
);
311 XclImpDrawObjRef
XclImpDrawObjBase::ReadObj8( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
313 XclImpDrawObjRef xDrawObj
;
315 if( rStrm
.GetRecLeft() >= 10 )
317 sal_uInt16
nSubRecId(0), nSubRecSize(0), nObjType(0);
318 nSubRecId
= rStrm
.ReaduInt16();
319 nSubRecSize
= rStrm
.ReaduInt16();
320 nObjType
= rStrm
.ReaduInt16();
321 OSL_ENSURE( nSubRecId
== EXC_ID_OBJCMO
, "XclImpDrawObjBase::ReadObj8 - OBJCMO subrecord expected" );
322 if( (nSubRecId
== EXC_ID_OBJCMO
) && (nSubRecSize
>= 6) )
326 // in BIFF8, all simple objects support text
327 case EXC_OBJTYPE_LINE
:
328 case EXC_OBJTYPE_ARC
:
329 xDrawObj
= std::make_shared
<XclImpTextObj
>( rRoot
);
330 // lines and arcs may be 2-dimensional
331 xDrawObj
->SetAreaObj( false );
334 // in BIFF8, all simple objects support text
335 case EXC_OBJTYPE_RECTANGLE
:
336 case EXC_OBJTYPE_OVAL
:
337 case EXC_OBJTYPE_POLYGON
:
338 case EXC_OBJTYPE_DRAWING
:
339 case EXC_OBJTYPE_TEXT
:
340 xDrawObj
= std::make_shared
<XclImpTextObj
>( rRoot
);
343 case EXC_OBJTYPE_GROUP
: xDrawObj
= std::make_shared
<XclImpGroupObj
>( rRoot
); break;
344 case EXC_OBJTYPE_CHART
: xDrawObj
= std::make_shared
<XclImpChartObj
>( rRoot
); break;
345 case EXC_OBJTYPE_BUTTON
: xDrawObj
= std::make_shared
<XclImpButtonObj
>( rRoot
); break;
346 case EXC_OBJTYPE_PICTURE
: xDrawObj
= std::make_shared
<XclImpPictureObj
>( rRoot
); break;
347 case EXC_OBJTYPE_CHECKBOX
: xDrawObj
= std::make_shared
<XclImpCheckBoxObj
>( rRoot
); break;
348 case EXC_OBJTYPE_OPTIONBUTTON
: xDrawObj
= std::make_shared
<XclImpOptionButtonObj
>( rRoot
); break;
349 case EXC_OBJTYPE_EDIT
: xDrawObj
= std::make_shared
<XclImpEditObj
>( rRoot
); break;
350 case EXC_OBJTYPE_LABEL
: xDrawObj
= std::make_shared
<XclImpLabelObj
>( rRoot
); break;
351 case EXC_OBJTYPE_DIALOG
: xDrawObj
= std::make_shared
<XclImpDialogObj
>( rRoot
); break;
352 case EXC_OBJTYPE_SPIN
: xDrawObj
= std::make_shared
<XclImpSpinButtonObj
>( rRoot
); break;
353 case EXC_OBJTYPE_SCROLLBAR
: xDrawObj
= std::make_shared
<XclImpScrollBarObj
>( rRoot
); break;
354 case EXC_OBJTYPE_LISTBOX
: xDrawObj
= std::make_shared
<XclImpListBoxObj
>( rRoot
); break;
355 case EXC_OBJTYPE_GROUPBOX
: xDrawObj
= std::make_shared
<XclImpGroupBoxObj
>( rRoot
); break;
356 case EXC_OBJTYPE_DROPDOWN
: xDrawObj
= std::make_shared
<XclImpDropDownObj
>( rRoot
); break;
357 case EXC_OBJTYPE_NOTE
: xDrawObj
= std::make_shared
<XclImpNoteObj
>( rRoot
); break;
360 SAL_WARN("sc.filter", "XclImpDrawObjBase::ReadObj8 - unknown object type 0x" << std::hex
<< nObjType
);
361 rRoot
.GetTracer().TraceUnsupportedObjects();
366 if (!xDrawObj
) //ensure placeholder for unknown or broken records
368 SAL_WARN( "sc.filter", "XclImpDrawObjBase::ReadObj8 import failed, substituting placeholder");
369 xDrawObj
= std::make_shared
<XclImpPhObj
>( rRoot
);
372 xDrawObj
->mnTab
= rRoot
.GetCurrScTab();
373 xDrawObj
->ImplReadObj8( rStrm
);
377 void XclImpDrawObjBase::SetAnchor( const XclObjAnchor
& rAnchor
)
383 void XclImpDrawObjBase::SetDffData(
384 const DffObjData
& rDffObjData
, const OUString
& rObjName
, const OUString
& rHyperlink
,
385 bool bVisible
, bool bAutoMargin
)
387 mnDffShapeId
= rDffObjData
.nShapeId
;
388 mnDffFlags
= rDffObjData
.nSpFlags
;
389 maObjName
= rObjName
;
390 maHyperlink
= rHyperlink
;
391 mbVisible
= bVisible
;
392 mbAutoMargin
= bAutoMargin
;
395 OUString
XclImpDrawObjBase::GetObjName() const
397 /* #i51348# Always return a non-empty name. Create English
398 default names depending on the object type. This is not implemented as
399 virtual functions in derived classes, as class type and object type may
401 return maObjName
.isEmpty() ? GetObjectManager().GetDefaultObjName(*this) : maObjName
;
404 const XclObjAnchor
* XclImpDrawObjBase::GetAnchor() const
406 return mbHasAnchor
? &maAnchor
: nullptr;
409 bool XclImpDrawObjBase::IsValidSize( const tools::Rectangle
& rAnchorRect
) const
411 // XclObjAnchor rounds up the width, width of 3 is the result of an Excel width of 0
413 ((rAnchorRect
.GetWidth() > 3) && (rAnchorRect
.GetHeight() > 1)) :
414 ((rAnchorRect
.GetWidth() > 3) || (rAnchorRect
.GetHeight() > 1));
417 ScRange
XclImpDrawObjBase::GetUsedArea( SCTAB nScTab
) const
419 ScRange
aScUsedArea( ScAddress::INITIALIZE_INVALID
);
420 // #i44077# object inserted -> update used area for OLE object import
421 if( mbHasAnchor
&& GetAddressConverter().ConvertRange( aScUsedArea
, maAnchor
, nScTab
, nScTab
, false ) )
423 // reduce range, if object ends directly on borders between two columns or rows
424 if( (maAnchor
.mnRX
== 0) && (aScUsedArea
.aStart
.Col() < aScUsedArea
.aEnd
.Col()) )
425 aScUsedArea
.aEnd
.IncCol( -1 );
426 if( (maAnchor
.mnBY
== 0) && (aScUsedArea
.aStart
.Row() < aScUsedArea
.aEnd
.Row()) )
427 aScUsedArea
.aEnd
.IncRow( -1 );
432 std::size_t XclImpDrawObjBase::GetProgressSize() const
434 return DoGetProgressSize();
437 SdrObjectUniquePtr
XclImpDrawObjBase::CreateSdrObject( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
, bool bIsDff
) const
439 SdrObjectUniquePtr xSdrObj
;
440 if( bIsDff
&& !mbCustomDff
)
442 rDffConv
.Progress( GetProgressSize() );
446 xSdrObj
= DoCreateSdrObj( rDffConv
, rAnchorRect
);
448 //added for exporting OCX control
449 /* mnObjType value set should be as below table:
450 0x0000 Group 0x0001 Line
451 0x0002 Rectangle 0x0003 Oval
452 0x0004 Arc 0x0005 Chart
453 0x0006 Text 0x0009 Polygon
454 +-----------------------------------------------------+
455 OCX ==>| 0x0008 Picture |
456 +-----------------------------------------------------+
458 | 0x000B Checkbox 0x000C Radio button |
459 | 0x000D Edit box 0x000E Label |
460 TBX ==> | 0x000F Dialog box 0x0010 Spin control |
461 | 0x0011 Scrollbar 0x0012 List |
462 | 0x0013 Group box 0x0014 Dropdown list |
463 +-----------------------------------------------------+
464 0x0019 Note 0x001E OfficeArt object
466 if( xSdrObj
&& xSdrObj
->IsUnoObj() &&
467 ( (mnObjType
< 25 && mnObjType
> 10) || mnObjType
== 7 || mnObjType
== 8 ) )
469 SdrUnoObj
* pSdrUnoObj
= dynamic_cast< SdrUnoObj
* >( xSdrObj
.get() );
470 if( pSdrUnoObj
!= nullptr )
472 const Reference
< XControlModel
>& xCtrlModel
= pSdrUnoObj
->GetUnoControlModel();
473 Reference
< XPropertySet
> xPropSet(xCtrlModel
,UNO_QUERY
);
474 static constexpr OUStringLiteral
sPropertyName(u
"ControlTypeinMSO");
476 enum { eCreateFromOffice
= 0, eCreateFromMSTBXControl
, eCreateFromMSOCXControl
};
478 if( mnObjType
== 7 || (mnObjType
< 25 && mnObjType
> 10) )//TBX
482 //Need summary type for export. Detail type(checkbox, button ...) has been contained by mnObjType
483 const sal_Int16 nTBXControlType
= eCreateFromMSTBXControl
;
484 xPropSet
->setPropertyValue(sPropertyName
, Any(nTBXControlType
));
486 catch(const Exception
&)
488 SAL_WARN("sc.filter", "XclImpDrawObjBase::CreateSdrObject, this control can't be set the property ControlTypeinMSO!");
491 if( mnObjType
== 8 )//OCX
493 //Need summary type for export
494 static constexpr OUStringLiteral
sObjIdPropertyName(u
"ObjIDinMSO");
495 const XclImpPictureObj
* const pObj
= dynamic_cast< const XclImpPictureObj
* const >(this);
496 if( pObj
!= nullptr && pObj
->IsOcxControl() )
500 const sal_Int16 nOCXControlType
= eCreateFromMSOCXControl
;
501 xPropSet
->setPropertyValue(sPropertyName
, Any(nOCXControlType
));
502 //Detail type(checkbox, button ...)
503 xPropSet
->setPropertyValue(sObjIdPropertyName
, makeAny
<sal_uInt16
>(mnObjId
));
505 catch(const Exception
&)
507 SAL_WARN("sc.filter", "XclImpDrawObjBase::CreateSdrObject, this control can't be set the property ObjIDinMSO!");
518 void XclImpDrawObjBase::NotifyMacroEventRead()
520 if (mbNotifyMacroEventRead
)
522 SfxObjectShell
* pDocShell
= GetDocShell();
525 comphelper::DocumentInfo::notifyMacroEventRead(pDocShell
->GetModel());
526 mbNotifyMacroEventRead
= true;
529 void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
)
531 // default: front layer, derived classes may have to set other layer in DoPreProcessSdrObj()
532 rSdrObj
.NbcSetLayer( SC_LAYER_FRONT
);
534 // set object name (GetObjName() will always return a non-empty name)
535 rSdrObj
.SetName( GetObjName() );
537 // #i39167# full width for all objects regardless of horizontal alignment
538 rSdrObj
.SetMergedItem( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_BLOCK
) );
540 // automatic text margin
543 sal_Int32 nMargin
= rDffConv
.GetDefaultTextMargin();
544 rSdrObj
.SetMergedItem( makeSdrTextLeftDistItem( nMargin
) );
545 rSdrObj
.SetMergedItem( makeSdrTextRightDistItem( nMargin
) );
546 rSdrObj
.SetMergedItem( makeSdrTextUpperDistItem( nMargin
) );
547 rSdrObj
.SetMergedItem( makeSdrTextLowerDistItem( nMargin
) );
550 // macro and hyperlink
551 // removed oracle/sun check for mbSimpleMacro ( no idea what its for )
552 if (!maMacroName
.isEmpty())
554 if( ScMacroInfo
* pInfo
= ScDrawLayer::GetMacroInfo( &rSdrObj
, true ) )
556 OUString sMacro
= XclTools::GetSbMacroUrl(maMacroName
, GetDocShell());
557 if (!sMacro
.isEmpty())
558 NotifyMacroEventRead();
559 pInfo
->SetMacro(sMacro
);
562 if (!maHyperlink
.isEmpty())
563 rSdrObj
.setHyperlink(maHyperlink
);
565 // call virtual function for object type specific processing
566 DoPreProcessSdrObj( rDffConv
, rSdrObj
);
569 void XclImpDrawObjBase::PostProcessSdrObject( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
571 // call virtual function for object type specific processing
572 DoPostProcessSdrObj( rDffConv
, rSdrObj
);
575 // protected ------------------------------------------------------------------
577 void XclImpDrawObjBase::ReadName5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
)
582 // name length field is repeated before the name
583 maObjName
= rStrm
.ReadByteString( false );
584 // skip padding byte for word boundaries
585 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
589 void XclImpDrawObjBase::ReadMacro3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
592 rStrm
.Ignore( nMacroSize
);
593 // skip padding byte for word boundaries, not contained in nMacroSize
594 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
597 void XclImpDrawObjBase::ReadMacro4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
600 rStrm
.Ignore( nMacroSize
);
603 void XclImpDrawObjBase::ReadMacro5( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
606 rStrm
.Ignore( nMacroSize
);
609 void XclImpDrawObjBase::ReadMacro8( XclImpStream
& rStrm
)
612 if( rStrm
.GetRecLeft() <= 6 )
615 // macro is stored in a tNameXR token containing a link to a defined name
616 sal_uInt16 nFmlaSize
;
617 nFmlaSize
= rStrm
.ReaduInt16();
619 OSL_ENSURE( nFmlaSize
== 7, "XclImpDrawObjBase::ReadMacro - unexpected formula size" );
623 sal_uInt16 nExtSheet
, nExtName
;
624 nTokenId
= rStrm
.ReaduInt8();
625 nExtSheet
= rStrm
.ReaduInt16();
626 nExtName
= rStrm
.ReaduInt16();
627 OSL_ENSURE( nTokenId
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
),
628 "XclImpDrawObjBase::ReadMacro - tNameXR token expected" );
629 if( nTokenId
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
) )
630 maMacroName
= GetLinkManager().GetMacroName( nExtSheet
, nExtName
);
634 void XclImpDrawObjBase::ConvertLineStyle( SdrObject
& rSdrObj
, const XclObjLineData
& rLineData
) const
636 if( rLineData
.IsAuto() )
638 XclObjLineData aAutoData
;
639 aAutoData
.mnAuto
= 0;
640 ConvertLineStyle( rSdrObj
, aAutoData
);
644 tools::Long nLineWidth
= 35 * ::std::min( rLineData
.mnWidth
, EXC_OBJ_LINE_THICK
);
645 rSdrObj
.SetMergedItem( XLineWidthItem( nLineWidth
) );
646 rSdrObj
.SetMergedItem( XLineColorItem( OUString(), GetPalette().GetColor( rLineData
.mnColorIdx
) ) );
647 rSdrObj
.SetMergedItem( XLineJointItem( css::drawing::LineJoint_MITER
) );
649 sal_uLong nDotLen
= ::std::max
< sal_uLong
>( 70 * rLineData
.mnWidth
, 35 );
650 sal_uLong nDashLen
= 3 * nDotLen
;
651 sal_uLong nDist
= 2 * nDotLen
;
653 switch( rLineData
.mnStyle
)
656 case EXC_OBJ_LINE_SOLID
:
657 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_SOLID
) );
659 case EXC_OBJ_LINE_DASH
:
660 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_DASH
) );
661 rSdrObj
.SetMergedItem( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT
, 0, nDotLen
, 1, nDashLen
, nDist
) ) );
663 case EXC_OBJ_LINE_DOT
:
664 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_DASH
) );
665 rSdrObj
.SetMergedItem( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT
, 1, nDotLen
, 0, nDashLen
, nDist
) ) );
667 case EXC_OBJ_LINE_DASHDOT
:
668 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_DASH
) );
669 rSdrObj
.SetMergedItem( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT
, 1, nDotLen
, 1, nDashLen
, nDist
) ) );
671 case EXC_OBJ_LINE_DASHDOTDOT
:
672 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_DASH
) );
673 rSdrObj
.SetMergedItem( XLineDashItem( OUString(), XDash( css::drawing::DashStyle_RECT
, 2, nDotLen
, 1, nDashLen
, nDist
) ) );
675 case EXC_OBJ_LINE_MEDTRANS
:
676 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_SOLID
) );
677 rSdrObj
.SetMergedItem( XLineTransparenceItem( 50 ) );
679 case EXC_OBJ_LINE_DARKTRANS
:
680 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_SOLID
) );
681 rSdrObj
.SetMergedItem( XLineTransparenceItem( 25 ) );
683 case EXC_OBJ_LINE_LIGHTTRANS
:
684 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_SOLID
) );
685 rSdrObj
.SetMergedItem( XLineTransparenceItem( 75 ) );
687 case EXC_OBJ_LINE_NONE
:
688 rSdrObj
.SetMergedItem( XLineStyleItem( drawing::LineStyle_NONE
) );
694 void XclImpDrawObjBase::ConvertFillStyle( SdrObject
& rSdrObj
, const XclObjFillData
& rFillData
) const
696 if( rFillData
.IsAuto() )
698 XclObjFillData aAutoData
;
699 aAutoData
.mnAuto
= 0;
700 ConvertFillStyle( rSdrObj
, aAutoData
);
702 else if( rFillData
.mnPattern
== EXC_PATT_NONE
)
704 rSdrObj
.SetMergedItem( XFillStyleItem( drawing::FillStyle_NONE
) );
708 Color aPattColor
= GetPalette().GetColor( rFillData
.mnPattColorIdx
);
709 Color aBackColor
= GetPalette().GetColor( rFillData
.mnBackColorIdx
);
710 if( (rFillData
.mnPattern
== EXC_PATT_SOLID
) || (aPattColor
== aBackColor
) )
712 rSdrObj
.SetMergedItem( XFillStyleItem( drawing::FillStyle_SOLID
) );
713 rSdrObj
.SetMergedItem( XFillColorItem( OUString(), aPattColor
) );
717 static const sal_uInt8 sppnPatterns
[][ 8 ] =
719 { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
720 { 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD, 0x77, 0xDD },
721 { 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22 },
722 { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 },
723 { 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC },
724 { 0x33, 0x66, 0xCC, 0x99, 0x33, 0x66, 0xCC, 0x99 },
725 { 0xCC, 0x66, 0x33, 0x99, 0xCC, 0x66, 0x33, 0x99 },
726 { 0xCC, 0xCC, 0x33, 0x33, 0xCC, 0xCC, 0x33, 0x33 },
727 { 0xCC, 0xFF, 0x33, 0xFF, 0xCC, 0xFF, 0x33, 0xFF },
728 { 0xFF, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00 },
729 { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 },
730 { 0x11, 0x22, 0x44, 0x88, 0x11, 0x22, 0x44, 0x88 },
731 { 0x88, 0x44, 0x22, 0x11, 0x88, 0x44, 0x22, 0x11 },
732 { 0xFF, 0x11, 0x11, 0x11, 0xFF, 0x11, 0x11, 0x11 },
733 { 0xAA, 0x44, 0xAA, 0x11, 0xAA, 0x44, 0xAA, 0x11 },
734 { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00 },
735 { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00 }
737 const sal_uInt8
* const pnPattern
= sppnPatterns
[std::min
<size_t>(rFillData
.mnPattern
- 2, SAL_N_ELEMENTS(sppnPatterns
) - 1)];
738 // create 2-colored 8x8 DIB
739 SvMemoryStream aMemStrm
;
740 aMemStrm
.WriteUInt32( 12 ).WriteInt16( 8 ).WriteInt16( 8 ).WriteUInt16( 1 ).WriteUInt16( 1 );
741 aMemStrm
.WriteUChar( 0xFF ).WriteUChar( 0xFF ).WriteUChar( 0xFF );
742 aMemStrm
.WriteUChar( 0x00 ).WriteUChar( 0x00 ).WriteUChar( 0x00 );
743 for( size_t nIdx
= 0; nIdx
< 8; ++nIdx
)
744 aMemStrm
.WriteUInt32( pnPattern
[ nIdx
] ); // 32-bit little-endian
745 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
747 (void)ReadDIB(aBitmap
, aMemStrm
, false);
749 XOBitmap
aXOBitmap(( BitmapEx(aBitmap
) ));
750 aXOBitmap
.Bitmap2Array();
751 if( aXOBitmap
.GetBackgroundColor() == COL_BLACK
)
752 ::std::swap( aPattColor
, aBackColor
);
753 aXOBitmap
.SetPixelColor( aPattColor
);
754 aXOBitmap
.SetBackgroundColor( aBackColor
);
755 aXOBitmap
.Array2Bitmap();
756 aBitmap
= aXOBitmap
.GetBitmap().GetBitmap();
758 rSdrObj
.SetMergedItem(XFillStyleItem(drawing::FillStyle_BITMAP
));
759 rSdrObj
.SetMergedItem(XFillBitmapItem(OUString(), Graphic(BitmapEx(aBitmap
))));
764 void XclImpDrawObjBase::ConvertFrameStyle( SdrObject
& rSdrObj
, sal_uInt16 nFrameFlags
) const
766 if( ::get_flag( nFrameFlags
, EXC_OBJ_FRAME_SHADOW
) )
768 rSdrObj
.SetMergedItem( makeSdrShadowItem( true ) );
769 rSdrObj
.SetMergedItem( makeSdrShadowXDistItem( 35 ) );
770 rSdrObj
.SetMergedItem( makeSdrShadowYDistItem( 35 ) );
771 rSdrObj
.SetMergedItem( makeSdrShadowColorItem( GetPalette().GetColor( EXC_COLOR_WINDOWTEXT
) ) );
775 Color
XclImpDrawObjBase::GetSolidLineColor( const XclObjLineData
& rLineData
) const
777 Color
aColor( COL_TRANSPARENT
);
778 if( rLineData
.IsAuto() )
780 XclObjLineData aAutoData
;
781 aAutoData
.mnAuto
= 0;
782 aColor
= GetSolidLineColor( aAutoData
);
784 else if( rLineData
.mnStyle
!= EXC_OBJ_LINE_NONE
)
786 aColor
= GetPalette().GetColor( rLineData
.mnColorIdx
);
791 Color
XclImpDrawObjBase::GetSolidFillColor( const XclObjFillData
& rFillData
) const
793 Color
aColor( COL_TRANSPARENT
);
794 if( rFillData
.IsAuto() )
796 XclObjFillData aAutoData
;
797 aAutoData
.mnAuto
= 0;
798 aColor
= GetSolidFillColor( aAutoData
);
800 else if( rFillData
.mnPattern
!= EXC_PATT_NONE
)
802 Color aPattColor
= GetPalette().GetColor( rFillData
.mnPattColorIdx
);
803 Color aBackColor
= GetPalette().GetColor( rFillData
.mnBackColorIdx
);
804 aColor
= XclTools::GetPatternColor( aPattColor
, aBackColor
, rFillData
.mnPattern
);
809 void XclImpDrawObjBase::DoReadObj3( XclImpStream
&, sal_uInt16
)
813 void XclImpDrawObjBase::DoReadObj4( XclImpStream
&, sal_uInt16
)
817 void XclImpDrawObjBase::DoReadObj5( XclImpStream
&, sal_uInt16
, sal_uInt16
)
821 void XclImpDrawObjBase::DoReadObj8SubRec( XclImpStream
&, sal_uInt16
, sal_uInt16
)
825 std::size_t XclImpDrawObjBase::DoGetProgressSize() const
830 SdrObjectUniquePtr
XclImpDrawObjBase::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& ) const
832 rDffConv
.Progress( GetProgressSize() );
836 void XclImpDrawObjBase::DoPreProcessSdrObj( XclImpDffConverter
&, SdrObject
& ) const
838 // trace if object is not printable
840 GetTracer().TraceObjectNotPrintable();
843 void XclImpDrawObjBase::DoPostProcessSdrObj( XclImpDffConverter
&, SdrObject
& ) const
847 void XclImpDrawObjBase::ImplReadObj3( XclImpStream
& rStrm
)
849 // back to offset 4 (ignore object count field)
852 sal_uInt16 nObjFlags
, nMacroSize
;
853 mnObjType
= rStrm
.ReaduInt16();
854 mnObjId
= rStrm
.ReaduInt16();
855 nObjFlags
= rStrm
.ReaduInt16();
857 nMacroSize
= rStrm
.ReaduInt16();
861 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
862 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
863 DoReadObj3( rStrm
, nMacroSize
);
866 void XclImpDrawObjBase::ImplReadObj4( XclImpStream
& rStrm
)
868 // back to offset 4 (ignore object count field)
871 sal_uInt16 nObjFlags
, nMacroSize
;
872 mnObjType
= rStrm
.ReaduInt16();
873 mnObjId
= rStrm
.ReaduInt16();
874 nObjFlags
= rStrm
.ReaduInt16();
876 nMacroSize
= rStrm
.ReaduInt16();
880 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
881 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
882 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJ_PRINTABLE
);
883 DoReadObj4( rStrm
, nMacroSize
);
886 void XclImpDrawObjBase::ImplReadObj5( XclImpStream
& rStrm
)
888 // back to offset 4 (ignore object count field)
891 sal_uInt16 nObjFlags
, nMacroSize
, nNameLen
;
892 mnObjType
= rStrm
.ReaduInt16();
893 mnObjId
= rStrm
.ReaduInt16();
894 nObjFlags
= rStrm
.ReaduInt16();
896 nMacroSize
= rStrm
.ReaduInt16();
898 nNameLen
= rStrm
.ReaduInt16();
902 mbHidden
= ::get_flag( nObjFlags
, EXC_OBJ_HIDDEN
);
903 mbVisible
= ::get_flag( nObjFlags
, EXC_OBJ_VISIBLE
);
904 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJ_PRINTABLE
);
905 DoReadObj5( rStrm
, nNameLen
, nMacroSize
);
908 void XclImpDrawObjBase::ImplReadObj8( XclImpStream
& rStrm
)
911 rStrm
.Seek( EXC_REC_SEEK_TO_BEGIN
);
916 if (rStrm
.GetRecLeft() < 4)
919 sal_uInt16 nSubRecId
= rStrm
.ReaduInt16();
920 sal_uInt16 nSubRecSize
= rStrm
.ReaduInt16();
921 rStrm
.PushPosition();
922 // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
923 nSubRecSize
= static_cast< sal_uInt16
>( ::std::min
< std::size_t >( nSubRecSize
, rStrm
.GetRecLeft() ) );
928 OSL_ENSURE( rStrm
.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" );
929 if( (rStrm
.GetRecPos() == 4) && (nSubRecSize
>= 6) )
931 sal_uInt16 nObjFlags
;
932 mnObjType
= rStrm
.ReaduInt16();
933 mnObjId
= rStrm
.ReaduInt16( );
934 nObjFlags
= rStrm
.ReaduInt16( );
935 mbPrintable
= ::get_flag( nObjFlags
, EXC_OBJCMO_PRINTABLE
);
938 case EXC_ID_OBJMACRO
:
945 DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
949 rStrm
.Ignore( nSubRecSize
);
952 /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream
953 processing (e.g. charts), even if the OBJEND subrecord is missing. */
954 DoReadObj8SubRec( rStrm
, EXC_ID_OBJEND
, 0 );
956 /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
957 IMGDATA record following the OBJ record (but they use the image data
958 stored in DFF). The IMGDATA record may be continued by several CONTINUE
959 records. But the last CONTINUE record may be in fact an MSODRAWING
960 record that contains the DFF data of the next drawing object! So we
961 have to skip just enough CONTINUE records to look at the next
962 MSODRAWING/CONTINUE record. */
963 if( !((rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord()) )
967 sal_uInt32 nDataSize
= rStrm
.ReaduInt32();
968 nDataSize
-= rStrm
.GetRecLeft();
969 // skip following CONTINUE records until IMGDATA ends
974 if (rStrm
.GetNextRecId() != EXC_ID_CONT
)
976 if (!rStrm
.StartNextRecord())
978 OSL_ENSURE( nDataSize
>= rStrm
.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" );
979 nDataSize
-= ::std::min
< sal_uInt32
>( rStrm
.GetRecLeft(), nDataSize
);
981 OSL_ENSURE( nDataSize
== 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" );
982 // next record may be MSODRAWING or CONTINUE or anything else
985 void XclImpDrawObjVector::InsertGrouped( XclImpDrawObjRef
const & xDrawObj
)
988 if( XclImpGroupObj
* pGroupObj
= dynamic_cast< XclImpGroupObj
* >( mObjs
.back().get() ) )
989 if( pGroupObj
->TryInsert( xDrawObj
) )
991 mObjs
.push_back( xDrawObj
);
994 std::size_t XclImpDrawObjVector::GetProgressSize() const
996 return std::accumulate(mObjs
.begin(), mObjs
.end(), std::size_t(0),
997 [](const std::size_t& rSum
, const XclImpDrawObjRef
& rxObj
) { return rSum
+ rxObj
->GetProgressSize(); });
1000 XclImpPhObj::XclImpPhObj( const XclImpRoot
& rRoot
) :
1001 XclImpDrawObjBase( rRoot
)
1003 SetProcessSdrObj( false );
1006 XclImpGroupObj::XclImpGroupObj( const XclImpRoot
& rRoot
) :
1007 XclImpDrawObjBase( rRoot
),
1008 mnFirstUngrouped( 0 )
1012 bool XclImpGroupObj::TryInsert( XclImpDrawObjRef
const & xDrawObj
)
1014 if( xDrawObj
->GetObjId() == mnFirstUngrouped
)
1016 // insert into own list or into nested group
1017 maChildren
.InsertGrouped( xDrawObj
);
1021 void XclImpGroupObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1024 mnFirstUngrouped
= rStrm
.ReaduInt16();
1026 ReadMacro3( rStrm
, nMacroSize
);
1029 void XclImpGroupObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1032 mnFirstUngrouped
= rStrm
.ReaduInt16();
1034 ReadMacro4( rStrm
, nMacroSize
);
1037 void XclImpGroupObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1040 mnFirstUngrouped
= rStrm
.ReaduInt16();
1042 ReadName5( rStrm
, nNameLen
);
1043 ReadMacro5( rStrm
, nMacroSize
);
1046 std::size_t XclImpGroupObj::DoGetProgressSize() const
1048 return XclImpDrawObjBase::DoGetProgressSize() + maChildren
.GetProgressSize();
1051 SdrObjectUniquePtr
XclImpGroupObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& /*rAnchorRect*/ ) const
1053 std::unique_ptr
<SdrObjGroup
, SdrObjectFreeOp
> xSdrObj(
1055 *GetDoc().GetDrawLayer()));
1056 // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle
1057 SdrObjList
& rObjList
= *xSdrObj
->GetSubList(); // SdrObjGroup always returns existing sublist
1058 for( const auto& rxChild
: maChildren
)
1059 rDffConv
.ProcessObject( rObjList
, *rxChild
);
1060 rDffConv
.Progress();
1064 XclImpLineObj::XclImpLineObj( const XclImpRoot
& rRoot
) :
1065 XclImpDrawObjBase( rRoot
),
1067 mnStartPoint( EXC_OBJ_LINE_TL
)
1069 SetAreaObj( false );
1072 void XclImpLineObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1074 rStrm
>> maLineData
;
1075 mnArrows
= rStrm
.ReaduInt16();
1076 mnStartPoint
= rStrm
.ReaduInt8();
1078 ReadMacro3( rStrm
, nMacroSize
);
1081 void XclImpLineObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1083 rStrm
>> maLineData
;
1084 mnArrows
= rStrm
.ReaduInt16();
1085 mnStartPoint
= rStrm
.ReaduInt8();
1087 ReadMacro4( rStrm
, nMacroSize
);
1090 void XclImpLineObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1092 rStrm
>> maLineData
;
1093 mnArrows
= rStrm
.ReaduInt16();
1094 mnStartPoint
= rStrm
.ReaduInt8();
1096 ReadName5( rStrm
, nNameLen
);
1097 ReadMacro5( rStrm
, nMacroSize
);
1100 SdrObjectUniquePtr
XclImpLineObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
1102 ::basegfx::B2DPolygon aB2DPolygon
;
1103 switch( mnStartPoint
)
1106 case EXC_OBJ_LINE_TL
:
1107 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Top() ) );
1108 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Bottom() ) );
1110 case EXC_OBJ_LINE_TR
:
1111 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Top() ) );
1112 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Bottom() ) );
1114 case EXC_OBJ_LINE_BR
:
1115 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Bottom() ) );
1116 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Top() ) );
1118 case EXC_OBJ_LINE_BL
:
1119 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Left(), rAnchorRect
.Bottom() ) );
1120 aB2DPolygon
.append( ::basegfx::B2DPoint( rAnchorRect
.Right(), rAnchorRect
.Top() ) );
1123 SdrObjectUniquePtr
xSdrObj(
1125 *GetDoc().GetDrawLayer(),
1127 ::basegfx::B2DPolyPolygon(aB2DPolygon
)));
1128 ConvertLineStyle( *xSdrObj
, maLineData
);
1131 sal_uInt8 nArrowType
= ::extract_value
< sal_uInt8
>( mnArrows
, 0, 4 );
1132 bool bLineStart
= false;
1133 bool bLineEnd
= false;
1134 bool bFilled
= false;
1135 switch( nArrowType
)
1137 case EXC_OBJ_ARROW_OPEN
: bLineStart
= false; bLineEnd
= true; bFilled
= false; break;
1138 case EXC_OBJ_ARROW_OPENBOTH
: bLineStart
= true; bLineEnd
= true; bFilled
= false; break;
1139 case EXC_OBJ_ARROW_FILLED
: bLineStart
= false; bLineEnd
= true; bFilled
= true; break;
1140 case EXC_OBJ_ARROW_FILLEDBOTH
: bLineStart
= true; bLineEnd
= true; bFilled
= true; break;
1142 if( bLineStart
|| bLineEnd
)
1144 sal_uInt8 nArrowWidth
= ::extract_value
< sal_uInt8
>( mnArrows
, 4, 4 );
1145 double fArrowWidth
= 3.0;
1146 switch( nArrowWidth
)
1148 case EXC_OBJ_ARROW_NARROW
: fArrowWidth
= 2.0; break;
1149 case EXC_OBJ_ARROW_MEDIUM
: fArrowWidth
= 3.0; break;
1150 case EXC_OBJ_ARROW_WIDE
: fArrowWidth
= 5.0; break;
1153 sal_uInt8 nArrowLength
= ::extract_value
< sal_uInt8
>( mnArrows
, 8, 4 );
1154 double fArrowLength
= 3.0;
1155 switch( nArrowLength
)
1157 case EXC_OBJ_ARROW_NARROW
: fArrowLength
= 2.5; break;
1158 case EXC_OBJ_ARROW_MEDIUM
: fArrowLength
= 3.5; break;
1159 case EXC_OBJ_ARROW_WIDE
: fArrowLength
= 6.0; break;
1162 ::basegfx::B2DPolygon aArrowPoly
;
1163 #define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) )
1166 aArrowPoly
.append( EXC_ARROW_POINT( 0, 100 ) );
1167 aArrowPoly
.append( EXC_ARROW_POINT( 50, 0 ) );
1168 aArrowPoly
.append( EXC_ARROW_POINT( 100, 100 ) );
1172 sal_uInt8 nLineWidth
= ::limit_cast
< sal_uInt8
>( maLineData
.mnWidth
, EXC_OBJ_LINE_THIN
, EXC_OBJ_LINE_THICK
);
1173 aArrowPoly
.append( EXC_ARROW_POINT( 50, 0 ) );
1174 aArrowPoly
.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth
) );
1175 aArrowPoly
.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth
, 100 ) );
1176 aArrowPoly
.append( EXC_ARROW_POINT( 50, 12 * nLineWidth
) );
1177 aArrowPoly
.append( EXC_ARROW_POINT( 5 * nLineWidth
, 100 ) );
1178 aArrowPoly
.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth
) );
1180 #undef EXC_ARROW_POINT
1182 ::basegfx::B2DPolyPolygon
aArrowPolyPoly( aArrowPoly
);
1183 tools::Long nWidth
= static_cast< tools::Long
>( 125 * fArrowWidth
);
1186 xSdrObj
->SetMergedItem( XLineStartItem( OUString(), aArrowPolyPoly
) );
1187 xSdrObj
->SetMergedItem( XLineStartWidthItem( nWidth
) );
1188 xSdrObj
->SetMergedItem( XLineStartCenterItem( false ) );
1192 xSdrObj
->SetMergedItem( XLineEndItem( OUString(), aArrowPolyPoly
) );
1193 xSdrObj
->SetMergedItem( XLineEndWidthItem( nWidth
) );
1194 xSdrObj
->SetMergedItem( XLineEndCenterItem( false ) );
1197 rDffConv
.Progress();
1201 XclImpRectObj::XclImpRectObj( const XclImpRoot
& rRoot
) :
1202 XclImpDrawObjBase( rRoot
),
1208 void XclImpRectObj::ReadFrameData( XclImpStream
& rStrm
)
1210 rStrm
>> maFillData
>> maLineData
;
1211 mnFrameFlags
= rStrm
.ReaduInt16();
1214 void XclImpRectObj::ConvertRectStyle( SdrObject
& rSdrObj
) const
1216 ConvertLineStyle( rSdrObj
, maLineData
);
1217 ConvertFillStyle( rSdrObj
, maFillData
);
1218 ConvertFrameStyle( rSdrObj
, mnFrameFlags
);
1221 void XclImpRectObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1223 ReadFrameData( rStrm
);
1224 ReadMacro3( rStrm
, nMacroSize
);
1227 void XclImpRectObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1229 ReadFrameData( rStrm
);
1230 ReadMacro4( rStrm
, nMacroSize
);
1233 void XclImpRectObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1235 ReadFrameData( rStrm
);
1236 ReadName5( rStrm
, nNameLen
);
1237 ReadMacro5( rStrm
, nMacroSize
);
1240 SdrObjectUniquePtr
XclImpRectObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
1242 SdrObjectUniquePtr
xSdrObj(
1244 *GetDoc().GetDrawLayer(),
1246 ConvertRectStyle( *xSdrObj
);
1247 rDffConv
.Progress();
1251 XclImpOvalObj::XclImpOvalObj( const XclImpRoot
& rRoot
) :
1252 XclImpRectObj( rRoot
)
1256 SdrObjectUniquePtr
XclImpOvalObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
1258 SdrObjectUniquePtr
xSdrObj(
1260 *GetDoc().GetDrawLayer(),
1263 ConvertRectStyle( *xSdrObj
);
1264 rDffConv
.Progress();
1268 XclImpArcObj::XclImpArcObj( const XclImpRoot
& rRoot
) :
1269 XclImpDrawObjBase( rRoot
),
1270 mnQuadrant( EXC_OBJ_ARC_TR
)
1272 SetAreaObj( false ); // arc may be 2-dimensional
1275 void XclImpArcObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1277 rStrm
>> maFillData
>> maLineData
;
1278 mnQuadrant
= rStrm
.ReaduInt8();
1280 ReadMacro3( rStrm
, nMacroSize
);
1283 void XclImpArcObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1285 rStrm
>> maFillData
>> maLineData
;
1286 mnQuadrant
= rStrm
.ReaduInt8();
1288 ReadMacro4( rStrm
, nMacroSize
);
1291 void XclImpArcObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1293 rStrm
>> maFillData
>> maLineData
;
1294 mnQuadrant
= rStrm
.ReaduInt8();
1296 ReadName5( rStrm
, nNameLen
);
1297 ReadMacro5( rStrm
, nMacroSize
);
1300 SdrObjectUniquePtr
XclImpArcObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
1302 tools::Rectangle aNewRect
= rAnchorRect
;
1303 Degree100 nStartAngle
;
1304 Degree100 nEndAngle
;
1305 switch( mnQuadrant
)
1308 case EXC_OBJ_ARC_TR
:
1309 nStartAngle
= 0_deg100
;
1310 nEndAngle
= 9000_deg100
;
1311 aNewRect
.AdjustLeft( -(rAnchorRect
.GetWidth()) );
1312 aNewRect
.AdjustBottom(rAnchorRect
.GetHeight() );
1314 case EXC_OBJ_ARC_TL
:
1315 nStartAngle
= 9000_deg100
;
1316 nEndAngle
= 18000_deg100
;
1317 aNewRect
.AdjustRight(rAnchorRect
.GetWidth() );
1318 aNewRect
.AdjustBottom(rAnchorRect
.GetHeight() );
1320 case EXC_OBJ_ARC_BL
:
1321 nStartAngle
= 18000_deg100
;
1322 nEndAngle
= 27000_deg100
;
1323 aNewRect
.AdjustRight(rAnchorRect
.GetWidth() );
1324 aNewRect
.AdjustTop( -(rAnchorRect
.GetHeight()) );
1326 case EXC_OBJ_ARC_BR
:
1327 nStartAngle
= 27000_deg100
;
1328 nEndAngle
= 0_deg100
;
1329 aNewRect
.AdjustLeft( -(rAnchorRect
.GetWidth()) );
1330 aNewRect
.AdjustTop( -(rAnchorRect
.GetHeight()) );
1333 SdrCircKind eObjKind
= maFillData
.IsFilled() ? SdrCircKind::Section
: SdrCircKind::Arc
;
1334 SdrObjectUniquePtr
xSdrObj(
1336 *GetDoc().GetDrawLayer(),
1341 ConvertFillStyle( *xSdrObj
, maFillData
);
1342 ConvertLineStyle( *xSdrObj
, maLineData
);
1343 rDffConv
.Progress();
1347 XclImpPolygonObj::XclImpPolygonObj( const XclImpRoot
& rRoot
) :
1348 XclImpRectObj( rRoot
),
1352 SetAreaObj( false ); // polygon may be 2-dimensional
1355 void XclImpPolygonObj::ReadCoordList( XclImpStream
& rStrm
)
1357 if( (rStrm
.GetNextRecId() == EXC_ID_COORDLIST
) && rStrm
.StartNextRecord() )
1359 OSL_ENSURE( rStrm
.GetRecLeft() / 4 == mnPointCount
, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" );
1362 if (rStrm
.GetRecLeft() < 4)
1364 sal_uInt16 nX
= rStrm
.ReaduInt16();
1365 sal_uInt16 nY
= rStrm
.ReaduInt16();
1366 maCoords
.emplace_back( nX
, nY
);
1371 void XclImpPolygonObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1373 ReadFrameData( rStrm
);
1374 mnPolyFlags
= rStrm
.ReaduInt16();
1376 mnPointCount
= rStrm
.ReaduInt16();
1378 ReadMacro4( rStrm
, nMacroSize
);
1379 ReadCoordList( rStrm
);
1382 void XclImpPolygonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1384 ReadFrameData( rStrm
);
1385 mnPolyFlags
= rStrm
.ReaduInt16();
1387 mnPointCount
= rStrm
.ReaduInt16();
1389 ReadName5( rStrm
, nNameLen
);
1390 ReadMacro5( rStrm
, nMacroSize
);
1391 ReadCoordList( rStrm
);
1396 ::basegfx::B2DPoint
lclGetPolyPoint( const tools::Rectangle
& rAnchorRect
, const Point
& rPoint
)
1398 return ::basegfx::B2DPoint(
1399 rAnchorRect
.Left() + static_cast< sal_Int32
>( ::std::min
< double >( rPoint
.X(), 16384.0 ) / 16384.0 * rAnchorRect
.GetWidth() + 0.5 ),
1400 rAnchorRect
.Top() + static_cast< sal_Int32
>( ::std::min
< double >( rPoint
.Y(), 16384.0 ) / 16384.0 * rAnchorRect
.GetHeight() + 0.5 ) );
1405 SdrObjectUniquePtr
XclImpPolygonObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
1407 SdrObjectUniquePtr xSdrObj
;
1408 if( maCoords
.size() >= 2 )
1410 // create the polygon
1411 ::basegfx::B2DPolygon aB2DPolygon
;
1412 for( const auto& rCoord
: maCoords
)
1413 aB2DPolygon
.append( lclGetPolyPoint( rAnchorRect
, rCoord
) );
1414 // close polygon if specified
1415 if( ::get_flag( mnPolyFlags
, EXC_OBJ_POLY_CLOSED
) && (maCoords
.front() != maCoords
.back()) )
1416 aB2DPolygon
.append( lclGetPolyPoint( rAnchorRect
, maCoords
.front() ) );
1417 // create the SdrObject
1418 SdrObjKind eObjKind
= maFillData
.IsFilled() ? OBJ_PATHPOLY
: OBJ_PATHPLIN
;
1421 *GetDoc().GetDrawLayer(),
1423 ::basegfx::B2DPolyPolygon(aB2DPolygon
)));
1424 ConvertRectStyle( *xSdrObj
);
1426 rDffConv
.Progress();
1430 void XclImpObjTextData::ReadByteString( XclImpStream
& rStrm
)
1433 if( maData
.mnTextLen
> 0 )
1435 mxString
= std::make_shared
<XclImpString
>( rStrm
.ReadRawByteString( maData
.mnTextLen
) );
1436 // skip padding byte for word boundaries
1437 if( rStrm
.GetRecPos() & 1 ) rStrm
.Ignore( 1 );
1441 void XclImpObjTextData::ReadFormats( XclImpStream
& rStrm
)
1444 mxString
->ReadObjFormats( rStrm
, maData
.mnFormatSize
);
1446 rStrm
.Ignore( maData
.mnFormatSize
);
1449 XclImpTextObj::XclImpTextObj( const XclImpRoot
& rRoot
) :
1450 XclImpRectObj( rRoot
)
1454 void XclImpTextObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1456 ReadFrameData( rStrm
);
1457 maTextData
.maData
.ReadObj3( rStrm
);
1458 ReadMacro3( rStrm
, nMacroSize
);
1459 maTextData
.ReadByteString( rStrm
);
1460 maTextData
.ReadFormats( rStrm
);
1463 void XclImpTextObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1465 ReadFrameData( rStrm
);
1466 maTextData
.maData
.ReadObj3( rStrm
);
1467 ReadMacro4( rStrm
, nMacroSize
);
1468 maTextData
.ReadByteString( rStrm
);
1469 maTextData
.ReadFormats( rStrm
);
1472 void XclImpTextObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1474 ReadFrameData( rStrm
);
1475 maTextData
.maData
.ReadObj5( rStrm
);
1476 ReadName5( rStrm
, nNameLen
);
1477 ReadMacro5( rStrm
, nMacroSize
);
1478 maTextData
.ReadByteString( rStrm
);
1479 rStrm
.Ignore( maTextData
.maData
.mnLinkSize
); // ignore text link formula
1480 maTextData
.ReadFormats( rStrm
);
1483 SdrObjectUniquePtr
XclImpTextObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
1485 std::unique_ptr
<SdrObjCustomShape
, SdrObjectFreeOp
> xSdrObj(
1486 new SdrObjCustomShape(
1487 *GetDoc().GetDrawLayer()));
1488 xSdrObj
->NbcSetSnapRect( rAnchorRect
);
1489 OUString aRectType
= "rectangle";
1490 xSdrObj
->MergeDefaultAttributes( &aRectType
);
1491 ConvertRectStyle( *xSdrObj
);
1492 bool bAutoSize
= ::get_flag( maTextData
.maData
.mnFlags
, EXC_OBJ_TEXT_AUTOSIZE
);
1493 xSdrObj
->SetMergedItem( makeSdrTextAutoGrowWidthItem( bAutoSize
) );
1494 xSdrObj
->SetMergedItem( makeSdrTextAutoGrowHeightItem( bAutoSize
) );
1495 xSdrObj
->SetMergedItem( makeSdrTextWordWrapItem( true ) );
1496 rDffConv
.Progress();
1500 void XclImpTextObj::DoPreProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
1503 if( SdrTextObj
* pTextObj
= dynamic_cast< SdrTextObj
* >( &rSdrObj
) )
1505 if( maTextData
.mxString
)
1507 if( maTextData
.mxString
->IsRich() )
1509 if (maTextData
.mxString
->GetText().getLength() > 1024 && utl::ConfigManager::IsFuzzing())
1511 SAL_WARN("sc.filter", "truncating slow long rich text for fuzzing performance");
1512 maTextData
.mxString
->SetText(maTextData
.mxString
->GetText().copy(0, 1024));
1516 std::unique_ptr
< EditTextObject
> xEditObj(
1517 XclImpStringHelper::CreateTextObject( GetRoot(), *maTextData
.mxString
) );
1518 OutlinerParaObject
aOutlineObj(std::move(xEditObj
));
1519 aOutlineObj
.SetOutlinerMode( OutlinerMode::TextObject
);
1520 pTextObj
->NbcSetOutlinerParaObject( std::move(aOutlineObj
) );
1525 pTextObj
->NbcSetText( maTextData
.mxString
->GetText() );
1528 /* #i96858# Do not apply any formatting if there is no text.
1529 SdrObjCustomShape::SetVerticalWriting (initiated from
1530 SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which
1531 ensures that we can erroneously write a ClientTextbox record
1532 (with no content) while exporting to XLS, which can cause a
1533 corrupted exported document. */
1535 SvxAdjust eHorAlign
= SvxAdjust::Left
;
1536 SdrTextVertAdjust eVerAlign
= SDRTEXTVERTADJUST_TOP
;
1538 // orientation (this is only a fake, drawing does not support real text orientation)
1539 namespace csst
= ::com::sun::star::text
;
1540 csst::WritingMode eWriteMode
= csst::WritingMode_LR_TB
;
1541 switch( maTextData
.maData
.mnOrient
)
1544 case EXC_OBJ_ORIENT_NONE
:
1546 eWriteMode
= csst::WritingMode_LR_TB
;
1547 switch( maTextData
.maData
.GetHorAlign() )
1549 case EXC_OBJ_HOR_LEFT
: eHorAlign
= SvxAdjust::Left
; break;
1550 case EXC_OBJ_HOR_CENTER
: eHorAlign
= SvxAdjust::Center
; break;
1551 case EXC_OBJ_HOR_RIGHT
: eHorAlign
= SvxAdjust::Right
; break;
1552 case EXC_OBJ_HOR_JUSTIFY
: eHorAlign
= SvxAdjust::Block
; break;
1554 switch( maTextData
.maData
.GetVerAlign() )
1556 case EXC_OBJ_VER_TOP
: eVerAlign
= SDRTEXTVERTADJUST_TOP
; break;
1557 case EXC_OBJ_VER_CENTER
: eVerAlign
= SDRTEXTVERTADJUST_CENTER
; break;
1558 case EXC_OBJ_VER_BOTTOM
: eVerAlign
= SDRTEXTVERTADJUST_BOTTOM
; break;
1559 case EXC_OBJ_VER_JUSTIFY
: eVerAlign
= SDRTEXTVERTADJUST_BLOCK
; break;
1564 case EXC_OBJ_ORIENT_90CCW
:
1566 if( SdrObjCustomShape
* pObjCustomShape
= dynamic_cast< SdrObjCustomShape
* >( &rSdrObj
) )
1568 css::beans::PropertyValue aTextRotateAngle
;
1569 aTextRotateAngle
.Name
= "TextRotateAngle";
1570 aTextRotateAngle
.Value
<<= 180.0;
1571 SdrCustomShapeGeometryItem
aGeometryItem(pObjCustomShape
->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY
));
1572 aGeometryItem
.SetPropertyValue( aTextRotateAngle
);
1573 pObjCustomShape
->SetMergedItem( aGeometryItem
);
1575 eWriteMode
= csst::WritingMode_TB_RL
;
1576 switch( maTextData
.maData
.GetHorAlign() )
1578 case EXC_OBJ_HOR_LEFT
: eVerAlign
= SDRTEXTVERTADJUST_TOP
; break;
1579 case EXC_OBJ_HOR_CENTER
: eVerAlign
= SDRTEXTVERTADJUST_CENTER
; break;
1580 case EXC_OBJ_HOR_RIGHT
: eVerAlign
= SDRTEXTVERTADJUST_BOTTOM
; break;
1581 case EXC_OBJ_HOR_JUSTIFY
: eVerAlign
= SDRTEXTVERTADJUST_BLOCK
; break;
1583 MSO_Anchor eTextAnchor
= static_cast<MSO_Anchor
>(rDffConv
.GetPropertyValue( DFF_Prop_anchorText
, mso_anchorTop
));
1584 switch( eTextAnchor
)
1586 case mso_anchorTopCentered
:
1587 case mso_anchorMiddleCentered
:
1588 case mso_anchorBottomCentered
:
1590 eHorAlign
= SvxAdjust::Center
;
1596 switch( maTextData
.maData
.GetVerAlign() )
1598 case EXC_OBJ_VER_TOP
: eHorAlign
= SvxAdjust::Right
; break;
1599 case EXC_OBJ_VER_CENTER
: eHorAlign
= SvxAdjust::Center
; break;
1600 case EXC_OBJ_VER_BOTTOM
: eHorAlign
= SvxAdjust::Left
; break;
1601 case EXC_OBJ_VER_JUSTIFY
: eHorAlign
= SvxAdjust::Block
; break;
1608 case EXC_OBJ_ORIENT_STACKED
:
1610 // sj: STACKED is not supported, maybe it can be optimized here a bit
1613 case EXC_OBJ_ORIENT_90CW
:
1615 eWriteMode
= csst::WritingMode_TB_RL
;
1616 switch( maTextData
.maData
.GetHorAlign() )
1618 case EXC_OBJ_HOR_LEFT
: eVerAlign
= SDRTEXTVERTADJUST_BOTTOM
; break;
1619 case EXC_OBJ_HOR_CENTER
: eVerAlign
= SDRTEXTVERTADJUST_CENTER
; break;
1620 case EXC_OBJ_HOR_RIGHT
: eVerAlign
= SDRTEXTVERTADJUST_TOP
; break;
1621 case EXC_OBJ_HOR_JUSTIFY
: eVerAlign
= SDRTEXTVERTADJUST_BLOCK
; break;
1623 MSO_Anchor eTextAnchor
= static_cast<MSO_Anchor
>(rDffConv
.GetPropertyValue( DFF_Prop_anchorText
, mso_anchorTop
));
1624 switch ( eTextAnchor
)
1626 case mso_anchorTopCentered
:
1627 case mso_anchorMiddleCentered
:
1628 case mso_anchorBottomCentered
:
1630 eHorAlign
= SvxAdjust::Center
;
1636 switch( maTextData
.maData
.GetVerAlign() )
1638 case EXC_OBJ_VER_TOP
: eHorAlign
= SvxAdjust::Left
; break;
1639 case EXC_OBJ_VER_CENTER
: eHorAlign
= SvxAdjust::Center
; break;
1640 case EXC_OBJ_VER_BOTTOM
: eHorAlign
= SvxAdjust::Right
; break;
1641 case EXC_OBJ_VER_JUSTIFY
: eHorAlign
= SvxAdjust::Block
; break;
1648 rSdrObj
.SetMergedItem( SvxAdjustItem( eHorAlign
, EE_PARA_JUST
) );
1649 rSdrObj
.SetMergedItem( SdrTextVertAdjustItem( eVerAlign
) );
1650 rSdrObj
.SetMergedItem( SvxWritingModeItem( eWriteMode
, SDRATTR_TEXTDIRECTION
) );
1653 // base class processing
1654 XclImpRectObj::DoPreProcessSdrObj( rDffConv
, rSdrObj
);
1657 XclImpChartObj::XclImpChartObj( const XclImpRoot
& rRoot
, bool bOwnTab
) :
1658 XclImpRectObj( rRoot
),
1661 SetSimpleMacro( false );
1662 SetCustomDffObj( true );
1665 void XclImpChartObj::ReadChartSubStream( XclImpStream
& rStrm
)
1667 /* If chart is read from a chartsheet (mbOwnTab == true), the BOF record
1668 has already been read. If chart is embedded as object, the next record
1669 has to be the BOF record. */
1672 /* #i109800# The input stream may point somewhere inside the chart
1673 substream and not exactly to the leading BOF record. To read this
1674 record correctly in the following, the stream has to rewind it, so
1675 that the next call to StartNextRecord() will find it correctly. */
1676 if( rStrm
.GetRecId() != EXC_ID5_BOF
)
1677 rStrm
.RewindRecord();
1681 if( (rStrm
.GetNextRecId() == EXC_ID5_BOF
) && rStrm
.StartNextRecord() )
1683 sal_uInt16 nBofType
;
1685 nBofType
= rStrm
.ReaduInt16();
1686 SAL_WARN_IF( nBofType
!= EXC_BOF_CHART
, "sc.filter", "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
1690 SAL_INFO("sc.filter", "XclImpChartObj::ReadChartSubStream - missing chart substream");
1695 // read chart, even if BOF record contains wrong substream identifier
1696 mxChart
= std::make_shared
<XclImpChart
>( GetRoot(), mbOwnTab
);
1697 mxChart
->ReadChartSubStream( rStrm
);
1702 void XclImpChartObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1704 // read OBJ record and the following chart substream
1705 ReadFrameData( rStrm
);
1707 ReadMacro3( rStrm
, nMacroSize
);
1708 // set frame format from OBJ record, it is used if chart itself is transparent
1710 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1713 void XclImpChartObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
1715 // read OBJ record and the following chart substream
1716 ReadFrameData( rStrm
);
1718 ReadMacro4( rStrm
, nMacroSize
);
1719 // set frame format from OBJ record, it is used if chart itself is transparent
1721 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1724 void XclImpChartObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
1726 // read OBJ record and the following chart substream
1727 ReadFrameData( rStrm
);
1729 ReadName5( rStrm
, nNameLen
);
1730 ReadMacro5( rStrm
, nMacroSize
);
1731 ReadChartSubStream( rStrm
);
1732 // set frame format from OBJ record, it is used if chart itself is transparent
1734 mxChart
->UpdateObjFrame( maLineData
, maFillData
);
1737 void XclImpChartObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16
/*nSubRecSize*/ )
1739 // read the following chart substream
1740 if( nSubRecId
== EXC_ID_OBJEND
)
1742 // enable CONTINUE handling for the entire chart substream
1743 rStrm
.ResetRecord( true );
1744 ReadChartSubStream( rStrm
);
1745 /* disable CONTINUE handling again to be able to read
1746 following CONTINUE records as MSODRAWING records. */
1747 rStrm
.ResetRecord( false );
1751 std::size_t XclImpChartObj::DoGetProgressSize() const
1753 return mxChart
? mxChart
->GetProgressSize() : 1;
1756 SdrObjectUniquePtr
XclImpChartObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
1758 SdrObjectUniquePtr xSdrObj
;
1759 SfxObjectShell
* pDocShell
= GetDocShell();
1760 if( rDffConv
.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell
&& mxChart
&& !mxChart
->IsPivotChart() )
1762 // create embedded chart object
1763 OUString aEmbObjName
;
1764 OUString
sBaseURL(GetRoot().GetMedium().GetBaseURL());
1765 Reference
< XEmbeddedObject
> xEmbObj
= pDocShell
->GetEmbeddedObjectContainer().
1766 CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID
).GetByteSequence(), aEmbObjName
, &sBaseURL
);
1768 /* Set the size to the embedded object, this prevents that font sizes
1769 of text objects are changed in the chart when the object is
1770 inserted into the draw page. */
1771 sal_Int64 nAspect
= css::embed::Aspects::MSOLE_CONTENT
;
1772 MapUnit aUnit
= VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj
->getMapUnit( nAspect
) );
1773 Size
aSize( OutputDevice::LogicToLogic( rAnchorRect
.GetSize(), MapMode( MapUnit::Map100thMM
), MapMode( aUnit
) ) );
1774 css::awt::Size
aAwtSize( aSize
.Width(), aSize
.Height() );
1775 xEmbObj
->setVisualAreaSize( nAspect
, aAwtSize
);
1777 // #i121334# This call will change the chart's default background fill from white to transparent.
1778 // Add here again if this is wanted (see task description for details)
1779 // ChartHelper::AdaptDefaultsForChart( xEmbObj );
1781 // create the container OLE object
1784 *GetDoc().GetDrawLayer(),
1785 svt::EmbeddedObjectRef(xEmbObj
, nAspect
),
1793 void XclImpChartObj::DoPostProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
1795 const SdrOle2Obj
* pSdrOleObj
= dynamic_cast< const SdrOle2Obj
* >( &rSdrObj
);
1796 if( !(mxChart
&& pSdrOleObj
) )
1799 const Reference
< XEmbeddedObject
>& xEmbObj
= pSdrOleObj
->GetObjRef();
1800 if( xEmbObj
.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj
) ) try
1802 Reference
< XEmbedPersist
> xPersist( xEmbObj
, UNO_QUERY_THROW
);
1803 Reference
< XModel
> xModel( xEmbObj
->getComponent(), UNO_QUERY_THROW
);
1804 mxChart
->Convert( xModel
, rDffConv
, xPersist
->getEntryName(), rSdrObj
.GetLogicRect() );
1806 catch( const Exception
& )
1811 void XclImpChartObj::FinalizeTabChart()
1813 /* #i44077# Calculate and store DFF anchor for sheet charts.
1814 Needed to get used area if this chart is inserted as OLE object. */
1815 OSL_ENSURE( mbOwnTab
, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" );
1817 // set uninitialized page to landscape
1818 if( !GetPageSettings().GetPageData().mbValid
)
1819 GetPageSettings().SetPaperSize( EXC_PAPERSIZE_DEFAULT
, false );
1821 // calculate size of the chart object
1822 const XclPageData
& rPageData
= GetPageSettings().GetPageData();
1823 Size aPaperSize
= rPageData
.GetScPaperSize();
1825 tools::Long nWidth
= XclTools::GetHmmFromTwips( aPaperSize
.Width() );
1826 tools::Long nHeight
= XclTools::GetHmmFromTwips( aPaperSize
.Height() );
1828 // subtract page margins, give some more extra space
1829 nWidth
-= o3tl::saturating_add(XclTools::GetHmmFromInch(rPageData
.mfLeftMargin
+ rPageData
.mfRightMargin
), static_cast<sal_Int32
>(2000));
1830 nHeight
-= o3tl::saturating_add(XclTools::GetHmmFromInch(rPageData
.mfTopMargin
+ rPageData
.mfBottomMargin
), static_cast<sal_Int32
>(1000));
1832 // print column/row headers?
1833 if( rPageData
.mbPrintHeadings
)
1839 // create the object anchor
1840 XclObjAnchor aAnchor
;
1841 aAnchor
.SetRect( GetRoot(), GetCurrScTab(), tools::Rectangle( 1000, 500, nWidth
, nHeight
), MapUnit::Map100thMM
);
1842 SetAnchor( aAnchor
);
1845 XclImpNoteObj::XclImpNoteObj( const XclImpRoot
& rRoot
) :
1846 XclImpTextObj( rRoot
),
1847 maScPos( ScAddress::INITIALIZE_INVALID
),
1850 SetSimpleMacro( false );
1851 // caption object will be created manually
1852 SetInsertSdrObj( false );
1855 void XclImpNoteObj::SetNoteData( const ScAddress
& rScPos
, sal_uInt16 nNoteFlags
)
1858 mnNoteFlags
= nNoteFlags
;
1861 void XclImpNoteObj::DoPreProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
1863 // create formatted text
1864 XclImpTextObj::DoPreProcessSdrObj( rDffConv
, rSdrObj
);
1865 OutlinerParaObject
* pOutlinerObj
= rSdrObj
.GetOutlinerParaObject();
1866 if( maScPos
.IsValid() && pOutlinerObj
)
1868 // create cell note with all data from drawing object
1869 ScNoteUtil::CreateNoteFromObjectData(
1871 rSdrObj
.GetMergedItemSet().CloneAsValue(), // new object on heap expected
1873 rSdrObj
.GetLogicRect(),
1874 ::get_flag( mnNoteFlags
, EXC_NOTE_VISIBLE
) );
1878 XclImpControlHelper::XclImpControlHelper( const XclImpRoot
& rRoot
, XclCtrlBindMode eBindMode
) :
1880 meBindMode( eBindMode
)
1884 XclImpControlHelper::~XclImpControlHelper()
1888 SdrObjectUniquePtr
XclImpControlHelper::CreateSdrObjectFromShape(
1889 const Reference
< XShape
>& rxShape
, const tools::Rectangle
& rAnchorRect
) const
1892 SdrObjectUniquePtr
xSdrObj( SdrObject::getSdrObjectFromXShape( rxShape
) );
1895 xSdrObj
->NbcSetSnapRect( rAnchorRect
);
1896 // #i30543# insert into control layer
1897 xSdrObj
->NbcSetLayer( SC_LAYER_CONTROLS
);
1902 void XclImpControlHelper::ApplySheetLinkProps() const
1905 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( mxShape
);
1906 if( !xCtrlModel
.is() )
1910 SfxObjectShell
* pDocShell
= mrRoot
.GetDocShell();
1914 Reference
< XMultiServiceFactory
> xFactory( pDocShell
->GetModel(), UNO_QUERY
);
1915 if( !xFactory
.is() )
1919 if( mxCellLink
) try
1921 Reference
< XBindableValue
> xBindable( xCtrlModel
, UNO_QUERY_THROW
);
1923 // create argument sequence for createInstanceWithArguments()
1924 CellAddress aApiAddress
;
1925 ScUnoConversion::FillApiAddress( aApiAddress
, *mxCellLink
);
1928 aValue
.Name
= SC_UNONAME_BOUNDCELL
;
1929 aValue
.Value
<<= aApiAddress
;
1931 Sequence
< Any
> aArgs
{ Any(aValue
) };
1933 // create the CellValueBinding instance and set at the control model
1934 OUString aServiceName
;
1935 switch( meBindMode
)
1937 case EXC_CTRL_BINDCONTENT
: aServiceName
= SC_SERVICENAME_VALBIND
; break;
1938 case EXC_CTRL_BINDPOSITION
: aServiceName
= SC_SERVICENAME_LISTCELLBIND
; break;
1940 Reference
< XValueBinding
> xBinding(
1941 xFactory
->createInstanceWithArguments( aServiceName
, aArgs
), UNO_QUERY_THROW
);
1942 xBindable
->setValueBinding( xBinding
);
1944 catch( const Exception
& )
1954 Reference
< XListEntrySink
> xEntrySink( xCtrlModel
, UNO_QUERY_THROW
);
1956 // create argument sequence for createInstanceWithArguments()
1957 CellRangeAddress aApiRange
;
1958 ScUnoConversion::FillApiRange( aApiRange
, *mxSrcRange
);
1961 aValue
.Name
= SC_UNONAME_CELLRANGE
;
1962 aValue
.Value
<<= aApiRange
;
1964 Sequence
< Any
> aArgs
{ Any(aValue
) };
1966 // create the EntrySource instance and set at the control model
1967 Reference
< XListEntrySource
> xEntrySource( xFactory
->createInstanceWithArguments(
1968 SC_SERVICENAME_LISTSOURCE
, aArgs
), UNO_QUERY_THROW
);
1969 xEntrySink
->setListEntrySource( xEntrySource
);
1971 catch( const Exception
& )
1976 void XclImpControlHelper::ProcessControl( const XclImpDrawObjBase
& rDrawObj
) const
1978 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( mxShape
);
1979 if( !xCtrlModel
.is() )
1982 ApplySheetLinkProps();
1984 ScfPropertySet
aPropSet( xCtrlModel
);
1986 // #i51348# set object name at control model
1987 aPropSet
.SetStringProperty( "Name", rDrawObj
.GetObjName() );
1989 // control visible and printable?
1990 aPropSet
.SetBoolProperty( "EnableVisible", rDrawObj
.IsVisible() );
1991 aPropSet
.SetBoolProperty( "Printable", rDrawObj
.IsPrintable() );
1993 // virtual call for type specific processing
1994 DoProcessControl( aPropSet
);
1997 void XclImpControlHelper::ReadCellLinkFormula( XclImpStream
& rStrm
, bool bWithBoundSize
)
1999 ScRangeList aScRanges
;
2000 ReadRangeList( aScRanges
, rStrm
, bWithBoundSize
);
2001 // Use first cell of first range
2002 if ( !aScRanges
.empty() )
2004 const ScRange
& rScRange
= aScRanges
.front();
2005 mxCellLink
= std::make_shared
<ScAddress
>( rScRange
.aStart
);
2009 void XclImpControlHelper::ReadSourceRangeFormula( XclImpStream
& rStrm
, bool bWithBoundSize
)
2011 ScRangeList aScRanges
;
2012 ReadRangeList( aScRanges
, rStrm
, bWithBoundSize
);
2014 if ( !aScRanges
.empty() )
2016 const ScRange
& rScRange
= aScRanges
.front();
2017 mxSrcRange
= std::make_shared
<ScRange
>( rScRange
);
2021 void XclImpControlHelper::DoProcessControl( ScfPropertySet
& ) const
2025 void XclImpControlHelper::ReadRangeList( ScRangeList
& rScRanges
, XclImpStream
& rStrm
)
2027 XclTokenArray aXclTokArr
;
2028 sal_uInt16 nSize
= XclTokenArray::ReadSize(rStrm
);
2030 aXclTokArr
.ReadArray(nSize
, rStrm
);
2031 mrRoot
.GetFormulaCompiler().CreateRangeList( rScRanges
, EXC_FMLATYPE_CONTROL
, aXclTokArr
, rStrm
);
2034 void XclImpControlHelper::ReadRangeList( ScRangeList
& rScRanges
, XclImpStream
& rStrm
, bool bWithBoundSize
)
2036 if( bWithBoundSize
)
2039 nSize
= rStrm
.ReaduInt16();
2042 rStrm
.PushPosition();
2043 ReadRangeList( rScRanges
, rStrm
);
2044 rStrm
.PopPosition();
2045 rStrm
.Ignore( nSize
);
2050 ReadRangeList( rScRanges
, rStrm
);
2054 XclImpTbxObjBase::XclImpTbxObjBase( const XclImpRoot
& rRoot
) :
2055 XclImpTextObj( rRoot
),
2056 XclImpControlHelper( rRoot
, EXC_CTRL_BINDPOSITION
)
2058 SetSimpleMacro( false );
2059 SetCustomDffObj( true );
2064 void lclExtractColor( sal_uInt8
& rnColorIdx
, const DffPropSet
& rDffPropSet
, sal_uInt32 nPropId
)
2066 if( rDffPropSet
.IsProperty( nPropId
) )
2068 sal_uInt32 nColor
= rDffPropSet
.GetPropertyValue( nPropId
, 0 );
2069 if( (nColor
& 0xFF000000) == 0x08000000 )
2070 rnColorIdx
= ::extract_value
< sal_uInt8
>( nColor
, 0, 8 );
2076 void XclImpTbxObjBase::SetDffProperties( const DffPropSet
& rDffPropSet
)
2078 maFillData
.mnPattern
= rDffPropSet
.GetPropertyBool( DFF_Prop_fFilled
) ? EXC_PATT_SOLID
: EXC_PATT_NONE
;
2079 lclExtractColor( maFillData
.mnBackColorIdx
, rDffPropSet
, DFF_Prop_fillBackColor
);
2080 lclExtractColor( maFillData
.mnPattColorIdx
, rDffPropSet
, DFF_Prop_fillColor
);
2081 ::set_flag( maFillData
.mnAuto
, EXC_OBJ_LINE_AUTO
, false );
2083 maLineData
.mnStyle
= rDffPropSet
.GetPropertyBool( DFF_Prop_fLine
) ? EXC_OBJ_LINE_SOLID
: EXC_OBJ_LINE_NONE
;
2084 lclExtractColor( maLineData
.mnColorIdx
, rDffPropSet
, DFF_Prop_lineColor
);
2085 ::set_flag( maLineData
.mnAuto
, EXC_OBJ_FILL_AUTO
, false );
2088 bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor
& rDescriptor
) const
2090 return XclControlHelper::FillMacroDescriptor( rDescriptor
, DoGetEventType(), GetMacroName(), GetDocShell() );
2093 void XclImpTbxObjBase::ConvertFont( ScfPropertySet
& rPropSet
) const
2095 if( maTextData
.mxString
)
2097 const XclFormatRunVec
& rFormatRuns
= maTextData
.mxString
->GetFormats();
2098 if( rFormatRuns
.empty() )
2099 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet
);
2101 GetFontBuffer().WriteFontProperties( rPropSet
, EXC_FONTPROPSET_CONTROL
, rFormatRuns
.front().mnFontIdx
);
2105 void XclImpTbxObjBase::ConvertLabel( ScfPropertySet
& rPropSet
) const
2107 if( maTextData
.mxString
)
2109 OUString aLabel
= maTextData
.mxString
->GetText();
2110 if( maTextData
.maData
.mnShortcut
> 0 )
2112 sal_Int32 nPos
= aLabel
.indexOf( static_cast< sal_Unicode
>( maTextData
.maData
.mnShortcut
) );
2114 aLabel
= aLabel
.replaceAt( nPos
, 0, u
"~" );
2116 rPropSet
.SetStringProperty( "Label", aLabel
);
2118 //Excel Alt text <==> Aoo description
2119 //For TBX control, if user does not operate alt text, alt text will be set label text as default value in Excel.
2120 //In this case, DFF_Prop_wzDescription will not be set in excel file.
2121 //So In the end of SvxMSDffManager::ImportShape, description will not be set. But actually in excel,
2122 //the alt text is the label value. So here set description as label text first which is called before ImportShape.
2123 Reference
< css::beans::XPropertySet
> xPropset( mxShape
, UNO_QUERY
);
2126 xPropset
->setPropertyValue( "Description", makeAny(aLabel
) );
2129 SAL_WARN("sc.filter", "Can't set a default text for TBX Control ");
2132 ConvertFont( rPropSet
);
2135 SdrObjectUniquePtr
XclImpTbxObjBase::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
2137 SdrObjectUniquePtr
xSdrObj( rDffConv
.CreateSdrObject( *this, rAnchorRect
) );
2138 rDffConv
.Progress();
2142 void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter
& /*rDffConv*/, SdrObject
& /*rSdrObj*/ ) const
2144 // do not call DoPreProcessSdrObj() from base class (to skip text processing)
2145 ProcessControl( *this );
2148 XclImpButtonObj::XclImpButtonObj( const XclImpRoot
& rRoot
) :
2149 XclImpTbxObjBase( rRoot
)
2153 void XclImpButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2155 // label and text formatting
2156 ConvertLabel( rPropSet
);
2158 /* Horizontal text alignment. For unknown reason, the property type is a
2159 simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
2160 sal_Int16 nHorAlign
= 1;
2161 switch( maTextData
.maData
.GetHorAlign() )
2163 case EXC_OBJ_HOR_LEFT
: nHorAlign
= 0; break;
2164 case EXC_OBJ_HOR_CENTER
: nHorAlign
= 1; break;
2165 case EXC_OBJ_HOR_RIGHT
: nHorAlign
= 2; break;
2167 rPropSet
.SetProperty( "Align", nHorAlign
);
2169 // vertical text alignment
2170 namespace csss
= ::com::sun::star::style
;
2171 csss::VerticalAlignment eVerAlign
= csss::VerticalAlignment_MIDDLE
;
2172 switch( maTextData
.maData
.GetVerAlign() )
2174 case EXC_OBJ_VER_TOP
: eVerAlign
= csss::VerticalAlignment_TOP
; break;
2175 case EXC_OBJ_VER_CENTER
: eVerAlign
= csss::VerticalAlignment_MIDDLE
; break;
2176 case EXC_OBJ_VER_BOTTOM
: eVerAlign
= csss::VerticalAlignment_BOTTOM
; break;
2178 rPropSet
.SetProperty( "VerticalAlign", eVerAlign
);
2180 // always wrap text automatically
2181 rPropSet
.SetBoolProperty( "MultiLine", true );
2184 bool bDefButton
= ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_DEFAULT
);
2185 rPropSet
.SetBoolProperty( "DefaultButton", bDefButton
);
2187 // button type (flags cannot be combined in OOo)
2188 namespace cssa
= ::com::sun::star::awt
;
2189 cssa::PushButtonType eButtonType
= cssa::PushButtonType_STANDARD
;
2190 if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_CLOSE
) )
2191 eButtonType
= cssa::PushButtonType_OK
;
2192 else if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_CANCEL
) )
2193 eButtonType
= cssa::PushButtonType_CANCEL
;
2194 else if( ::get_flag( maTextData
.maData
.mnButtonFlags
, EXC_OBJ_BUTTON_HELP
) )
2195 eButtonType
= cssa::PushButtonType_HELP
;
2196 // property type is short, not enum
2197 rPropSet
.SetProperty( "PushButtonType", sal_Int16( eButtonType
) );
2200 OUString
XclImpButtonObj::DoGetServiceName() const
2202 return "com.sun.star.form.component.CommandButton";
2205 XclTbxEventType
XclImpButtonObj::DoGetEventType() const
2207 return EXC_TBX_EVENT_ACTION
;
2210 XclImpCheckBoxObj::XclImpCheckBoxObj( const XclImpRoot
& rRoot
) :
2211 XclImpTbxObjBase( rRoot
),
2212 mnState( EXC_OBJ_CHECKBOX_UNCHECKED
),
2213 mnCheckBoxFlags( 0 )
2217 void XclImpCheckBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2219 ReadFrameData( rStrm
);
2221 maTextData
.maData
.mnFlags
= rStrm
.ReaduInt16();
2223 ReadName5( rStrm
, nNameLen
);
2224 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2225 ReadCellLinkFormula( rStrm
, true );
2226 maTextData
.maData
.mnTextLen
= rStrm
.ReaduInt16();
2227 maTextData
.ReadByteString( rStrm
);
2228 mnState
= rStrm
.ReaduInt16();
2229 maTextData
.maData
.mnShortcut
= rStrm
.ReaduInt16();
2230 maTextData
.maData
.mnShortcutEA
= rStrm
.ReaduInt16();
2231 mnCheckBoxFlags
= rStrm
.ReaduInt16();
2234 void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2238 case EXC_ID_OBJCBLS
:
2239 // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
2240 mnState
= rStrm
.ReaduInt16();
2242 maTextData
.maData
.mnShortcut
= rStrm
.ReaduInt16();
2243 maTextData
.maData
.mnShortcutEA
= rStrm
.ReaduInt16();
2244 mnCheckBoxFlags
= rStrm
.ReaduInt16();
2246 case EXC_ID_OBJCBLSFMLA
:
2247 ReadCellLinkFormula( rStrm
, false );
2250 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2254 void XclImpCheckBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2256 // label and text formatting
2257 ConvertLabel( rPropSet
);
2260 bool bSupportsTristate
= GetObjType() == EXC_OBJTYPE_CHECKBOX
;
2261 sal_Int16 nApiState
= 0;
2264 case EXC_OBJ_CHECKBOX_UNCHECKED
: nApiState
= 0; break;
2265 case EXC_OBJ_CHECKBOX_CHECKED
: nApiState
= 1; break;
2266 case EXC_OBJ_CHECKBOX_TRISTATE
: nApiState
= bSupportsTristate
? 2 : 1; break;
2268 if( bSupportsTristate
)
2269 rPropSet
.SetBoolProperty( "TriState", nApiState
== 2 );
2270 rPropSet
.SetProperty( "DefaultState", nApiState
);
2273 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
2274 sal_Int16 nEffect
= ::get_flagvalue( mnCheckBoxFlags
, EXC_OBJ_CHECKBOX_FLAT
, AwtVisualEffect::FLAT
, AwtVisualEffect::LOOK3D
);
2275 rPropSet
.SetProperty( "VisualEffect", nEffect
);
2277 // do not wrap text automatically
2278 rPropSet
.SetBoolProperty( "MultiLine", false );
2280 // #i40279# always centered vertically
2281 namespace csss
= ::com::sun::star::style
;
2282 rPropSet
.SetProperty( "VerticalAlign", csss::VerticalAlignment_MIDDLE
);
2285 if( maFillData
.IsFilled() )
2287 sal_Int32 nColor
= static_cast< sal_Int32
>( GetSolidFillColor( maFillData
) );
2288 rPropSet
.SetProperty( "BackgroundColor", nColor
);
2292 OUString
XclImpCheckBoxObj::DoGetServiceName() const
2294 return "com.sun.star.form.component.CheckBox";
2297 XclTbxEventType
XclImpCheckBoxObj::DoGetEventType() const
2299 return EXC_TBX_EVENT_ACTION
;
2302 XclImpOptionButtonObj::XclImpOptionButtonObj( const XclImpRoot
& rRoot
) :
2303 XclImpCheckBoxObj( rRoot
),
2309 void XclImpOptionButtonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2311 ReadFrameData( rStrm
);
2313 maTextData
.maData
.mnFlags
= rStrm
.ReaduInt16();
2315 ReadName5( rStrm
, nNameLen
);
2316 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2317 ReadCellLinkFormula( rStrm
, true );
2318 maTextData
.maData
.mnTextLen
= rStrm
.ReaduInt16();
2319 maTextData
.ReadByteString( rStrm
);
2320 mnState
= rStrm
.ReaduInt16();
2321 maTextData
.maData
.mnShortcut
= rStrm
.ReaduInt16();
2322 maTextData
.maData
.mnShortcutEA
= rStrm
.ReaduInt16();
2323 mnCheckBoxFlags
= rStrm
.ReaduInt16();
2324 mnNextInGroup
= rStrm
.ReaduInt16();
2325 mnFirstInGroup
= rStrm
.ReaduInt16();
2328 void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2332 case EXC_ID_OBJRBODATA
:
2333 mnNextInGroup
= rStrm
.ReaduInt16();
2334 mnFirstInGroup
= rStrm
.ReaduInt16();
2337 XclImpCheckBoxObj::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2341 void XclImpOptionButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2343 XclImpCheckBoxObj::DoProcessControl( rPropSet
);
2345 XclImpOptionButtonObj
* pTbxObj
= dynamic_cast< XclImpOptionButtonObj
* >( GetObjectManager().GetSheetDrawing( GetTab() ).FindDrawObj( mnNextInGroup
).get() );
2346 if ( pTbxObj
&& pTbxObj
->mnFirstInGroup
)
2348 // Group has terminated
2349 // traverse each RadioButton in group and
2350 // a) apply the groupname
2351 // b) propagate the linked cell from the lead radiobutton
2352 // c) apply the correct Ref value
2353 XclImpOptionButtonObj
* pLeader
= pTbxObj
;
2355 sal_Int32 nRefVal
= 1;
2359 Reference
< XControlModel
> xCtrlModel
= XclControlHelper::GetControlModel( pTbxObj
->mxShape
);
2360 if ( xCtrlModel
.is() )
2362 ScfPropertySet
aProps( xCtrlModel
);
2363 OUString sGroupName
= OUString::number( pLeader
->GetDffShapeId() );
2365 aProps
.SetStringProperty( "GroupName", sGroupName
);
2366 aProps
.SetStringProperty( "RefValue", OUString::number( nRefVal
++ ) );
2367 if ( pLeader
->HasCellLink() && !pTbxObj
->HasCellLink() )
2369 // propagate cell link info
2370 pTbxObj
->mxCellLink
= std::make_shared
<ScAddress
>( *pLeader
->mxCellLink
);
2371 pTbxObj
->ApplySheetLinkProps();
2373 pTbxObj
= dynamic_cast< XclImpOptionButtonObj
* >( GetObjectManager().GetSheetDrawing( GetTab() ).FindDrawObj( pTbxObj
->mnNextInGroup
).get() );
2377 } while ( pTbxObj
&& ( pTbxObj
->mnFirstInGroup
!= 1 ) );
2381 // not the leader? try and find it
2385 OUString
XclImpOptionButtonObj::DoGetServiceName() const
2387 return "com.sun.star.form.component.RadioButton";
2390 XclTbxEventType
XclImpOptionButtonObj::DoGetEventType() const
2392 return EXC_TBX_EVENT_ACTION
;
2395 XclImpLabelObj::XclImpLabelObj( const XclImpRoot
& rRoot
) :
2396 XclImpTbxObjBase( rRoot
)
2400 void XclImpLabelObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2402 // label and text formatting
2403 ConvertLabel( rPropSet
);
2405 // text alignment (always top/left aligned)
2406 rPropSet
.SetProperty( "Align", sal_Int16( 0 ) );
2407 namespace csss
= ::com::sun::star::style
;
2408 rPropSet
.SetProperty( "VerticalAlign", csss::VerticalAlignment_TOP
);
2410 // always wrap text automatically
2411 rPropSet
.SetBoolProperty( "MultiLine", true );
2414 OUString
XclImpLabelObj::DoGetServiceName() const
2416 return "com.sun.star.form.component.FixedText";
2419 XclTbxEventType
XclImpLabelObj::DoGetEventType() const
2421 return EXC_TBX_EVENT_MOUSE
;
2424 XclImpGroupBoxObj::XclImpGroupBoxObj( const XclImpRoot
& rRoot
) :
2425 XclImpTbxObjBase( rRoot
),
2426 mnGroupBoxFlags( 0 )
2430 void XclImpGroupBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2432 ReadFrameData( rStrm
);
2434 maTextData
.maData
.mnFlags
= rStrm
.ReaduInt16();
2436 ReadName5( rStrm
, nNameLen
);
2437 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2438 maTextData
.maData
.mnTextLen
= rStrm
.ReaduInt16();
2439 maTextData
.ReadByteString( rStrm
);
2440 maTextData
.maData
.mnShortcut
= rStrm
.ReaduInt16();
2441 maTextData
.maData
.mnShortcutEA
= rStrm
.ReaduInt16( );
2442 mnGroupBoxFlags
= rStrm
.ReaduInt16();
2445 void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2449 case EXC_ID_OBJGBODATA
:
2450 maTextData
.maData
.mnShortcut
= rStrm
.ReaduInt16();
2451 maTextData
.maData
.mnShortcutEA
= rStrm
.ReaduInt16();
2452 mnGroupBoxFlags
= rStrm
.ReaduInt16();
2455 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2459 void XclImpGroupBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2461 // label and text formatting
2462 ConvertLabel( rPropSet
);
2465 OUString
XclImpGroupBoxObj::DoGetServiceName() const
2467 return "com.sun.star.form.component.GroupBox";
2470 XclTbxEventType
XclImpGroupBoxObj::DoGetEventType() const
2472 return EXC_TBX_EVENT_MOUSE
;
2475 XclImpDialogObj::XclImpDialogObj( const XclImpRoot
& rRoot
) :
2476 XclImpTbxObjBase( rRoot
)
2480 void XclImpDialogObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2482 // label and text formatting
2483 ConvertLabel( rPropSet
);
2486 OUString
XclImpDialogObj::DoGetServiceName() const
2488 // dialog frame faked by a groupbox
2489 return "com.sun.star.form.component.GroupBox";
2492 XclTbxEventType
XclImpDialogObj::DoGetEventType() const
2494 return EXC_TBX_EVENT_MOUSE
;
2497 XclImpEditObj::XclImpEditObj( const XclImpRoot
& rRoot
) :
2498 XclImpTbxObjBase( rRoot
),
2499 mnContentType( EXC_OBJ_EDIT_TEXT
),
2506 bool XclImpEditObj::IsNumeric() const
2508 return (mnContentType
== EXC_OBJ_EDIT_INTEGER
) || (mnContentType
== EXC_OBJ_EDIT_DOUBLE
);
2511 void XclImpEditObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2513 ReadFrameData( rStrm
);
2515 maTextData
.maData
.mnFlags
= rStrm
.ReaduInt16();
2517 ReadName5( rStrm
, nNameLen
);
2518 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2519 maTextData
.maData
.mnTextLen
= rStrm
.ReaduInt16();
2520 maTextData
.ReadByteString( rStrm
);
2521 mnContentType
= rStrm
.ReaduInt16();
2522 mnMultiLine
= rStrm
.ReaduInt16();
2523 mnScrollBar
= rStrm
.ReaduInt16();
2524 mnListBoxObjId
= rStrm
.ReaduInt16();
2527 void XclImpEditObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2531 case EXC_ID_OBJEDODATA
:
2532 mnContentType
= rStrm
.ReaduInt16();
2533 mnMultiLine
= rStrm
.ReaduInt16();
2534 mnScrollBar
= rStrm
.ReaduInt16();
2535 mnListBoxObjId
= rStrm
.ReaduInt16();
2538 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2542 void XclImpEditObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2544 if( maTextData
.mxString
)
2546 OUString aText
= maTextData
.mxString
->GetText();
2549 // TODO: OUString::toDouble() does not handle local decimal separator
2550 rPropSet
.SetProperty( "DefaultValue", aText
.toDouble() );
2551 rPropSet
.SetBoolProperty( "Spin", mnScrollBar
!= 0 );
2555 rPropSet
.SetProperty( "DefaultText", aText
);
2556 rPropSet
.SetBoolProperty( "MultiLine", mnMultiLine
!= 0 );
2557 rPropSet
.SetBoolProperty( "VScroll", mnScrollBar
!= 0 );
2560 ConvertFont( rPropSet
);
2563 OUString
XclImpEditObj::DoGetServiceName() const
2565 return IsNumeric() ?
2566 OUString( "com.sun.star.form.component.NumericField" ) :
2567 OUString( "com.sun.star.form.component.TextField" );
2570 XclTbxEventType
XclImpEditObj::DoGetEventType() const
2572 return EXC_TBX_EVENT_TEXT
;
2575 XclImpTbxObjScrollableBase::XclImpTbxObjScrollableBase( const XclImpRoot
& rRoot
) :
2576 XclImpTbxObjBase( rRoot
),
2588 void XclImpTbxObjScrollableBase::ReadSbs( XclImpStream
& rStrm
)
2591 mnValue
= rStrm
.ReaduInt16();
2592 mnMin
= rStrm
.ReaduInt16();
2593 mnMax
= rStrm
.ReaduInt16();
2594 mnStep
= rStrm
.ReaduInt16();
2595 mnPageStep
= rStrm
.ReaduInt16();
2596 mnOrient
= rStrm
.ReaduInt16();
2597 mnThumbWidth
= rStrm
.ReaduInt16();
2598 mnScrollFlags
= rStrm
.ReaduInt16();
2601 void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2608 case EXC_ID_OBJSBSFMLA
:
2609 ReadCellLinkFormula( rStrm
, false );
2612 XclImpTbxObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2616 XclImpSpinButtonObj::XclImpSpinButtonObj( const XclImpRoot
& rRoot
) :
2617 XclImpTbxObjScrollableBase( rRoot
)
2621 void XclImpSpinButtonObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2623 ReadFrameData( rStrm
);
2625 ReadName5( rStrm
, nNameLen
);
2626 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2627 ReadCellLinkFormula( rStrm
, true );
2630 void XclImpSpinButtonObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2632 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2633 rPropSet
.SetProperty( "Border", css::awt::VisualEffect::NONE
);
2634 rPropSet
.SetProperty
< sal_Int32
>( "DefaultSpinValue", mnValue
);
2635 rPropSet
.SetProperty
< sal_Int32
>( "SpinValueMin", mnMin
);
2636 rPropSet
.SetProperty
< sal_Int32
>( "SpinValueMax", mnMax
);
2637 rPropSet
.SetProperty
< sal_Int32
>( "SpinIncrement", mnStep
);
2639 // Excel spin buttons always vertical
2640 rPropSet
.SetProperty( "Orientation", css::awt::ScrollBarOrientation::VERTICAL
);
2643 OUString
XclImpSpinButtonObj::DoGetServiceName() const
2645 return "com.sun.star.form.component.SpinButton";
2648 XclTbxEventType
XclImpSpinButtonObj::DoGetEventType() const
2650 return EXC_TBX_EVENT_VALUE
;
2653 XclImpScrollBarObj::XclImpScrollBarObj( const XclImpRoot
& rRoot
) :
2654 XclImpTbxObjScrollableBase( rRoot
)
2658 void XclImpScrollBarObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2660 ReadFrameData( rStrm
);
2662 ReadName5( rStrm
, nNameLen
);
2663 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2664 ReadCellLinkFormula( rStrm
, true );
2667 void XclImpScrollBarObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2669 // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2670 rPropSet
.SetProperty( "Border", css::awt::VisualEffect::NONE
);
2671 rPropSet
.SetProperty
< sal_Int32
>( "DefaultScrollValue", mnValue
);
2672 rPropSet
.SetProperty
< sal_Int32
>( "ScrollValueMin", mnMin
);
2673 rPropSet
.SetProperty
< sal_Int32
>( "ScrollValueMax", mnMax
);
2674 rPropSet
.SetProperty
< sal_Int32
>( "LineIncrement", mnStep
);
2675 rPropSet
.SetProperty
< sal_Int32
>( "BlockIncrement", mnPageStep
);
2676 rPropSet
.SetProperty( "VisibleSize", ::std::min
< sal_Int32
>( mnPageStep
, 1 ) );
2678 namespace AwtScrollOrient
= ::com::sun::star::awt::ScrollBarOrientation
;
2679 sal_Int32 nApiOrient
= ::get_flagvalue( mnOrient
, EXC_OBJ_SCROLLBAR_HOR
, AwtScrollOrient::HORIZONTAL
, AwtScrollOrient::VERTICAL
);
2680 rPropSet
.SetProperty( "Orientation", nApiOrient
);
2683 OUString
XclImpScrollBarObj::DoGetServiceName() const
2685 return "com.sun.star.form.component.ScrollBar";
2688 XclTbxEventType
XclImpScrollBarObj::DoGetEventType() const
2690 return EXC_TBX_EVENT_VALUE
;
2693 XclImpTbxObjListBase::XclImpTbxObjListBase( const XclImpRoot
& rRoot
) :
2694 XclImpTbxObjScrollableBase( rRoot
),
2699 mbHasDefFontIdx( false )
2703 void XclImpTbxObjListBase::ReadLbsData( XclImpStream
& rStrm
)
2705 ReadSourceRangeFormula( rStrm
, true );
2706 mnEntryCount
= rStrm
.ReaduInt16();
2707 mnSelEntry
= rStrm
.ReaduInt16();
2708 mnListFlags
= rStrm
.ReaduInt16();
2709 mnEditObjId
= rStrm
.ReaduInt16();
2712 void XclImpTbxObjListBase::SetBoxFormatting( ScfPropertySet
& rPropSet
) const
2715 namespace AwtVisualEffect
= ::com::sun::star::awt::VisualEffect
;
2716 sal_Int16 nApiBorder
= ::get_flagvalue( mnListFlags
, EXC_OBJ_LISTBOX_FLAT
, AwtVisualEffect::FLAT
, AwtVisualEffect::LOOK3D
);
2717 rPropSet
.SetProperty( "Border", nApiBorder
);
2720 if( mbHasDefFontIdx
)
2721 GetFontBuffer().WriteFontProperties( rPropSet
, EXC_FONTPROPSET_CONTROL
, maTextData
.maData
.mnDefFontIdx
);
2723 GetFontBuffer().WriteDefaultCtrlFontProperties( rPropSet
);
2726 XclImpListBoxObj::XclImpListBoxObj( const XclImpRoot
& rRoot
) :
2727 XclImpTbxObjListBase( rRoot
)
2731 void XclImpListBoxObj::ReadFullLbsData( XclImpStream
& rStrm
, std::size_t nRecLeft
)
2733 std::size_t nRecEnd
= rStrm
.GetRecPos() + nRecLeft
;
2734 ReadLbsData( rStrm
);
2735 OSL_ENSURE( (rStrm
.GetRecPos() == nRecEnd
) || (rStrm
.GetRecPos() + mnEntryCount
== nRecEnd
),
2736 "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
2737 while (rStrm
.IsValid())
2739 if (rStrm
.GetRecPos() >= nRecEnd
)
2741 maSelection
.push_back( rStrm
.ReaduInt8() );
2745 void XclImpListBoxObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2747 ReadFrameData( rStrm
);
2750 maTextData
.maData
.mnDefFontIdx
= rStrm
.ReaduInt16();
2752 ReadName5( rStrm
, nNameLen
);
2753 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2754 ReadCellLinkFormula( rStrm
, true );
2755 ReadFullLbsData( rStrm
, rStrm
.GetRecLeft() );
2756 mbHasDefFontIdx
= true;
2759 void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2763 case EXC_ID_OBJLBSDATA
:
2764 ReadFullLbsData( rStrm
, nSubRecSize
);
2767 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2771 void XclImpListBoxObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2773 // listbox formatting
2774 SetBoxFormatting( rPropSet
);
2777 sal_uInt8 nSelType
= ::extract_value
< sal_uInt8
>( mnListFlags
, 4, 2 );
2778 bool bMultiSel
= nSelType
!= EXC_OBJ_LISTBOX_SINGLE
;
2779 rPropSet
.SetBoolProperty( "MultiSelection", bMultiSel
);
2781 // selection (do not set, if listbox is linked to a cell)
2785 ScfInt16Vec aSelVec
;
2787 // multi selection: API expects sequence of list entry indexes
2790 sal_Int16 nIndex
= 0;
2791 for( const auto& rItem
: maSelection
)
2794 aSelVec
.push_back( nIndex
);
2798 // single selection: mnSelEntry is one-based, API expects zero-based
2799 else if( mnSelEntry
> 0 )
2800 aSelVec
.push_back( static_cast< sal_Int16
>( mnSelEntry
- 1 ) );
2802 if( !aSelVec
.empty() )
2804 Sequence
<sal_Int16
> aSelSeq(aSelVec
.data(), static_cast<sal_Int32
>(aSelVec
.size()));
2805 rPropSet
.SetProperty( "DefaultSelection", aSelSeq
);
2809 OUString
XclImpListBoxObj::DoGetServiceName() const
2811 return "com.sun.star.form.component.ListBox";
2814 XclTbxEventType
XclImpListBoxObj::DoGetEventType() const
2816 return EXC_TBX_EVENT_CHANGE
;
2819 XclImpDropDownObj::XclImpDropDownObj( const XclImpRoot
& rRoot
) :
2820 XclImpTbxObjListBase( rRoot
),
2825 mnDropDownFlags( 0 ),
2831 sal_uInt16
XclImpDropDownObj::GetDropDownType() const
2833 return ::extract_value
< sal_uInt8
>( mnDropDownFlags
, 0, 2 );
2836 void XclImpDropDownObj::ReadFullLbsData( XclImpStream
& rStrm
)
2838 ReadLbsData( rStrm
);
2839 mnDropDownFlags
= rStrm
.ReaduInt16();
2840 mnLineCount
= rStrm
.ReaduInt16();
2841 mnMinWidth
= rStrm
.ReaduInt16();
2842 maTextData
.maData
.mnTextLen
= rStrm
.ReaduInt16();
2843 maTextData
.ReadByteString( rStrm
);
2844 // dropdowns of auto-filters have 'simple' style, they don't have a text area
2845 if( GetDropDownType() == EXC_OBJ_DROPDOWN_SIMPLE
)
2846 SetProcessSdrObj( false );
2849 void XclImpDropDownObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16
/*nMacroSize*/ )
2851 ReadFrameData( rStrm
);
2854 maTextData
.maData
.mnDefFontIdx
= rStrm
.ReaduInt16();
2856 mnLeft
= rStrm
.ReaduInt16();
2857 mnTop
= rStrm
.ReaduInt16();
2858 mnRight
= rStrm
.ReaduInt16();
2859 mnBottom
= rStrm
.ReaduInt16();
2861 ReadName5( rStrm
, nNameLen
);
2862 ReadMacro5( rStrm
, rStrm
.ReaduInt16() ); // first macro size invalid and unused
2863 ReadCellLinkFormula( rStrm
, true );
2864 ReadFullLbsData( rStrm
);
2865 mbHasDefFontIdx
= true;
2868 void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
2872 case EXC_ID_OBJLBSDATA
:
2873 ReadFullLbsData( rStrm
);
2876 XclImpTbxObjListBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
2880 void XclImpDropDownObj::DoProcessControl( ScfPropertySet
& rPropSet
) const
2882 // dropdown listbox formatting
2883 SetBoxFormatting( rPropSet
);
2884 // enable dropdown button
2885 rPropSet
.SetBoolProperty( "Dropdown", true );
2886 // dropdown line count
2887 rPropSet
.SetProperty( "LineCount", mnLineCount
);
2889 if( GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
)
2891 // text of editable combobox
2892 if( maTextData
.mxString
)
2893 rPropSet
.SetStringProperty( "DefaultText", maTextData
.mxString
->GetText() );
2897 // selection (do not set, if dropdown is linked to a cell)
2898 if( !HasCellLink() && (mnSelEntry
> 0) )
2900 Sequence
< sal_Int16
> aSelSeq
{ o3tl::narrowing
<sal_Int16
>(mnSelEntry
- 1) };
2901 rPropSet
.SetProperty( "DefaultSelection", aSelSeq
);
2906 OUString
XclImpDropDownObj::DoGetServiceName() const
2908 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
) ?
2909 OUString( "com.sun.star.form.component.ComboBox" ) :
2910 OUString( "com.sun.star.form.component.ListBox" );
2913 XclTbxEventType
XclImpDropDownObj::DoGetEventType() const
2915 return (GetDropDownType() == EXC_OBJ_DROPDOWN_COMBOBOX
) ? EXC_TBX_EVENT_TEXT
: EXC_TBX_EVENT_CHANGE
;
2918 XclImpPictureObj::XclImpPictureObj( const XclImpRoot
& rRoot
) :
2919 XclImpRectObj( rRoot
),
2920 XclImpControlHelper( rRoot
, EXC_CTRL_BINDCONTENT
),
2923 mnCtlsStrmSize( 0 ),
2924 mbEmbedded( false ),
2928 mbUseCtlsStrm( false )
2931 SetSimpleMacro( true );
2932 SetCustomDffObj( true );
2935 OUString
XclImpPictureObj::GetOleStorageName() const
2937 OUStringBuffer aStrgName
;
2938 if( (mbEmbedded
|| mbLinked
) && !mbControl
&& (mnStorageId
> 0) )
2940 aStrgName
= mbEmbedded
? std::u16string_view(u
"" EXC_STORAGE_OLE_EMBEDDED
) : std::u16string_view(u
"" EXC_STORAGE_OLE_LINKED
);
2941 static const char spcHexChars
[] = "0123456789ABCDEF";
2942 for( sal_uInt8 nIndex
= 32; nIndex
> 0; nIndex
-= 4 )
2943 aStrgName
.append(OUStringChar( spcHexChars
[ ::extract_value
< sal_uInt8
>( mnStorageId
, nIndex
- 4, 4 ) ] ));
2945 return aStrgName
.makeStringAndClear();
2948 void XclImpPictureObj::DoReadObj3( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
2950 sal_uInt16 nLinkSize
;
2951 ReadFrameData( rStrm
);
2953 nLinkSize
= rStrm
.ReaduInt16();
2955 ReadFlags3( rStrm
);
2956 ReadMacro3( rStrm
, nMacroSize
);
2957 ReadPictFmla( rStrm
, nLinkSize
);
2959 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2960 maGraphic
= XclImpDrawing::ReadImgData( GetRoot(), rStrm
);
2963 void XclImpPictureObj::DoReadObj4( XclImpStream
& rStrm
, sal_uInt16 nMacroSize
)
2965 sal_uInt16 nLinkSize
;
2966 ReadFrameData( rStrm
);
2968 nLinkSize
= rStrm
.ReaduInt16();
2970 ReadFlags3( rStrm
);
2971 ReadMacro4( rStrm
, nMacroSize
);
2972 ReadPictFmla( rStrm
, nLinkSize
);
2974 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2975 maGraphic
= XclImpDrawing::ReadImgData( GetRoot(), rStrm
);
2978 void XclImpPictureObj::DoReadObj5( XclImpStream
& rStrm
, sal_uInt16 nNameLen
, sal_uInt16 nMacroSize
)
2980 sal_uInt16 nLinkSize
;
2981 ReadFrameData( rStrm
);
2983 nLinkSize
= rStrm
.ReaduInt16();
2985 ReadFlags3( rStrm
);
2987 ReadName5( rStrm
, nNameLen
);
2988 ReadMacro5( rStrm
, nMacroSize
);
2989 ReadPictFmla( rStrm
, nLinkSize
);
2991 if( (rStrm
.GetNextRecId() == EXC_ID3_IMGDATA
) && rStrm
.StartNextRecord() )
2993 // page background is stored as hidden picture with name "__BkgndObj"
2994 if ( IsHidden() && (GetObjName() == "__BkgndObj") )
2995 GetPageSettings().ReadImgData( rStrm
);
2997 maGraphic
= XclImpDrawing::ReadImgData( GetRoot(), rStrm
);
3001 void XclImpPictureObj::DoReadObj8SubRec( XclImpStream
& rStrm
, sal_uInt16 nSubRecId
, sal_uInt16 nSubRecSize
)
3005 case EXC_ID_OBJFLAGS
:
3006 ReadFlags8( rStrm
);
3008 case EXC_ID_OBJPICTFMLA
:
3009 ReadPictFmla( rStrm
, rStrm
.ReaduInt16() );
3012 XclImpDrawObjBase::DoReadObj8SubRec( rStrm
, nSubRecId
, nSubRecSize
);
3016 SdrObjectUniquePtr
XclImpPictureObj::DoCreateSdrObj( XclImpDffConverter
& rDffConv
, const tools::Rectangle
& rAnchorRect
) const
3018 // try to create an OLE object or form control
3019 SdrObjectUniquePtr
xSdrObj( rDffConv
.CreateSdrObject( *this, rAnchorRect
) );
3021 // insert a graphic replacement for unsupported ole object ( if none already
3022 // exists ) Hmm ok, it's possibly that there has been some imported
3023 // graphic at a base level but unlikely, normally controls have a valid
3024 // preview in the IMGDATA record ( see below )
3025 // It might be possible to push such an imported graphic up to this
3026 // XclImpPictureObj instance but there are so many layers of indirection I
3027 // don't see an easy way. This way at least ensures that we can
3028 // avoid a 'blank' shape that can result from a failed control import
3029 if ( !xSdrObj
&& IsOcxControl() && maGraphic
.GetType() == GraphicType::NONE
)
3031 const_cast< XclImpPictureObj
* >( this )->maGraphic
=
3032 SdrOle2Obj::GetEmptyOLEReplacementGraphic();
3034 // no OLE - create a plain picture from IMGDATA record data
3035 if( !xSdrObj
&& (maGraphic
.GetType() != GraphicType::NONE
) )
3039 *GetDoc().GetDrawLayer(),
3042 ConvertRectStyle( *xSdrObj
);
3045 rDffConv
.Progress();
3049 OUString
XclImpPictureObj::GetObjName() const
3051 if( IsOcxControl() )
3053 OUString
sName( GetObjectManager().GetOleNameOverride( GetTab(), GetObjId() ) );
3054 if (!sName
.isEmpty())
3057 return XclImpDrawObjBase::GetObjName();
3060 void XclImpPictureObj::DoPreProcessSdrObj( XclImpDffConverter
& rDffConv
, SdrObject
& rSdrObj
) const
3062 if( IsOcxControl() )
3064 // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature
3065 ProcessControl( *this );
3067 else if( mbEmbedded
|| mbLinked
)
3069 // trace missing "printable" feature
3070 XclImpRectObj::DoPreProcessSdrObj( rDffConv
, rSdrObj
);
3072 SfxObjectShell
* pDocShell
= GetDocShell();
3073 SdrOle2Obj
* pOleSdrObj
= dynamic_cast< SdrOle2Obj
* >( &rSdrObj
);
3074 if( pOleSdrObj
&& pDocShell
)
3076 comphelper::EmbeddedObjectContainer
& rEmbObjCont
= pDocShell
->GetEmbeddedObjectContainer();
3077 Reference
< XEmbeddedObject
> xEmbObj
= pOleSdrObj
->GetObjRef();
3078 OUString
aOldName( pOleSdrObj
->GetPersistName() );
3080 /* The object persistence should be already in the storage, but
3081 the object still might not be inserted into the container. */
3082 if( rEmbObjCont
.HasEmbeddedObject( aOldName
) )
3084 if( !rEmbObjCont
.HasEmbeddedObject( xEmbObj
) )
3085 // filter code is allowed to call the following method
3086 rEmbObjCont
.AddEmbeddedObject( xEmbObj
, aOldName
);
3090 /* If the object is still not in container it must be inserted
3091 there, the name must be generated in this case. */
3093 rEmbObjCont
.InsertEmbeddedObject( xEmbObj
, aNewName
);
3094 if( aOldName
!= aNewName
)
3095 // SetPersistName, not SetName
3096 pOleSdrObj
->SetPersistName( aNewName
);
3102 void XclImpPictureObj::ReadFlags3( XclImpStream
& rStrm
)
3105 nFlags
= rStrm
.ReaduInt16();
3106 mbSymbol
= ::get_flag( nFlags
, EXC_OBJ_PIC_SYMBOL
);
3109 void XclImpPictureObj::ReadFlags8( XclImpStream
& rStrm
)
3112 nFlags
= rStrm
.ReaduInt16();
3113 mbSymbol
= ::get_flag( nFlags
, EXC_OBJ_PIC_SYMBOL
);
3114 mbControl
= ::get_flag( nFlags
, EXC_OBJ_PIC_CONTROL
);
3115 mbUseCtlsStrm
= ::get_flag( nFlags
, EXC_OBJ_PIC_CTLSSTREAM
);
3116 OSL_ENSURE( mbControl
|| !mbUseCtlsStrm
, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
3117 SetProcessSdrObj( mbControl
|| !mbUseCtlsStrm
);
3120 void XclImpPictureObj::ReadPictFmla( XclImpStream
& rStrm
, sal_uInt16 nLinkSize
)
3122 std::size_t nLinkEnd
= rStrm
.GetRecPos() + nLinkSize
;
3123 if( nLinkSize
>= 6 )
3125 sal_uInt16 nFmlaSize
;
3126 nFmlaSize
= rStrm
.ReaduInt16();
3127 OSL_ENSURE( nFmlaSize
> 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
3128 // BIFF3/BIFF4 do not support storages, nothing to do here
3129 if( (nFmlaSize
> 0) && (GetBiff() >= EXC_BIFF5
) )
3133 nToken
= rStrm
.ReaduInt8();
3135 // different processing for linked vs. embedded OLE objects
3136 if( nToken
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX
, EXC_TOKCLASS_REF
) )
3144 sal_uInt16 nNameIdx
;
3145 nRefIdx
= rStrm
.ReadInt16();
3147 nNameIdx
= rStrm
.ReaduInt16();
3149 const ExtName
* pExtName
= GetOldRoot().pExtNameBuff
->GetNameByIndex( nRefIdx
, nNameIdx
);
3150 if( pExtName
&& pExtName
->IsOLE() )
3151 mnStorageId
= pExtName
->nStorageId
;
3156 sal_uInt16 nXti
, nExtName
;
3157 nXti
= rStrm
.ReaduInt16();
3158 nExtName
= rStrm
.ReaduInt16();
3159 const XclImpExtName
* pExtName
= GetLinkManager().GetExternName( nXti
, nExtName
);
3160 if( pExtName
&& (pExtName
->GetType() == xlExtOLE
) )
3161 mnStorageId
= pExtName
->GetStorageId();
3168 else if( nToken
== XclTokenArrayHelper::GetTokenId( EXC_TOKID_TBL
, EXC_TOKCLASS_NONE
) )
3171 OSL_ENSURE( nFmlaSize
== 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
3172 rStrm
.Ignore( nFmlaSize
- 1 ); // token ID already read
3174 rStrm
.Ignore( 1 ); // padding byte
3176 // a class name may follow inside the picture link
3177 if( rStrm
.GetRecPos() + 2 <= nLinkEnd
)
3179 sal_uInt16 nLen
= rStrm
.ReaduInt16();
3181 maClassName
= (GetBiff() == EXC_BIFF8
) ? rStrm
.ReadUniString( nLen
) : rStrm
.ReadRawByteString( nLen
);
3184 // else: ignore other formulas, e.g. pictures linked to cell ranges
3188 // seek behind picture link data
3189 rStrm
.Seek( nLinkEnd
);
3191 // read additional data for embedded OLE objects following the picture link
3192 if( IsOcxControl() )
3194 // #i26521# form controls to be ignored
3195 if( maClassName
== "Forms.HTML:Hidden.1" )
3197 SetProcessSdrObj( false );
3201 if( rStrm
.GetRecLeft() <= 8 ) return;
3203 // position and size of control data in 'Ctls' stream
3204 mnCtlsStrmPos
= static_cast< std::size_t >( rStrm
.ReaduInt32() );
3205 mnCtlsStrmSize
= static_cast< std::size_t >( rStrm
.ReaduInt32() );
3207 if( rStrm
.GetRecLeft() <= 8 ) return;
3209 // additional string (16-bit characters), e.g. for progress bar control
3210 sal_uInt32 nAddStrSize
;
3211 nAddStrSize
= rStrm
.ReaduInt32();
3212 OSL_ENSURE( rStrm
.GetRecLeft() >= nAddStrSize
+ 4, "XclImpPictureObj::ReadPictFmla - missing data" );
3213 if( rStrm
.GetRecLeft() >= nAddStrSize
+ 4 )
3215 rStrm
.Ignore( nAddStrSize
);
3216 // cell link and source range
3217 ReadCellLinkFormula( rStrm
, true );
3218 ReadSourceRangeFormula( rStrm
, true );
3221 else if( mbEmbedded
&& (rStrm
.GetRecLeft() >= 4) )
3223 mnStorageId
= rStrm
.ReaduInt32();
3227 // DFF stream conversion ======================================================
3229 void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject
& rSdrObj
, sal_uInt32 nDffShapeId
, ShapeFlag nDffFlags
)
3231 if( nDffShapeId
> 0 )
3233 maSdrInfoMap
[ nDffShapeId
].Set( &rSdrObj
, nDffFlags
);
3234 maSdrObjMap
[ &rSdrObj
] = nDffShapeId
;
3238 void XclImpSolverContainer::RemoveSdrObjectInfo( SdrObject
& rSdrObj
)
3240 // remove info of passed object from the maps
3241 XclImpSdrObjMap::iterator aIt
= maSdrObjMap
.find( &rSdrObj
);
3242 if( aIt
!= maSdrObjMap
.end() )
3244 maSdrInfoMap
.erase( aIt
->second
);
3245 maSdrObjMap
.erase( aIt
);
3248 // remove info of all child objects of a group object
3249 if( SdrObjGroup
* pGroupObj
= dynamic_cast< SdrObjGroup
* >( &rSdrObj
) )
3251 if( SdrObjList
* pSubList
= pGroupObj
->GetSubList() )
3253 // iterate flat over the list because this function already works recursively
3254 SdrObjListIter
aObjIt( pSubList
, SdrIterMode::Flat
);
3255 for( SdrObject
* pChildObj
= aObjIt
.Next(); pChildObj
; pChildObj
= aObjIt
.Next() )
3256 RemoveSdrObjectInfo( *pChildObj
);
3261 void XclImpSolverContainer::UpdateConnectorRules()
3263 for (auto const & pRule
: aCList
)
3265 UpdateConnection( pRule
->nShapeA
, pRule
->pAObj
, &pRule
->nSpFlagsA
);
3266 UpdateConnection( pRule
->nShapeB
, pRule
->pBObj
, &pRule
->nSpFlagsB
);
3267 UpdateConnection( pRule
->nShapeC
, pRule
->pCObj
);
3271 void XclImpSolverContainer::RemoveConnectorRules()
3274 maSdrInfoMap
.clear();
3275 maSdrObjMap
.clear();
3278 void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId
, SdrObject
*& rpSdrObj
, ShapeFlag
* pnDffFlags
)
3280 XclImpSdrInfoMap::const_iterator aIt
= maSdrInfoMap
.find( nDffShapeId
);
3281 if( aIt
!= maSdrInfoMap
.end() )
3283 rpSdrObj
= aIt
->second
.mpSdrObj
;
3285 *pnDffFlags
= aIt
->second
.mnDffFlags
;
3289 XclImpSimpleDffConverter::XclImpSimpleDffConverter( const XclImpRoot
& rRoot
, SvStream
& rDffStrm
) :
3290 SvxMSDffManager( rDffStrm
, rRoot
.GetBasePath(), 0, nullptr, rRoot
.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT
, nullptr ),
3293 SetSvxMSDffSettings( SVXMSDFF_SETTINGS_CROP_BITMAPS
| SVXMSDFF_SETTINGS_IMPORT_EXCEL
);
3296 XclImpSimpleDffConverter::~XclImpSimpleDffConverter()
3300 bool XclImpSimpleDffConverter::GetColorFromPalette( sal_uInt16 nIndex
, Color
& rColor
) const
3302 Color nColor
= GetPalette().GetColor( nIndex
);
3304 if( nColor
== COL_AUTO
)
3311 XclImpDffConverter::XclImpDffConvData::XclImpDffConvData(
3312 XclImpDrawing
& rDrawing
, SdrModel
& rSdrModel
, SdrPage
& rSdrPage
) :
3313 mrDrawing( rDrawing
),
3314 mrSdrModel( rSdrModel
),
3315 mrSdrPage( rSdrPage
),
3316 mnLastCtrlIndex( -1 ),
3317 mbHasCtrlForm( false )
3321 constexpr OUStringLiteral
gaStdFormName( u
"Standard" ); /// Standard name of control forms.
3323 XclImpDffConverter::XclImpDffConverter( const XclImpRoot
& rRoot
, SvStream
& rDffStrm
) :
3324 XclImpSimpleDffConverter( rRoot
, rDffStrm
),
3325 oox::ole::MSConvertOCXControls( rRoot
.GetDocShell()->GetModel() ),
3327 mbNotifyMacroEventRead(false)
3329 const SvtFilterOptions
& rFilterOpt
= SvtFilterOptions::Get();
3330 if( rFilterOpt
.IsMathType2Math() )
3331 mnOleImpFlags
|= OLE_MATHTYPE_2_STARMATH
;
3332 if( rFilterOpt
.IsWinWord2Writer() )
3333 mnOleImpFlags
|= OLE_WINWORD_2_STARWRITER
;
3334 if( rFilterOpt
.IsPowerPoint2Impress() )
3335 mnOleImpFlags
|= OLE_POWERPOINT_2_STARIMPRESS
;
3337 // try to open the 'Ctls' storage stream containing OCX control properties
3338 mxCtlsStrm
= OpenStream( EXC_STREAM_CTLS
);
3340 // default text margin (convert EMU to drawing layer units)
3341 mnDefTextMargin
= EXC_OBJ_TEXT_MARGIN
;
3342 ScaleEmu( mnDefTextMargin
);
3345 XclImpDffConverter::~XclImpDffConverter()
3349 OUString
XclImpObjectManager::GetOleNameOverride( SCTAB nTab
, sal_uInt16 nObjId
)
3352 OUString sCodeName
= GetExtDocOptions().GetCodeName( nTab
);
3354 if (mxOleCtrlNameOverride
.is() && mxOleCtrlNameOverride
->hasByName(sCodeName
))
3356 Reference
< XIndexContainer
> xIdToOleName
;
3357 mxOleCtrlNameOverride
->getByName( sCodeName
) >>= xIdToOleName
;
3358 xIdToOleName
->getByIndex( nObjId
) >>= sOleName
;
3364 void XclImpDffConverter::StartProgressBar( std::size_t nProgressSize
)
3366 mxProgress
= std::make_shared
<ScfProgressBar
>( GetDocShell(), STR_PROGRESS_CALCULATING
);
3367 mxProgress
->AddSegment( nProgressSize
);
3368 mxProgress
->Activate();
3371 void XclImpDffConverter::Progress( std::size_t nDelta
)
3373 OSL_ENSURE( mxProgress
, "XclImpDffConverter::Progress - invalid call, no progress bar" );
3374 mxProgress
->Progress( nDelta
);
3377 void XclImpDffConverter::InitializeDrawing( XclImpDrawing
& rDrawing
, SdrModel
& rSdrModel
, SdrPage
& rSdrPage
)
3379 XclImpDffConvDataRef xConvData
= std::make_shared
<XclImpDffConvData
>( rDrawing
, rSdrModel
, rSdrPage
);
3380 maDataStack
.push_back( xConvData
);
3381 SetModel( &xConvData
->mrSdrModel
, 1440 );
3384 void XclImpDffConverter::ProcessObject( SdrObjList
& rObjList
, XclImpDrawObjBase
& rDrawObj
)
3386 if( !rDrawObj
.IsProcessSdrObj() )
3389 const XclObjAnchor
* pAnchor
= rDrawObj
.GetAnchor();
3393 tools::Rectangle aAnchorRect
= GetConvData().mrDrawing
.CalcAnchorRect( *pAnchor
, false );
3394 if( rDrawObj
.IsValidSize( aAnchorRect
) )
3396 // CreateSdrObject() recursively creates embedded child objects
3397 SdrObjectUniquePtr
xSdrObj( rDrawObj
.CreateSdrObject( *this, aAnchorRect
, false ) );
3399 rDrawObj
.PreProcessSdrObject( *this, *xSdrObj
);
3400 // call InsertSdrObject() also, if SdrObject is missing
3401 InsertSdrObject( rObjList
, rDrawObj
, xSdrObj
.release() );
3405 void XclImpDffConverter::ProcessDrawing( const XclImpDrawObjVector
& rDrawObjs
)
3407 SdrPage
& rSdrPage
= GetConvData().mrSdrPage
;
3408 for( const auto& rxDrawObj
: rDrawObjs
)
3409 ProcessObject( rSdrPage
, *rxDrawObj
);
3412 void XclImpDffConverter::ProcessDrawing( SvStream
& rDffStrm
)
3414 if( rDffStrm
.TellEnd() > 0 )
3416 rDffStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
3417 DffRecordHeader aHeader
;
3418 ReadDffRecordHeader( rDffStrm
, aHeader
);
3419 OSL_ENSURE( aHeader
.nRecType
== DFF_msofbtDgContainer
, "XclImpDffConverter::ProcessDrawing - unexpected record" );
3420 if( aHeader
.nRecType
== DFF_msofbtDgContainer
)
3421 ProcessDgContainer( rDffStrm
, aHeader
);
3425 void XclImpDffConverter::FinalizeDrawing()
3427 OSL_ENSURE( !maDataStack
.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" );
3428 maDataStack
.pop_back();
3429 // restore previous model at core DFF converter
3430 if( !maDataStack
.empty() )
3431 SetModel( &maDataStack
.back()->mrSdrModel
, 1440 );
3434 void XclImpDffConverter::NotifyMacroEventRead()
3436 if (mbNotifyMacroEventRead
)
3438 comphelper::DocumentInfo::notifyMacroEventRead(mxModel
);
3439 mbNotifyMacroEventRead
= true;
3442 SdrObjectUniquePtr
XclImpDffConverter::CreateSdrObject( const XclImpTbxObjBase
& rTbxObj
, const tools::Rectangle
& rAnchorRect
)
3444 SdrObjectUniquePtr xSdrObj
;
3446 OUString aServiceName
= rTbxObj
.GetServiceName();
3447 if( SupportsOleObjects() && !aServiceName
.isEmpty() ) try
3449 // create the form control from scratch
3450 Reference
< XFormComponent
> xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName
), UNO_QUERY_THROW
);
3451 // set controls form, needed in virtual function InsertControl()
3453 // try to insert the control into the form
3454 css::awt::Size aDummySize
;
3455 Reference
< XShape
> xShape
;
3456 XclImpDffConvData
& rConvData
= GetConvData();
3457 if( rConvData
.mxCtrlForm
.is() && InsertControl( xFormComp
, aDummySize
, &xShape
, true ) )
3459 xSdrObj
= rTbxObj
.CreateSdrObjectFromShape( xShape
, rAnchorRect
);
3460 // try to attach a macro to the control
3461 ScriptEventDescriptor aDescriptor
;
3462 if( (rConvData
.mnLastCtrlIndex
>= 0) && rTbxObj
.FillMacroDescriptor( aDescriptor
) )
3464 NotifyMacroEventRead();
3465 Reference
< XEventAttacherManager
> xEventMgr( rConvData
.mxCtrlForm
, UNO_QUERY_THROW
);
3466 xEventMgr
->registerScriptEvent( rConvData
.mnLastCtrlIndex
, aDescriptor
);
3470 catch( const Exception
& )
3477 SdrObjectUniquePtr
XclImpDffConverter::CreateSdrObject( const XclImpPictureObj
& rPicObj
, const tools::Rectangle
& rAnchorRect
)
3479 SdrObjectUniquePtr xSdrObj
;
3481 if( SupportsOleObjects() )
3483 if( rPicObj
.IsOcxControl() )
3485 if( mxCtlsStrm
.is() ) try
3487 /* set controls form, needed in virtual function InsertControl()
3488 called from ReadOCXExcelKludgeStream() */
3491 // read from mxCtlsStrm into xShape, insert the control model into the form
3492 Reference
< XShape
> xShape
;
3493 if( GetConvData().mxCtrlForm
.is() )
3495 Reference
< XFormComponent
> xFComp
;
3496 ReadOCXCtlsStream( mxCtlsStrm
, xFComp
, rPicObj
.GetCtlsStreamPos(), rPicObj
.GetCtlsStreamSize() );
3497 // recreate the method formerly known as ReadOCXExcelKludgeStream()
3500 css::awt::Size aSz
; // not used in import
3501 ScfPropertySet
aPropSet( xFComp
);
3502 aPropSet
.SetStringProperty( "Name", rPicObj
.GetObjName() );
3503 InsertControl( xFComp
, aSz
,&xShape
,true);
3504 xSdrObj
= rPicObj
.CreateSdrObjectFromShape( xShape
, rAnchorRect
);
3508 catch( const Exception
& )
3514 SfxObjectShell
* pDocShell
= GetDocShell();
3515 tools::SvRef
<SotStorage
> xSrcStrg
= GetRootStorage();
3516 OUString aStrgName
= rPicObj
.GetOleStorageName();
3517 if( pDocShell
&& xSrcStrg
.is() && (!aStrgName
.isEmpty()) )
3519 // first try to resolve graphic from DFF storage
3521 tools::Rectangle aVisArea
;
3522 if( !GetBLIP( GetPropertyValue( DFF_Prop_pib
, 0 ), aGraphic
, &aVisArea
) )
3524 // if not found, use graphic from object (imported from IMGDATA record)
3525 aGraphic
= rPicObj
.GetGraphic();
3527 if( aGraphic
.GetType() != GraphicType::NONE
)
3529 ErrCode nError
= ERRCODE_NONE
;
3530 namespace cssea
= ::com::sun::star::embed::Aspects
;
3531 sal_Int64 nAspects
= rPicObj
.IsSymbol() ? cssea::MSOLE_ICON
: cssea::MSOLE_CONTENT
;
3533 CreateSdrOLEFromStorage(
3534 GetConvData().mrSdrModel
,
3537 pDocShell
->GetStorage(),
3545 GetRoot().GetMedium().GetBaseURL()));
3554 bool XclImpDffConverter::SupportsOleObjects() const
3556 return GetConvData().mrDrawing
.SupportsOleObjects();
3559 // virtual functions ----------------------------------------------------------
3561 void XclImpDffConverter::ProcessClientAnchor2( SvStream
& rDffStrm
,
3562 DffRecordHeader
& rHeader
, DffObjData
& rObjData
)
3564 // find the OBJ record data related to the processed shape
3565 XclImpDffConvData
& rConvData
= GetConvData();
3566 XclImpDrawObjBase
* pDrawObj
= rConvData
.mrDrawing
.FindDrawObj( rObjData
.rSpHd
).get();
3570 OSL_ENSURE( rHeader
.nRecType
== DFF_msofbtClientAnchor
, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" );
3571 XclObjAnchor aAnchor
;
3572 rHeader
.SeekToContent( rDffStrm
);
3573 sal_uInt8
nFlags(0);
3574 rDffStrm
.ReadUChar( nFlags
);
3575 rDffStrm
.SeekRel( 1 ); // flags
3576 rDffStrm
>> aAnchor
; // anchor format equal to BIFF5 OBJ records
3578 if (!rDffStrm
.good())
3580 SAL_WARN("sc.filter", "ProcessClientAnchor2 short read");
3584 pDrawObj
->SetAnchor( aAnchor
);
3585 rObjData
.aChildAnchor
= rConvData
.mrDrawing
.CalcAnchorRect( aAnchor
, true );
3586 rObjData
.bChildAnchor
= true;
3587 // page anchoring is the best approximation we have if mbMove
3589 rObjData
.bPageAnchor
= ( nFlags
& 0x1 );
3594 struct XclImpDrawObjClientData
: public SvxMSDffClientData
3596 const XclImpDrawObjBase
* m_pTopLevelObj
;
3598 XclImpDrawObjClientData()
3599 : m_pTopLevelObj(nullptr)
3602 virtual void NotifyFreeObj(SdrObject
*) override
{}
3607 SdrObject
* XclImpDffConverter::ProcessObj( SvStream
& rDffStrm
, DffObjData
& rDffObjData
,
3608 SvxMSDffClientData
& rClientData
, tools::Rectangle
& /*rTextRect*/, SdrObject
* pOldSdrObj
)
3610 XclImpDffConvData
& rConvData
= GetConvData();
3612 /* pOldSdrObj passes a generated SdrObject. This function owns this object
3613 and can modify it. The function has either to return it back to caller
3614 or to delete it by itself. */
3615 SdrObjectUniquePtr
xSdrObj( pOldSdrObj
);
3617 // find the OBJ record data related to the processed shape
3618 XclImpDrawObjRef xDrawObj
= rConvData
.mrDrawing
.FindDrawObj( rDffObjData
.rSpHd
);
3619 const tools::Rectangle
& rAnchorRect
= rDffObjData
.aChildAnchor
;
3621 // Do not process the global page group shape
3622 bool bGlobalPageGroup( rDffObjData
.nSpFlags
& ShapeFlag::Patriarch
);
3623 if( !xDrawObj
|| !xDrawObj
->IsProcessSdrObj() || bGlobalPageGroup
)
3624 return nullptr; // simply return, xSdrObj will be destroyed
3626 /* Pass pointer to top-level object back to caller. If the processed
3627 object is embedded in a group, the pointer is already set to the
3628 top-level parent object. */
3629 XclImpDrawObjClientData
& rDrawObjClientData
= static_cast<XclImpDrawObjClientData
&>(rClientData
);
3630 const bool bIsTopLevel
= !rDrawObjClientData
.m_pTopLevelObj
;
3632 rDrawObjClientData
.m_pTopLevelObj
= xDrawObj
.get();
3634 // connectors don't have to be area objects
3635 if( dynamic_cast< SdrEdgeObj
* >( xSdrObj
.get() ) )
3636 xDrawObj
->SetAreaObj( false );
3638 /* Check for valid size for all objects. Needed to ignore lots of invisible
3639 phantom objects from deleted rows or columns (for performance reasons).
3640 #i30816# Include objects embedded in groups.
3641 #i58780# Ignore group shapes, size is not initialized. */
3642 bool bEmbeddedGroup
= !bIsTopLevel
&& dynamic_cast< SdrObjGroup
* >( xSdrObj
.get() );
3643 if( !bEmbeddedGroup
&& !xDrawObj
->IsValidSize( rAnchorRect
) )
3644 return nullptr; // simply return, xSdrObj will be destroyed
3646 // set shape information from DFF stream
3647 OUString aObjName
= GetPropertyString( DFF_Prop_wzName
, rDffStrm
);
3648 OUString aHyperlink
= ReadHlinkProperty( rDffStrm
);
3649 bool bVisible
= !GetPropertyBool( DFF_Prop_fHidden
);
3650 bool bAutoMargin
= GetPropertyBool( DFF_Prop_AutoTextMargin
);
3651 xDrawObj
->SetDffData( rDffObjData
, aObjName
, aHyperlink
, bVisible
, bAutoMargin
);
3653 /* Connect textbox data (string, alignment, text orientation) to object.
3654 don't ask for a text-ID, DFF export doesn't set one. */
3655 if( XclImpTextObj
* pTextObj
= dynamic_cast< XclImpTextObj
* >( xDrawObj
.get() ) )
3656 if( const XclImpObjTextData
* pTextData
= rConvData
.mrDrawing
.FindTextData( rDffObjData
.rSpHd
) )
3657 pTextObj
->SetTextData( *pTextData
);
3659 // copy line and fill formatting of TBX form controls from DFF properties
3660 if( XclImpTbxObjBase
* pTbxObj
= dynamic_cast< XclImpTbxObjBase
* >( xDrawObj
.get() ) )
3661 pTbxObj
->SetDffProperties( *this );
3663 // try to create a custom SdrObject that overwrites the passed object
3664 SdrObjectUniquePtr
xNewSdrObj( xDrawObj
->CreateSdrObject( *this, rAnchorRect
, true ) );
3666 xSdrObj
= std::move( xNewSdrObj
);
3668 // process the SdrObject
3671 // filled without color -> set system window color
3672 if( GetPropertyBool( DFF_Prop_fFilled
) && !IsProperty( DFF_Prop_fillColor
) )
3673 xSdrObj
->SetMergedItem( XFillColorItem( OUString(), GetPalette().GetColor( EXC_COLOR_WINDOWBACK
) ) );
3675 // additional processing on the SdrObject
3676 xDrawObj
->PreProcessSdrObject( *this, *xSdrObj
);
3678 /* If the SdrObject will not be inserted into the draw page, delete it
3679 here. Happens e.g. for notes: The PreProcessSdrObject() call above
3680 has inserted the note into the document, and the SdrObject is not
3682 if( !xDrawObj
->IsInsertSdrObj() )
3688 /* Store the relation between shape ID and SdrObject for connectors.
3689 Must be done here (and not in InsertSdrObject() function),
3690 otherwise all SdrObjects embedded in groups would be lost. */
3691 rConvData
.maSolverCont
.InsertSdrObjectInfo( *xSdrObj
, xDrawObj
->GetDffShapeId(), xDrawObj
->GetDffFlags() );
3693 /* If the drawing object is embedded in a group object, call
3694 PostProcessSdrObject() here. For top-level objects this will be
3695 done automatically in InsertSdrObject() but grouped shapes are
3696 inserted into their groups somewhere in the SvxMSDffManager base
3697 class without chance of notification. Unfortunately, now this is
3698 called before the object is really inserted into its group object,
3699 but that should not have any effect for grouped objects. */
3701 xDrawObj
->PostProcessSdrObject( *this, *xSdrObj
);
3704 return xSdrObj
.release();
3707 SdrObject
* XclImpDffConverter::FinalizeObj(DffObjData
& rDffObjData
, SdrObject
* pOldSdrObj
)
3709 XclImpDffConvData
& rConvData
= GetConvData();
3711 /* pOldSdrObj passes a generated SdrObject. This function owns this object
3712 and can modify it. The function has either to return it back to caller
3713 or to delete it by itself. */
3714 SdrObjectUniquePtr
xSdrObj( pOldSdrObj
);
3716 // find the OBJ record data related to the processed shape
3717 XclImpDrawObjRef xDrawObj
= rConvData
.mrDrawing
.FindDrawObj( rDffObjData
.rSpHd
);
3719 if( xSdrObj
&& xDrawObj
)
3722 if ( !rDffObjData
.bPageAnchor
)
3723 ScDrawLayer::SetCellAnchoredFromPosition( *xSdrObj
, GetDoc(), xDrawObj
->GetTab(), false );
3726 return xSdrObj
.release();
3729 bool XclImpDffConverter::InsertControl( const Reference
< XFormComponent
>& rxFormComp
,
3730 const css::awt::Size
& /*rSize*/, Reference
< XShape
>* pxShape
,
3731 bool /*bFloatingCtrl*/ )
3733 if( GetDocShell() ) try
3735 XclImpDffConvData
& rConvData
= GetConvData();
3736 Reference
< XIndexContainer
> xFormIC( rConvData
.mxCtrlForm
, UNO_QUERY_THROW
);
3737 Reference
< XControlModel
> xCtrlModel( rxFormComp
, UNO_QUERY_THROW
);
3739 // create the control shape
3740 Reference
< XShape
> xShape( ScfApiHelper::CreateInstance( GetDocShell(), "com.sun.star.drawing.ControlShape" ), UNO_QUERY_THROW
);
3741 Reference
< XControlShape
> xCtrlShape( xShape
, UNO_QUERY_THROW
);
3743 // insert the new control into the form
3744 sal_Int32 nNewIndex
= xFormIC
->getCount();
3745 xFormIC
->insertByIndex( nNewIndex
, Any( rxFormComp
) );
3746 // on success: store new index of the control for later use (macro events)
3747 rConvData
.mnLastCtrlIndex
= nNewIndex
;
3749 // set control model at control shape and pass back shape to caller
3750 xCtrlShape
->setControl( xCtrlModel
);
3751 if( pxShape
) *pxShape
= xShape
;
3754 catch( const Exception
& )
3756 OSL_FAIL( "XclImpDffConverter::InsertControl - cannot create form control" );
3762 // private --------------------------------------------------------------------
3764 XclImpDffConverter::XclImpDffConvData
& XclImpDffConverter::GetConvData()
3766 OSL_ENSURE( !maDataStack
.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3767 return *maDataStack
.back();
3770 const XclImpDffConverter::XclImpDffConvData
& XclImpDffConverter::GetConvData() const
3772 OSL_ENSURE( !maDataStack
.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3773 return *maDataStack
.back();
3776 OUString
XclImpDffConverter::ReadHlinkProperty( SvStream
& rDffStrm
) const
3778 /* Reads hyperlink data from a complex DFF property. Contents of this
3779 property are equal to the HLINK record, import of this record is
3780 implemented in class XclImpHyperlink. This function has to create an
3781 instance of the XclImpStream class to be able to reuse the
3782 functionality of XclImpHyperlink. */
3784 sal_uInt32 nBufferSize
= GetPropertyValue( DFF_Prop_pihlShape
, 0 );
3785 if( (0 < nBufferSize
) && (nBufferSize
<= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape
, rDffStrm
) )
3787 // create a faked BIFF record that can be read by XclImpStream class
3788 SvMemoryStream aMemStream
;
3789 aMemStream
.WriteUInt16( 0 ).WriteUInt16( nBufferSize
);
3791 // copy from DFF stream to memory stream
3792 ::std::vector
< sal_uInt8
> aBuffer( nBufferSize
);
3793 sal_uInt8
* pnData
= aBuffer
.data();
3794 if (rDffStrm
.ReadBytes(pnData
, nBufferSize
) == nBufferSize
)
3796 aMemStream
.WriteBytes(pnData
, nBufferSize
);
3798 // create BIFF import stream to be able to use XclImpHyperlink class
3799 XclImpStream
aXclStrm( aMemStream
, GetRoot() );
3800 if( aXclStrm
.StartNextRecord() )
3801 aString
= XclImpHyperlink::ReadEmbeddedData( aXclStrm
);
3807 bool XclImpDffConverter::ProcessDgContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rDgHeader
)
3809 std::size_t nEndPos
= rDgHeader
.GetRecEndFilePos();
3810 bool isBreak(false);
3811 while (!isBreak
&& rDffStrm
.good() && rDffStrm
.Tell() < nEndPos
)
3813 DffRecordHeader aHeader
;
3814 ReadDffRecordHeader( rDffStrm
, aHeader
);
3815 switch( aHeader
.nRecType
)
3817 case DFF_msofbtSolverContainer
:
3818 isBreak
= !ProcessSolverContainer( rDffStrm
, aHeader
);
3820 case DFF_msofbtSpgrContainer
:
3821 isBreak
= !ProcessShGrContainer( rDffStrm
, aHeader
);
3824 isBreak
= !aHeader
.SeekToEndOfRecord( rDffStrm
);
3827 // seek to end of drawing page container
3828 isBreak
= !rDgHeader
.SeekToEndOfRecord( rDffStrm
);
3830 // #i12638# #i37900# connector rules
3831 XclImpSolverContainer
& rSolverCont
= GetConvData().maSolverCont
;
3832 rSolverCont
.UpdateConnectorRules();
3833 SolveSolver( rSolverCont
);
3834 rSolverCont
.RemoveConnectorRules();
3838 bool XclImpDffConverter::ProcessShGrContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rShGrHeader
)
3840 std::size_t nEndPos
= rShGrHeader
.GetRecEndFilePos();
3841 bool isBreak(false);
3842 while (!isBreak
&& rDffStrm
.good() && rDffStrm
.Tell() < nEndPos
)
3844 DffRecordHeader aHeader
;
3845 ReadDffRecordHeader( rDffStrm
, aHeader
);
3846 switch( aHeader
.nRecType
)
3848 case DFF_msofbtSpgrContainer
:
3849 case DFF_msofbtSpContainer
:
3850 isBreak
= !ProcessShContainer( rDffStrm
, aHeader
);
3853 isBreak
= !aHeader
.SeekToEndOfRecord( rDffStrm
);
3856 // seek to end of shape group container
3857 return rShGrHeader
.SeekToEndOfRecord( rDffStrm
) && !isBreak
;
3860 bool XclImpDffConverter::ProcessSolverContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rSolverHeader
)
3862 // solver container wants to read the solver container header again
3863 rSolverHeader
.SeekToBegOfRecord( rDffStrm
);
3864 // read the entire solver container
3865 ReadSvxMSDffSolverContainer( rDffStrm
, GetConvData().maSolverCont
);
3866 // seek to end of solver container
3867 return rSolverHeader
.SeekToEndOfRecord( rDffStrm
);
3870 bool XclImpDffConverter::ProcessShContainer( SvStream
& rDffStrm
, const DffRecordHeader
& rShHeader
)
3872 rShHeader
.SeekToBegOfRecord( rDffStrm
);
3873 tools::Rectangle aDummy
;
3874 XclImpDrawObjClientData aDrawObjClientData
;
3875 /* The call to ImportObj() creates and returns a new SdrObject for the
3876 processed shape. We take ownership of the returned object here. If the
3877 shape is a group object, all embedded objects are created recursively,
3878 and the returned group object contains them all. ImportObj() calls the
3879 virtual functions ProcessClientAnchor2() and ProcessObj() and writes
3880 the pointer to the related draw object data (OBJ record) into aDrawObjClientData. */
3881 SdrObjectUniquePtr
xSdrObj( ImportObj( rDffStrm
, aDrawObjClientData
, aDummy
, aDummy
, /*nCalledByGroup*/0, /*pShapeId*/nullptr ) );
3882 if (aDrawObjClientData
.m_pTopLevelObj
&& xSdrObj
)
3883 InsertSdrObject( GetConvData().mrSdrPage
, *aDrawObjClientData
.m_pTopLevelObj
, xSdrObj
.release() );
3884 return rShHeader
.SeekToEndOfRecord( rDffStrm
);
3887 void XclImpDffConverter::InsertSdrObject( SdrObjList
& rObjList
, const XclImpDrawObjBase
& rDrawObj
, SdrObject
* pSdrObj
)
3889 XclImpDffConvData
& rConvData
= GetConvData();
3890 /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
3891 states to skip insertion), the object is automatically deleted. */
3892 SdrObjectUniquePtr
xSdrObj( pSdrObj
);
3893 if( xSdrObj
&& rDrawObj
.IsInsertSdrObj() )
3895 rObjList
.NbcInsertObject( xSdrObj
.release() );
3896 // callback to drawing manager for e.g. tracking of used sheet area
3897 rConvData
.mrDrawing
.OnObjectInserted( rDrawObj
);
3898 // callback to drawing object for post processing (use pSdrObj, xSdrObj already released)
3899 rDrawObj
.PostProcessSdrObject( *this, *pSdrObj
);
3901 /* SdrObject still here? Insertion failed, remove data from shape ID map.
3902 The SdrObject will be destructed then. */
3904 rConvData
.maSolverCont
.RemoveSdrObjectInfo( *xSdrObj
);
3907 void XclImpDffConverter::InitControlForm()
3909 XclImpDffConvData
& rConvData
= GetConvData();
3910 if( rConvData
.mbHasCtrlForm
)
3913 rConvData
.mbHasCtrlForm
= true;
3914 if( !SupportsOleObjects() )
3919 Reference
< XFormsSupplier
> xFormsSupplier( rConvData
.mrSdrPage
.getUnoPage(), UNO_QUERY_THROW
);
3920 Reference
< XNameContainer
> xFormsNC( xFormsSupplier
->getForms(), UNO_SET_THROW
);
3921 // find or create the Standard form used to insert the imported controls
3922 if( xFormsNC
->hasByName( gaStdFormName
) )
3924 xFormsNC
->getByName( gaStdFormName
) >>= rConvData
.mxCtrlForm
;
3926 else if( SfxObjectShell
* pDocShell
= GetDocShell() )
3928 rConvData
.mxCtrlForm
.set( ScfApiHelper::CreateInstance( pDocShell
, "com.sun.star.form.component.Form" ), UNO_QUERY_THROW
);
3929 xFormsNC
->insertByName( gaStdFormName
, Any( rConvData
.mxCtrlForm
) );
3932 catch( const Exception
& )
3937 // Drawing manager ============================================================
3939 XclImpDrawing::XclImpDrawing( const XclImpRoot
& rRoot
, bool bOleObjects
) :
3940 XclImpRoot( rRoot
),
3941 mbOleObjs( bOleObjects
)
3945 XclImpDrawing::~XclImpDrawing()
3949 Graphic
XclImpDrawing::ReadImgData( const XclImpRoot
& rRoot
, XclImpStream
& rStrm
)
3952 sal_uInt16 nFormat
= rStrm
.ReaduInt16();
3953 rStrm
.Ignore( 2 );//nEnv
3954 sal_uInt32 nDataSize
= rStrm
.ReaduInt32();
3955 if( nDataSize
<= rStrm
.GetRecLeft() )
3959 case EXC_IMGDATA_WMF
: ReadWmf( aGraphic
, rStrm
); break;
3960 case EXC_IMGDATA_BMP
: ReadBmp( aGraphic
, rRoot
, rStrm
); break;
3961 default: OSL_FAIL( "XclImpDrawing::ReadImgData - unknown image format" );
3967 void XclImpDrawing::ReadObj( XclImpStream
& rStrm
)
3969 XclImpDrawObjRef xDrawObj
;
3971 /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
3972 records. In this case, the OBJ records are in BIFF5 format. Do a sanity
3973 check here that there is no DFF data loaded before. */
3974 OSL_ENSURE( maDffStrm
.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
3975 if( maDffStrm
.Tell() == 0 ) switch( GetBiff() )
3978 xDrawObj
= XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm
);
3981 xDrawObj
= XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm
);
3985 xDrawObj
= XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm
);
3993 // insert into maRawObjs or into the last open group object
3994 maRawObjs
.InsertGrouped( xDrawObj
);
3995 // to be able to find objects by ID
3996 maObjMapId
[ xDrawObj
->GetObjId() ] = xDrawObj
;
4000 void XclImpDrawing::ReadMsoDrawing( XclImpStream
& rStrm
)
4002 OSL_ENSURE_BIFF( GetBiff() == EXC_BIFF8
);
4003 // disable internal CONTINUE handling
4004 rStrm
.ResetRecord( false );
4005 // read leading MSODRAWING record
4006 ReadDffRecord( rStrm
);
4008 // read following drawing records, but do not start following unrelated record
4010 while( bLoop
) switch( rStrm
.GetNextRecId() )
4012 case EXC_ID_MSODRAWING
:
4013 case EXC_ID_MSODRAWINGSEL
:
4015 rStrm
.StartNextRecord();
4016 ReadDffRecord( rStrm
);
4019 rStrm
.StartNextRecord();
4023 rStrm
.StartNextRecord();
4030 // re-enable internal CONTINUE handling
4031 rStrm
.ResetRecord( true );
4034 XclImpDrawObjRef
XclImpDrawing::FindDrawObj( const DffRecordHeader
& rHeader
) const
4036 /* maObjMap stores objects by position of the client data (OBJ record) in
4037 the DFF stream, which is always behind shape start position of the
4038 passed header. The function upper_bound() finds the first element in
4039 the map whose key is greater than the start position of the header. Its
4040 end position is used to test whether the found object is really related
4042 XclImpDrawObjRef xDrawObj
;
4043 XclImpObjMap::const_iterator aIt
= maObjMap
.upper_bound( rHeader
.GetRecBegFilePos() );
4044 if( (aIt
!= maObjMap
.end()) && (aIt
->first
<= rHeader
.GetRecEndFilePos()) )
4045 xDrawObj
= aIt
->second
;
4049 XclImpDrawObjRef
XclImpDrawing::FindDrawObj( sal_uInt16 nObjId
) const
4051 XclImpDrawObjRef xDrawObj
;
4052 XclImpObjMapById::const_iterator aIt
= maObjMapId
.find( nObjId
);
4053 if( aIt
!= maObjMapId
.end() )
4054 xDrawObj
= aIt
->second
;
4058 const XclImpObjTextData
* XclImpDrawing::FindTextData( const DffRecordHeader
& rHeader
) const
4060 /* maTextMap stores textbox data by position of the client data (TXO
4061 record) in the DFF stream, which is always behind shape start position
4062 of the passed header. The function upper_bound() finds the first
4063 element in the map whose key is greater than the start position of the
4064 header. Its end position is used to test whether the found object is
4065 really related to the shape. */
4066 XclImpObjTextMap::const_iterator aIt
= maTextMap
.upper_bound( rHeader
.GetRecBegFilePos() );
4067 if( (aIt
!= maTextMap
.end()) && (aIt
->first
<= rHeader
.GetRecEndFilePos()) )
4068 return aIt
->second
.get();
4072 void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId
)
4074 maSkipObjs
.push_back( nObjId
);
4077 std::size_t XclImpDrawing::GetProgressSize() const
4079 return std::accumulate(maObjMap
.begin(), maObjMap
.end(), maRawObjs
.GetProgressSize(),
4080 [](const std::size_t& rSum
, const XclImpObjMap::value_type
& rEntry
) { return rSum
+ rEntry
.second
->GetProgressSize(); });
4083 void XclImpDrawing::ImplConvertObjects( XclImpDffConverter
& rDffConv
, SdrModel
& rSdrModel
, SdrPage
& rSdrPage
)
4085 //rhbz#636521, disable undo during conversion. faster, smaller and stops
4086 //temp objects being inserted into the undo list
4087 bool bOrigUndoStatus
= rSdrModel
.IsUndoEnabled();
4088 rSdrModel
.EnableUndo(false);
4089 // register this drawing manager at the passed (global) DFF manager
4090 rDffConv
.InitializeDrawing( *this, rSdrModel
, rSdrPage
);
4091 // process list of objects to be skipped
4092 for( const auto& rSkipObj
: maSkipObjs
)
4093 if( XclImpDrawObjBase
* pDrawObj
= FindDrawObj( rSkipObj
).get() )
4094 pDrawObj
->SetProcessSdrObj( false );
4095 // process drawing objects without DFF data
4096 rDffConv
.ProcessDrawing( maRawObjs
);
4097 // process all objects in the DFF stream
4098 rDffConv
.ProcessDrawing( maDffStrm
);
4099 // unregister this drawing manager at the passed (global) DFF manager
4100 rDffConv
.FinalizeDrawing();
4101 rSdrModel
.EnableUndo(bOrigUndoStatus
);
4104 // protected ------------------------------------------------------------------
4106 void XclImpDrawing::AppendRawObject( const XclImpDrawObjRef
& rxDrawObj
)
4108 OSL_ENSURE( rxDrawObj
, "XclImpDrawing::AppendRawObject - unexpected empty reference" );
4109 maRawObjs
.push_back( rxDrawObj
);
4112 // private --------------------------------------------------------------------
4114 void XclImpDrawing::ReadWmf( Graphic
& rGraphic
, XclImpStream
& rStrm
) // static helper
4116 // extract graphic data from IMGDATA and following CONTINUE records
4118 SvMemoryStream aMemStrm
;
4119 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
4120 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
4121 // import the graphic from memory stream
4122 GDIMetaFile aGDIMetaFile
;
4123 if( ::ReadWindowMetafile( aMemStrm
, aGDIMetaFile
) )
4124 rGraphic
= aGDIMetaFile
;
4127 void XclImpDrawing::ReadBmp( Graphic
& rGraphic
, const XclImpRoot
& rRoot
, XclImpStream
& rStrm
) // static helper
4129 // extract graphic data from IMGDATA and following CONTINUE records
4130 SvMemoryStream aMemStrm
;
4132 /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
4133 DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
4134 pixel depth = 32 bit. After that, 3 unused bytes are added before the
4135 actual pixel data. This does even confuse Excel 5 and later, which
4136 cannot read the image data correctly. */
4137 if( rRoot
.GetBiff() <= EXC_BIFF4
)
4139 rStrm
.PushPosition();
4140 sal_uInt32 nHdrSize
;
4141 sal_uInt16 nWidth
, nHeight
, nPlanes
, nDepth
;
4142 nHdrSize
= rStrm
.ReaduInt32();
4143 nWidth
= rStrm
.ReaduInt16();
4144 nHeight
= rStrm
.ReaduInt16();
4145 nPlanes
= rStrm
.ReaduInt16();
4146 nDepth
= rStrm
.ReaduInt16();
4147 if( (nHdrSize
== 12) && (nPlanes
== 1) && (nDepth
== 32) )
4150 aMemStrm
.SetEndian( SvStreamEndian::LITTLE
);
4151 aMemStrm
.WriteUInt32( nHdrSize
).WriteUInt16( nWidth
).WriteUInt16( nHeight
).WriteUInt16( nPlanes
).WriteUInt16( nDepth
);
4152 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
4154 rStrm
.PopPosition();
4157 // no special handling above -> just copy the remaining record data
4158 if( aMemStrm
.Tell() == 0 )
4159 rStrm
.CopyToStream( aMemStrm
, rStrm
.GetRecLeft() );
4161 // import the graphic from memory stream
4162 aMemStrm
.Seek( STREAM_SEEK_TO_BEGIN
);
4164 if( ReadDIB(aBitmap
, aMemStrm
, false) ) // read DIB without file header
4165 rGraphic
= BitmapEx(aBitmap
);
4168 void XclImpDrawing::ReadDffRecord( XclImpStream
& rStrm
)
4170 maDffStrm
.Seek( STREAM_SEEK_TO_END
);
4171 rStrm
.CopyRecordToStream( maDffStrm
);
4174 void XclImpDrawing::ReadObj8( XclImpStream
& rStrm
)
4176 XclImpDrawObjRef xDrawObj
= XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm
);
4177 // store the new object in the internal containers
4178 maObjMap
[ maDffStrm
.Tell() ] = xDrawObj
;
4179 maObjMapId
[ xDrawObj
->GetObjId() ] = xDrawObj
;
4182 void XclImpDrawing::ReadTxo( XclImpStream
& rStrm
)
4184 XclImpObjTextRef xTextData
= std::make_shared
<XclImpObjTextData
>();
4185 maTextMap
[ maDffStrm
.Tell() ] = xTextData
;
4187 // 1) read the TXO record
4188 xTextData
->maData
.ReadTxo8( rStrm
);
4190 // 2) first CONTINUE with string
4191 xTextData
->mxString
.reset();
4193 if( xTextData
->maData
.mnTextLen
> 0 )
4195 bValid
= (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord();
4196 OSL_ENSURE( bValid
, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
4198 xTextData
->mxString
= std::make_shared
<XclImpString
>( rStrm
.ReadUniString( xTextData
->maData
.mnTextLen
) );
4201 // 3) second CONTINUE with formatting runs
4202 if( xTextData
->maData
.mnFormatSize
> 0 )
4204 bValid
= (rStrm
.GetNextRecId() == EXC_ID_CONT
) && rStrm
.StartNextRecord();
4205 OSL_ENSURE( bValid
, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
4207 xTextData
->ReadFormats( rStrm
);
4211 XclImpSheetDrawing::XclImpSheetDrawing( const XclImpRoot
& rRoot
, SCTAB nScTab
) :
4212 XclImpDrawing( rRoot
, true ),
4213 maScUsedArea( ScAddress::INITIALIZE_INVALID
)
4215 maScUsedArea
.aStart
.SetTab( nScTab
);
4216 maScUsedArea
.aEnd
.SetTab( nScTab
);
4219 void XclImpSheetDrawing::ReadNote( XclImpStream
& rStrm
)
4237 void XclImpSheetDrawing::ReadTabChart( XclImpStream
& rStrm
)
4239 OSL_ENSURE_BIFF( GetBiff() >= EXC_BIFF5
);
4240 auto xChartObj
= std::make_shared
<XclImpChartObj
>( GetRoot(), true );
4241 xChartObj
->ReadChartSubStream( rStrm
);
4242 // insert the chart as raw object without connected DFF data
4243 AppendRawObject( xChartObj
);
4246 void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter
& rDffConv
)
4248 if( SdrModel
* pSdrModel
= GetDoc().GetDrawLayer() )
4249 if( SdrPage
* pSdrPage
= GetSdrPage( maScUsedArea
.aStart
.Tab() ) )
4250 ImplConvertObjects( rDffConv
, *pSdrModel
, *pSdrPage
);
4253 tools::Rectangle
XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor
& rAnchor
, bool /*bDffAnchor*/ ) const
4255 return rAnchor
.GetRect( GetRoot(), maScUsedArea
.aStart
.Tab(), MapUnit::Map100thMM
);
4258 void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase
& rDrawObj
)
4260 ScRange aScObjArea
= rDrawObj
.GetUsedArea( maScUsedArea
.aStart
.Tab() );
4261 if( aScObjArea
.IsValid() )
4262 maScUsedArea
.ExtendTo( aScObjArea
);
4265 // private --------------------------------------------------------------------
4267 void XclImpSheetDrawing::ReadNote3( XclImpStream
& rStrm
)
4271 sal_uInt16 nTotalLen
= rStrm
.ReaduInt16();
4273 ScAddress
aScNotePos( ScAddress::UNINITIALIZED
);
4274 if( !GetAddressConverter().ConvertAddress( aScNotePos
, aXclPos
, maScUsedArea
.aStart
.Tab(), true ) )
4277 sal_uInt16 nPartLen
= ::std::min( nTotalLen
, static_cast< sal_uInt16
>( rStrm
.GetRecLeft() ) );
4278 OUStringBuffer
aNoteText(rStrm
.ReadRawByteString( nPartLen
));
4279 nTotalLen
= nTotalLen
- nPartLen
;
4284 if (rStrm
.GetNextRecId() != EXC_ID_NOTE
)
4286 if (!rStrm
.StartNextRecord())
4289 nPartLen
= rStrm
.ReaduInt16();
4290 OSL_ENSURE( aXclPos
.mnRow
== 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
4291 if( aXclPos
.mnRow
== 0xFFFF )
4293 OSL_ENSURE( nPartLen
<= nTotalLen
, "XclImpObjectManager::ReadNote3 - string too long" );
4294 aNoteText
.append(rStrm
.ReadRawByteString( nPartLen
));
4295 nTotalLen
= nTotalLen
- ::std::min( nTotalLen
, nPartLen
);
4299 // seems to be a new note, record already started -> load the note
4300 rStrm
.Seek( EXC_REC_SEEK_TO_BEGIN
);
4305 ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos
, aNoteText
.makeStringAndClear(), false, false );
4308 void XclImpSheetDrawing::ReadNote8( XclImpStream
& rStrm
)
4311 sal_uInt16 nFlags
, nObjId
;
4313 nFlags
= rStrm
.ReaduInt16();
4314 nObjId
= rStrm
.ReaduInt16();
4316 ScAddress
aScNotePos( ScAddress::UNINITIALIZED
);
4317 if( GetAddressConverter().ConvertAddress( aScNotePos
, aXclPos
, maScUsedArea
.aStart
.Tab(), true ) )
4318 if( nObjId
!= EXC_OBJ_INVALID_ID
)
4319 if( XclImpNoteObj
* pNoteObj
= dynamic_cast< XclImpNoteObj
* >( FindDrawObj( nObjId
).get() ) )
4320 pNoteObj
->SetNoteData( aScNotePos
, nFlags
);
4323 // The object manager =========================================================
4325 XclImpObjectManager::XclImpObjectManager( const XclImpRoot
& rRoot
) :
4328 maDefObjNames
[ EXC_OBJTYPE_GROUP
] = "Group";
4329 maDefObjNames
[ EXC_OBJTYPE_LINE
] = ScResId( STR_SHAPE_LINE
);
4330 maDefObjNames
[ EXC_OBJTYPE_RECTANGLE
] = ScResId( STR_SHAPE_RECTANGLE
);
4331 maDefObjNames
[ EXC_OBJTYPE_OVAL
] = ScResId( STR_SHAPE_OVAL
);
4332 maDefObjNames
[ EXC_OBJTYPE_ARC
] = "Arc";
4333 maDefObjNames
[ EXC_OBJTYPE_CHART
] = "Chart";
4334 maDefObjNames
[ EXC_OBJTYPE_TEXT
] = "Text";
4335 maDefObjNames
[ EXC_OBJTYPE_BUTTON
] = ScResId( STR_FORM_BUTTON
);
4336 maDefObjNames
[ EXC_OBJTYPE_PICTURE
] = "Picture";
4337 maDefObjNames
[ EXC_OBJTYPE_POLYGON
] = "Freeform";
4338 maDefObjNames
[ EXC_OBJTYPE_CHECKBOX
] = ScResId( STR_FORM_CHECKBOX
);
4339 maDefObjNames
[ EXC_OBJTYPE_OPTIONBUTTON
] = ScResId( STR_FORM_OPTIONBUTTON
);
4340 maDefObjNames
[ EXC_OBJTYPE_EDIT
] = "Edit Box";
4341 maDefObjNames
[ EXC_OBJTYPE_LABEL
] = ScResId( STR_FORM_LABEL
);
4342 maDefObjNames
[ EXC_OBJTYPE_DIALOG
] = "Dialog Frame";
4343 maDefObjNames
[ EXC_OBJTYPE_SPIN
] = ScResId( STR_FORM_SPINNER
);
4344 maDefObjNames
[ EXC_OBJTYPE_SCROLLBAR
] = ScResId( STR_FORM_SCROLLBAR
);
4345 maDefObjNames
[ EXC_OBJTYPE_LISTBOX
] = ScResId( STR_FORM_LISTBOX
);
4346 maDefObjNames
[ EXC_OBJTYPE_GROUPBOX
] = ScResId( STR_FORM_GROUPBOX
);
4347 maDefObjNames
[ EXC_OBJTYPE_DROPDOWN
] = ScResId( STR_FORM_DROPDOWN
);
4348 maDefObjNames
[ EXC_OBJTYPE_NOTE
] = "Comment";
4349 maDefObjNames
[ EXC_OBJTYPE_DRAWING
] = ScResId( STR_SHAPE_AUTOSHAPE
);
4352 XclImpObjectManager::~XclImpObjectManager()
4356 void XclImpObjectManager::ReadMsoDrawingGroup( XclImpStream
& rStrm
)
4358 OSL_ENSURE_BIFF( GetBiff() == EXC_BIFF8
);
4359 // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
4360 rStrm
.ResetRecord( true, EXC_ID_MSODRAWINGGROUP
);
4361 maDggStrm
.Seek( STREAM_SEEK_TO_END
);
4362 rStrm
.CopyRecordToStream( maDggStrm
);
4365 XclImpSheetDrawing
& XclImpObjectManager::GetSheetDrawing( SCTAB nScTab
)
4367 XclImpSheetDrawingRef
& rxDrawing
= maSheetDrawings
[ nScTab
];
4369 rxDrawing
= std::make_shared
<XclImpSheetDrawing
>( GetRoot(), nScTab
);
4373 void XclImpObjectManager::ConvertObjects()
4375 // do nothing if the document does not contain a drawing layer
4376 if( !GetDoc().GetDrawLayer() )
4379 // get total progress bar size for all sheet drawing managers
4380 std::size_t nProgressSize
= std::accumulate(maSheetDrawings
.begin(), maSheetDrawings
.end(), std::size_t(0),
4381 [](const std::size_t& rSum
, const XclImpSheetDrawingMap::value_type
& rEntry
) { return rSum
+ rEntry
.second
->GetProgressSize(); });
4382 // nothing to do if progress bar is zero (no objects present)
4383 if( nProgressSize
== 0 )
4386 XclImpDffConverter
aDffConv( GetRoot(), maDggStrm
);
4387 aDffConv
.StartProgressBar( nProgressSize
);
4388 for( auto& rEntry
: maSheetDrawings
)
4389 rEntry
.second
->ConvertObjects( aDffConv
);
4391 // #i112436# don't call ScChartListenerCollection::SetDirty here,
4392 // instead use InterpretDirtyCells in ScDocument::CalcAfterLoad.
4395 OUString
XclImpObjectManager::GetDefaultObjName( const XclImpDrawObjBase
& rDrawObj
) const
4397 OUStringBuffer aDefName
;
4398 DefObjNameMap::const_iterator aIt
= maDefObjNames
.find( rDrawObj
.GetObjType() );
4399 if( aIt
!= maDefObjNames
.end() )
4400 aDefName
.append(aIt
->second
);
4401 return aDefName
.append(' ').append(static_cast<sal_Int32
>(rDrawObj
.GetObjId())).makeStringAndClear();
4404 ScRange
XclImpObjectManager::GetUsedArea( SCTAB nScTab
) const
4406 XclImpSheetDrawingMap::const_iterator aIt
= maSheetDrawings
.find( nScTab
);
4407 if( aIt
!= maSheetDrawings
.end() )
4408 return aIt
->second
->GetUsedArea();
4409 return ScRange( ScAddress::INITIALIZE_INVALID
);
4412 // DFF property set helper ====================================================
4414 XclImpDffPropSet::XclImpDffPropSet( const XclImpRoot
& rRoot
) :
4415 XclImpRoot( rRoot
),
4416 maDffConv( rRoot
, maDummyStrm
)
4420 void XclImpDffPropSet::Read( XclImpStream
& rStrm
)
4422 sal_uInt32 nPropSetSize
;
4424 rStrm
.PushPosition();
4426 nPropSetSize
= rStrm
.ReaduInt32();
4427 rStrm
.PopPosition();
4429 mxMemStrm
.reset( new SvMemoryStream
);
4430 rStrm
.CopyToStream( *mxMemStrm
, 8 + nPropSetSize
);
4431 mxMemStrm
->Seek( STREAM_SEEK_TO_BEGIN
);
4432 maDffConv
.ReadPropSet( *mxMemStrm
, nullptr );
4435 sal_uInt32
XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId
) const
4437 return maDffConv
.GetPropertyValue( nPropId
, 0 );
4440 void XclImpDffPropSet::FillToItemSet( SfxItemSet
& rItemSet
) const
4443 maDffConv
.ApplyAttributes( *mxMemStrm
, rItemSet
);
4446 XclImpStream
& operator>>( XclImpStream
& rStrm
, XclImpDffPropSet
& rPropSet
)
4448 rPropSet
.Read( rStrm
);
4452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */