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