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