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/outdev.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)
911  {
912  if (rStrm.GetRecLeft() < 4)
913  break;
914 
915  sal_uInt16 nSubRecId = rStrm.ReaduInt16();
916  sal_uInt16 nSubRecSize = rStrm.ReaduInt16();
917  rStrm.PushPosition();
918  // sometimes the last subrecord has an invalid length (OBJLBSDATA) -> min()
919  nSubRecSize = static_cast< sal_uInt16 >( ::std::min< std::size_t >( nSubRecSize, rStrm.GetRecLeft() ) );
920 
921  switch( nSubRecId )
922  {
923  case EXC_ID_OBJCMO:
924  OSL_ENSURE( rStrm.GetRecPos() == 4, "XclImpDrawObjBase::ImplReadObj8 - unexpected OBJCMO subrecord" );
925  if( (rStrm.GetRecPos() == 4) && (nSubRecSize >= 6) )
926  {
927  sal_uInt16 nObjFlags;
928  mnObjType = rStrm.ReaduInt16();
929  mnObjId = rStrm.ReaduInt16( );
930  nObjFlags = rStrm.ReaduInt16( );
932  }
933  break;
934  case EXC_ID_OBJMACRO:
935  ReadMacro8( rStrm );
936  break;
937  case EXC_ID_OBJEND:
938  bLoop = false;
939  break;
940  default:
941  DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
942  }
943 
944  rStrm.PopPosition();
945  rStrm.Ignore( nSubRecSize );
946  }
947 
948  /* Call DoReadObj8SubRec() with EXC_ID_OBJEND for further stream
949  processing (e.g. charts), even if the OBJEND subrecord is missing. */
950  DoReadObj8SubRec( rStrm, EXC_ID_OBJEND, 0 );
951 
952  /* Pictures that Excel reads from BIFF5 and writes to BIFF8 still have the
953  IMGDATA record following the OBJ record (but they use the image data
954  stored in DFF). The IMGDATA record may be continued by several CONTINUE
955  records. But the last CONTINUE record may be in fact an MSODRAWING
956  record that contains the DFF data of the next drawing object! So we
957  have to skip just enough CONTINUE records to look at the next
958  MSODRAWING/CONTINUE record. */
959  if( !((rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord()) )
960  return;
961 
962  rStrm.Ignore( 4 );
963  sal_uInt32 nDataSize = rStrm.ReaduInt32();
964  nDataSize -= rStrm.GetRecLeft();
965  // skip following CONTINUE records until IMGDATA ends
966  while (true)
967  {
968  if (!nDataSize)
969  break;
970  if (rStrm.GetNextRecId() != EXC_ID_CONT)
971  break;
972  if (!rStrm.StartNextRecord())
973  break;
974  OSL_ENSURE( nDataSize >= rStrm.GetRecLeft(), "XclImpDrawObjBase::ImplReadObj8 - CONTINUE too long" );
975  nDataSize -= ::std::min< sal_uInt32 >( rStrm.GetRecLeft(), nDataSize );
976  }
977  OSL_ENSURE( nDataSize == 0, "XclImpDrawObjBase::ImplReadObj8 - missing CONTINUE records" );
978  // next record may be MSODRAWING or CONTINUE or anything else
979 }
980 
982 {
983  if( !mObjs.empty() )
984  if( XclImpGroupObj* pGroupObj = dynamic_cast< XclImpGroupObj* >( mObjs.back().get() ) )
985  if( pGroupObj->TryInsert( xDrawObj ) )
986  return;
987  mObjs.push_back( xDrawObj );
988 }
989 
991 {
992  return std::accumulate(mObjs.begin(), mObjs.end(), std::size_t(0),
993  [](const std::size_t& rSum, const XclImpDrawObjRef& rxObj) { return rSum + rxObj->GetProgressSize(); });
994 }
995 
997  XclImpDrawObjBase( rRoot )
998 {
999  SetProcessSdrObj( false );
1000 }
1001 
1003  XclImpDrawObjBase( rRoot ),
1004  mnFirstUngrouped( 0 )
1005 {
1006 }
1007 
1009 {
1010  if( xDrawObj->GetObjId() == mnFirstUngrouped )
1011  return false;
1012  // insert into own list or into nested group
1013  maChildren.InsertGrouped( xDrawObj );
1014  return true;
1015 }
1016 
1017 void XclImpGroupObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1018 {
1019  rStrm.Ignore( 4 );
1020  mnFirstUngrouped = rStrm.ReaduInt16();
1021  rStrm.Ignore( 16 );
1022  ReadMacro3( rStrm, nMacroSize );
1023 }
1024 
1025 void XclImpGroupObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1026 {
1027  rStrm.Ignore( 4 );
1028  mnFirstUngrouped = rStrm.ReaduInt16();
1029  rStrm.Ignore( 16 );
1030  ReadMacro4( rStrm, nMacroSize );
1031 }
1032 
1033 void XclImpGroupObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1034 {
1035  rStrm.Ignore( 4 );
1036  mnFirstUngrouped = rStrm.ReaduInt16();
1037  rStrm.Ignore( 16 );
1038  ReadName5( rStrm, nNameLen );
1039  ReadMacro5( rStrm, nMacroSize );
1040 }
1041 
1043 {
1045 }
1046 
1048 {
1049  std::unique_ptr<SdrObjGroup, SdrObjectFreeOp> xSdrObj(
1050  new SdrObjGroup(
1051  *GetDoc().GetDrawLayer()));
1052  // child objects in BIFF2-BIFF5 have absolute size, not needed to pass own anchor rectangle
1053  SdrObjList& rObjList = *xSdrObj->GetSubList(); // SdrObjGroup always returns existing sublist
1054  for( const auto& rxChild : maChildren )
1055  rDffConv.ProcessObject( rObjList, *rxChild );
1056  rDffConv.Progress();
1057  return xSdrObj;
1058 }
1059 
1061  XclImpDrawObjBase( rRoot ),
1062  mnArrows( 0 ),
1063  mnStartPoint( EXC_OBJ_LINE_TL )
1064 {
1065  SetAreaObj( false );
1066 }
1067 
1068 void XclImpLineObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1069 {
1070  rStrm >> maLineData;
1071  mnArrows = rStrm.ReaduInt16();
1072  mnStartPoint = rStrm.ReaduInt8();
1073  rStrm.Ignore( 1 );
1074  ReadMacro3( rStrm, nMacroSize );
1075 }
1076 
1077 void XclImpLineObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1078 {
1079  rStrm >> maLineData;
1080  mnArrows = rStrm.ReaduInt16();
1081  mnStartPoint = rStrm.ReaduInt8();
1082  rStrm.Ignore( 1 );
1083  ReadMacro4( rStrm, nMacroSize );
1084 }
1085 
1086 void XclImpLineObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1087 {
1088  rStrm >> maLineData;
1089  mnArrows = rStrm.ReaduInt16();
1090  mnStartPoint = rStrm.ReaduInt8();
1091  rStrm.Ignore( 1 );
1092  ReadName5( rStrm, nNameLen );
1093  ReadMacro5( rStrm, nMacroSize );
1094 }
1095 
1097 {
1098  ::basegfx::B2DPolygon aB2DPolygon;
1099  switch( mnStartPoint )
1100  {
1101  default:
1102  case EXC_OBJ_LINE_TL:
1103  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
1104  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
1105  break;
1106  case EXC_OBJ_LINE_TR:
1107  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
1108  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
1109  break;
1110  case EXC_OBJ_LINE_BR:
1111  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Bottom() ) );
1112  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Top() ) );
1113  break;
1114  case EXC_OBJ_LINE_BL:
1115  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Left(), rAnchorRect.Bottom() ) );
1116  aB2DPolygon.append( ::basegfx::B2DPoint( rAnchorRect.Right(), rAnchorRect.Top() ) );
1117  break;
1118  }
1119  SdrObjectUniquePtr xSdrObj(
1120  new SdrPathObj(
1121  *GetDoc().GetDrawLayer(),
1122  OBJ_LINE,
1123  ::basegfx::B2DPolyPolygon(aB2DPolygon)));
1124  ConvertLineStyle( *xSdrObj, maLineData );
1125 
1126  // line ends
1127  sal_uInt8 nArrowType = ::extract_value< sal_uInt8 >( mnArrows, 0, 4 );
1128  bool bLineStart = false;
1129  bool bLineEnd = false;
1130  bool bFilled = false;
1131  switch( nArrowType )
1132  {
1133  case EXC_OBJ_ARROW_OPEN: bLineStart = false; bLineEnd = true; bFilled = false; break;
1134  case EXC_OBJ_ARROW_OPENBOTH: bLineStart = true; bLineEnd = true; bFilled = false; break;
1135  case EXC_OBJ_ARROW_FILLED: bLineStart = false; bLineEnd = true; bFilled = true; break;
1136  case EXC_OBJ_ARROW_FILLEDBOTH: bLineStart = true; bLineEnd = true; bFilled = true; break;
1137  }
1138  if( bLineStart || bLineEnd )
1139  {
1140  sal_uInt8 nArrowWidth = ::extract_value< sal_uInt8 >( mnArrows, 4, 4 );
1141  double fArrowWidth = 3.0;
1142  switch( nArrowWidth )
1143  {
1144  case EXC_OBJ_ARROW_NARROW: fArrowWidth = 2.0; break;
1145  case EXC_OBJ_ARROW_MEDIUM: fArrowWidth = 3.0; break;
1146  case EXC_OBJ_ARROW_WIDE: fArrowWidth = 5.0; break;
1147  }
1148 
1149  sal_uInt8 nArrowLength = ::extract_value< sal_uInt8 >( mnArrows, 8, 4 );
1150  double fArrowLength = 3.0;
1151  switch( nArrowLength )
1152  {
1153  case EXC_OBJ_ARROW_NARROW: fArrowLength = 2.5; break;
1154  case EXC_OBJ_ARROW_MEDIUM: fArrowLength = 3.5; break;
1155  case EXC_OBJ_ARROW_WIDE: fArrowLength = 6.0; break;
1156  }
1157 
1158  ::basegfx::B2DPolygon aArrowPoly;
1159 #define EXC_ARROW_POINT( x, y ) ::basegfx::B2DPoint( fArrowWidth * (x), fArrowLength * (y) )
1160  if( bFilled )
1161  {
1162  aArrowPoly.append( EXC_ARROW_POINT( 0, 100 ) );
1163  aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
1164  aArrowPoly.append( EXC_ARROW_POINT( 100, 100 ) );
1165  }
1166  else
1167  {
1169  aArrowPoly.append( EXC_ARROW_POINT( 50, 0 ) );
1170  aArrowPoly.append( EXC_ARROW_POINT( 100, 100 - 3 * nLineWidth ) );
1171  aArrowPoly.append( EXC_ARROW_POINT( 100 - 5 * nLineWidth, 100 ) );
1172  aArrowPoly.append( EXC_ARROW_POINT( 50, 12 * nLineWidth ) );
1173  aArrowPoly.append( EXC_ARROW_POINT( 5 * nLineWidth, 100 ) );
1174  aArrowPoly.append( EXC_ARROW_POINT( 0, 100 - 3 * nLineWidth ) );
1175  }
1176 #undef EXC_ARROW_POINT
1177 
1178  ::basegfx::B2DPolyPolygon aArrowPolyPoly( aArrowPoly );
1179  tools::Long nWidth = static_cast< tools::Long >( 125 * fArrowWidth );
1180  if( bLineStart )
1181  {
1182  xSdrObj->SetMergedItem( XLineStartItem( EMPTY_OUSTRING, aArrowPolyPoly ) );
1183  xSdrObj->SetMergedItem( XLineStartWidthItem( nWidth ) );
1184  xSdrObj->SetMergedItem( XLineStartCenterItem( false ) );
1185  }
1186  if( bLineEnd )
1187  {
1188  xSdrObj->SetMergedItem( XLineEndItem( EMPTY_OUSTRING, aArrowPolyPoly ) );
1189  xSdrObj->SetMergedItem( XLineEndWidthItem( nWidth ) );
1190  xSdrObj->SetMergedItem( XLineEndCenterItem( false ) );
1191  }
1192  }
1193  rDffConv.Progress();
1194  return xSdrObj;
1195 }
1196 
1198  XclImpDrawObjBase( rRoot ),
1199  mnFrameFlags( 0 )
1200 {
1201  SetAreaObj( true );
1202 }
1203 
1205 {
1206  rStrm >> maFillData >> maLineData;
1207  mnFrameFlags = rStrm.ReaduInt16();
1208 }
1209 
1211 {
1212  ConvertLineStyle( rSdrObj, maLineData );
1213  ConvertFillStyle( rSdrObj, maFillData );
1214  ConvertFrameStyle( rSdrObj, mnFrameFlags );
1215 }
1216 
1217 void XclImpRectObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1218 {
1219  ReadFrameData( rStrm );
1220  ReadMacro3( rStrm, nMacroSize );
1221 }
1222 
1223 void XclImpRectObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1224 {
1225  ReadFrameData( rStrm );
1226  ReadMacro4( rStrm, nMacroSize );
1227 }
1228 
1229 void XclImpRectObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1230 {
1231  ReadFrameData( rStrm );
1232  ReadName5( rStrm, nNameLen );
1233  ReadMacro5( rStrm, nMacroSize );
1234 }
1235 
1237 {
1238  SdrObjectUniquePtr xSdrObj(
1239  new SdrRectObj(
1240  *GetDoc().GetDrawLayer(),
1241  rAnchorRect));
1242  ConvertRectStyle( *xSdrObj );
1243  rDffConv.Progress();
1244  return xSdrObj;
1245 }
1246 
1248  XclImpRectObj( rRoot )
1249 {
1250 }
1251 
1253 {
1254  SdrObjectUniquePtr xSdrObj(
1255  new SdrCircObj(
1256  *GetDoc().GetDrawLayer(),
1257  SdrCircKind::Full,
1258  rAnchorRect));
1259  ConvertRectStyle( *xSdrObj );
1260  rDffConv.Progress();
1261  return xSdrObj;
1262 }
1263 
1265  XclImpDrawObjBase( rRoot ),
1266  mnQuadrant( EXC_OBJ_ARC_TR )
1267 {
1268  SetAreaObj( false ); // arc may be 2-dimensional
1269 }
1270 
1271 void XclImpArcObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1272 {
1273  rStrm >> maFillData >> maLineData;
1274  mnQuadrant = rStrm.ReaduInt8();
1275  rStrm.Ignore( 1 );
1276  ReadMacro3( rStrm, nMacroSize );
1277 }
1278 
1279 void XclImpArcObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1280 {
1281  rStrm >> maFillData >> maLineData;
1282  mnQuadrant = rStrm.ReaduInt8();
1283  rStrm.Ignore( 1 );
1284  ReadMacro4( rStrm, nMacroSize );
1285 }
1286 
1287 void XclImpArcObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1288 {
1289  rStrm >> maFillData >> maLineData;
1290  mnQuadrant = rStrm.ReaduInt8();
1291  rStrm.Ignore( 1 );
1292  ReadName5( rStrm, nNameLen );
1293  ReadMacro5( rStrm, nMacroSize );
1294 }
1295 
1297 {
1298  tools::Rectangle aNewRect = rAnchorRect;
1299  Degree100 nStartAngle;
1300  Degree100 nEndAngle;
1301  switch( mnQuadrant )
1302  {
1303  default:
1304  case EXC_OBJ_ARC_TR:
1305  nStartAngle = 0_deg100;
1306  nEndAngle = 9000_deg100;
1307  aNewRect.AdjustLeft( -(rAnchorRect.GetWidth()) );
1308  aNewRect.AdjustBottom(rAnchorRect.GetHeight() );
1309  break;
1310  case EXC_OBJ_ARC_TL:
1311  nStartAngle = 9000_deg100;
1312  nEndAngle = 18000_deg100;
1313  aNewRect.AdjustRight(rAnchorRect.GetWidth() );
1314  aNewRect.AdjustBottom(rAnchorRect.GetHeight() );
1315  break;
1316  case EXC_OBJ_ARC_BL:
1317  nStartAngle = 18000_deg100;
1318  nEndAngle = 27000_deg100;
1319  aNewRect.AdjustRight(rAnchorRect.GetWidth() );
1320  aNewRect.AdjustTop( -(rAnchorRect.GetHeight()) );
1321  break;
1322  case EXC_OBJ_ARC_BR:
1323  nStartAngle = 27000_deg100;
1324  nEndAngle = 0_deg100;
1325  aNewRect.AdjustLeft( -(rAnchorRect.GetWidth()) );
1326  aNewRect.AdjustTop( -(rAnchorRect.GetHeight()) );
1327  break;
1328  }
1329  SdrCircKind eObjKind = maFillData.IsFilled() ? SdrCircKind::Section : SdrCircKind::Arc;
1330  SdrObjectUniquePtr xSdrObj(
1331  new SdrCircObj(
1332  *GetDoc().GetDrawLayer(),
1333  eObjKind,
1334  aNewRect,
1335  nStartAngle,
1336  nEndAngle));
1337  ConvertFillStyle( *xSdrObj, maFillData );
1338  ConvertLineStyle( *xSdrObj, maLineData );
1339  rDffConv.Progress();
1340  return xSdrObj;
1341 }
1342 
1344  XclImpRectObj( rRoot ),
1345  mnPolyFlags( 0 ),
1346  mnPointCount( 0 )
1347 {
1348  SetAreaObj( false ); // polygon may be 2-dimensional
1349 }
1350 
1352 {
1353  if( (rStrm.GetNextRecId() == EXC_ID_COORDLIST) && rStrm.StartNextRecord() )
1354  {
1355  OSL_ENSURE( rStrm.GetRecLeft() / 4 == mnPointCount, "XclImpPolygonObj::ReadCoordList - wrong polygon point count" );
1356  while (true)
1357  {
1358  if (rStrm.GetRecLeft() < 4)
1359  break;
1360  sal_uInt16 nX = rStrm.ReaduInt16();
1361  sal_uInt16 nY = rStrm.ReaduInt16();
1362  maCoords.emplace_back( nX, nY );
1363  }
1364  }
1365 }
1366 
1367 void XclImpPolygonObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1368 {
1369  ReadFrameData( rStrm );
1370  mnPolyFlags = rStrm.ReaduInt16();
1371  rStrm.Ignore( 10 );
1372  mnPointCount = rStrm.ReaduInt16();
1373  rStrm.Ignore( 8 );
1374  ReadMacro4( rStrm, nMacroSize );
1375  ReadCoordList( rStrm );
1376 }
1377 
1378 void XclImpPolygonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1379 {
1380  ReadFrameData( rStrm );
1381  mnPolyFlags = rStrm.ReaduInt16();
1382  rStrm.Ignore( 10 );
1383  mnPointCount = rStrm.ReaduInt16();
1384  rStrm.Ignore( 8 );
1385  ReadName5( rStrm, nNameLen );
1386  ReadMacro5( rStrm, nMacroSize );
1387  ReadCoordList( rStrm );
1388 }
1389 
1390 namespace {
1391 
1392 ::basegfx::B2DPoint lclGetPolyPoint( const tools::Rectangle& rAnchorRect, const Point& rPoint )
1393 {
1394  return ::basegfx::B2DPoint(
1395  rAnchorRect.Left() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.X(), 16384.0 ) / 16384.0 * rAnchorRect.GetWidth() + 0.5 ),
1396  rAnchorRect.Top() + static_cast< sal_Int32 >( ::std::min< double >( rPoint.Y(), 16384.0 ) / 16384.0 * rAnchorRect.GetHeight() + 0.5 ) );
1397 }
1398 
1399 } // namespace
1400 
1402 {
1403  SdrObjectUniquePtr xSdrObj;
1404  if( maCoords.size() >= 2 )
1405  {
1406  // create the polygon
1407  ::basegfx::B2DPolygon aB2DPolygon;
1408  for( const auto& rCoord : maCoords )
1409  aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, rCoord ) );
1410  // close polygon if specified
1411  if( ::get_flag( mnPolyFlags, EXC_OBJ_POLY_CLOSED ) && (maCoords.front() != maCoords.back()) )
1412  aB2DPolygon.append( lclGetPolyPoint( rAnchorRect, maCoords.front() ) );
1413  // create the SdrObject
1415  xSdrObj.reset(
1416  new SdrPathObj(
1417  *GetDoc().GetDrawLayer(),
1418  eObjKind,
1419  ::basegfx::B2DPolyPolygon(aB2DPolygon)));
1420  ConvertRectStyle( *xSdrObj );
1421  }
1422  rDffConv.Progress();
1423  return xSdrObj;
1424 }
1425 
1427 {
1428  mxString.reset();
1429  if( maData.mnTextLen > 0 )
1430  {
1431  mxString = std::make_shared<XclImpString>( rStrm.ReadRawByteString( maData.mnTextLen ) );
1432  // skip padding byte for word boundaries
1433  if( rStrm.GetRecPos() & 1 ) rStrm.Ignore( 1 );
1434  }
1435 }
1436 
1438 {
1439  if( mxString )
1440  mxString->ReadObjFormats( rStrm, maData.mnFormatSize );
1441  else
1442  rStrm.Ignore( maData.mnFormatSize );
1443 }
1444 
1446  XclImpRectObj( rRoot )
1447 {
1448 }
1449 
1450 void XclImpTextObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1451 {
1452  ReadFrameData( rStrm );
1453  maTextData.maData.ReadObj3( rStrm );
1454  ReadMacro3( rStrm, nMacroSize );
1455  maTextData.ReadByteString( rStrm );
1456  maTextData.ReadFormats( rStrm );
1457 }
1458 
1459 void XclImpTextObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1460 {
1461  ReadFrameData( rStrm );
1462  maTextData.maData.ReadObj3( rStrm );
1463  ReadMacro4( rStrm, nMacroSize );
1464  maTextData.ReadByteString( rStrm );
1465  maTextData.ReadFormats( rStrm );
1466 }
1467 
1468 void XclImpTextObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1469 {
1470  ReadFrameData( rStrm );
1471  maTextData.maData.ReadObj5( rStrm );
1472  ReadName5( rStrm, nNameLen );
1473  ReadMacro5( rStrm, nMacroSize );
1474  maTextData.ReadByteString( rStrm );
1475  rStrm.Ignore( maTextData.maData.mnLinkSize ); // ignore text link formula
1476  maTextData.ReadFormats( rStrm );
1477 }
1478 
1480 {
1481  std::unique_ptr<SdrObjCustomShape, SdrObjectFreeOp> xSdrObj(
1482  new SdrObjCustomShape(
1483  *GetDoc().GetDrawLayer()));
1484  xSdrObj->NbcSetSnapRect( rAnchorRect );
1485  OUString aRectType = "rectangle";
1486  xSdrObj->MergeDefaultAttributes( &aRectType );
1487  ConvertRectStyle( *xSdrObj );
1489  xSdrObj->SetMergedItem( makeSdrTextAutoGrowWidthItem( bAutoSize ) );
1490  xSdrObj->SetMergedItem( makeSdrTextAutoGrowHeightItem( bAutoSize ) );
1491  xSdrObj->SetMergedItem( makeSdrTextWordWrapItem( true ) );
1492  rDffConv.Progress();
1493  return xSdrObj;
1494 }
1495 
1497 {
1498  // set text data
1499  if( SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( &rSdrObj ) )
1500  {
1501  if( maTextData.mxString )
1502  {
1503  if( maTextData.mxString->IsRich() )
1504  {
1505  // rich text
1506  std::unique_ptr< EditTextObject > xEditObj(
1508  std::unique_ptr<OutlinerParaObject> pOutlineObj(new OutlinerParaObject(std::move(xEditObj)));
1509  pOutlineObj->SetOutlinerMode( OutlinerMode::TextObject );
1510  pTextObj->NbcSetOutlinerParaObject( std::move(pOutlineObj) );
1511  }
1512  else
1513  {
1514  // plain text
1515  pTextObj->NbcSetText( maTextData.mxString->GetText() );
1516  }
1517 
1518  /* #i96858# Do not apply any formatting if there is no text.
1519  SdrObjCustomShape::SetVerticalWriting (initiated from
1520  SetMergedItem) calls SdrTextObj::ForceOutlinerParaObject which
1521  ensures that we can erroneously write a ClientTextbox record
1522  (with no content) while exporting to XLS, which can cause a
1523  corrupted exported document. */
1524 
1525  SvxAdjust eHorAlign = SvxAdjust::Left;
1527 
1528  // orientation (this is only a fake, drawing does not support real text orientation)
1529  namespace csst = ::com::sun::star::text;
1530  csst::WritingMode eWriteMode = csst::WritingMode_LR_TB;
1531  switch( maTextData.maData.mnOrient )
1532  {
1533  default:
1534  case EXC_OBJ_ORIENT_NONE:
1535  {
1536  eWriteMode = csst::WritingMode_LR_TB;
1537  switch( maTextData.maData.GetHorAlign() )
1538  {
1539  case EXC_OBJ_HOR_LEFT: eHorAlign = SvxAdjust::Left; break;
1540  case EXC_OBJ_HOR_CENTER: eHorAlign = SvxAdjust::Center; break;
1541  case EXC_OBJ_HOR_RIGHT: eHorAlign = SvxAdjust::Right; break;
1542  case EXC_OBJ_HOR_JUSTIFY: eHorAlign = SvxAdjust::Block; break;
1543  }
1544  switch( maTextData.maData.GetVerAlign() )
1545  {
1546  case EXC_OBJ_VER_TOP: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
1547  case EXC_OBJ_VER_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
1548  case EXC_OBJ_VER_BOTTOM: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
1549  case EXC_OBJ_VER_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
1550  }
1551  }
1552  break;
1553 
1554  case EXC_OBJ_ORIENT_90CCW:
1555  {
1556  if( SdrObjCustomShape* pObjCustomShape = dynamic_cast< SdrObjCustomShape* >( &rSdrObj ) )
1557  {
1558  css::beans::PropertyValue aTextRotateAngle;
1559  aTextRotateAngle.Name = "TextRotateAngle";
1560  aTextRotateAngle.Value <<= 180.0;
1561  SdrCustomShapeGeometryItem aGeometryItem(pObjCustomShape->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
1562  aGeometryItem.SetPropertyValue( aTextRotateAngle );
1563  pObjCustomShape->SetMergedItem( aGeometryItem );
1564  }
1565  eWriteMode = csst::WritingMode_TB_RL;
1566  switch( maTextData.maData.GetHorAlign() )
1567  {
1568  case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
1569  case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
1570  case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
1571  case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
1572  }
1573  MSO_Anchor eTextAnchor = static_cast<MSO_Anchor>(rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ));
1574  switch( eTextAnchor )
1575  {
1576  case mso_anchorTopCentered :
1579  {
1580  eHorAlign = SvxAdjust::Center;
1581  }
1582  break;
1583 
1584  default:
1585  {
1586  switch( maTextData.maData.GetVerAlign() )
1587  {
1588  case EXC_OBJ_VER_TOP: eHorAlign = SvxAdjust::Right; break;
1589  case EXC_OBJ_VER_CENTER: eHorAlign = SvxAdjust::Center; break;
1590  case EXC_OBJ_VER_BOTTOM: eHorAlign = SvxAdjust::Left; break;
1591  case EXC_OBJ_VER_JUSTIFY: eHorAlign = SvxAdjust::Block; break;
1592  }
1593  }
1594  }
1595  }
1596  break;
1597 
1599  {
1600  // sj: STACKED is not supported, maybe it can be optimized here a bit
1601  [[fallthrough]];
1602  }
1603  case EXC_OBJ_ORIENT_90CW:
1604  {
1605  eWriteMode = csst::WritingMode_TB_RL;
1606  switch( maTextData.maData.GetHorAlign() )
1607  {
1608  case EXC_OBJ_HOR_LEFT: eVerAlign = SDRTEXTVERTADJUST_BOTTOM; break;
1609  case EXC_OBJ_HOR_CENTER: eVerAlign = SDRTEXTVERTADJUST_CENTER; break;
1610  case EXC_OBJ_HOR_RIGHT: eVerAlign = SDRTEXTVERTADJUST_TOP; break;
1611  case EXC_OBJ_HOR_JUSTIFY: eVerAlign = SDRTEXTVERTADJUST_BLOCK; break;
1612  }
1613  MSO_Anchor eTextAnchor = static_cast<MSO_Anchor>(rDffConv.GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop ));
1614  switch ( eTextAnchor )
1615  {
1616  case mso_anchorTopCentered :
1619  {
1620  eHorAlign = SvxAdjust::Center;
1621  }
1622  break;
1623 
1624  default:
1625  {
1626  switch( maTextData.maData.GetVerAlign() )
1627  {
1628  case EXC_OBJ_VER_TOP: eHorAlign = SvxAdjust::Left; break;
1629  case EXC_OBJ_VER_CENTER: eHorAlign = SvxAdjust::Center; break;
1630  case EXC_OBJ_VER_BOTTOM: eHorAlign = SvxAdjust::Right; break;
1631  case EXC_OBJ_VER_JUSTIFY: eHorAlign = SvxAdjust::Block; break;
1632  }
1633  }
1634  }
1635  }
1636  break;
1637  }
1638  rSdrObj.SetMergedItem( SvxAdjustItem( eHorAlign, EE_PARA_JUST ) );
1639  rSdrObj.SetMergedItem( SdrTextVertAdjustItem( eVerAlign ) );
1640  rSdrObj.SetMergedItem( SvxWritingModeItem( eWriteMode, SDRATTR_TEXTDIRECTION ) );
1641  }
1642  }
1643  // base class processing
1644  XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
1645 }
1646 
1647 XclImpChartObj::XclImpChartObj( const XclImpRoot& rRoot, bool bOwnTab ) :
1648  XclImpRectObj( rRoot ),
1649  mbOwnTab( bOwnTab )
1650 {
1651  SetSimpleMacro( false );
1652  SetCustomDffObj( true );
1653 }
1654 
1656 {
1657  /* If chart is read from a chartsheet (mbOwnTab == true), the BOF record
1658  has already been read. If chart is embedded as object, the next record
1659  has to be the BOF record. */
1660  if( mbOwnTab )
1661  {
1662  /* #i109800# The input stream may point somewhere inside the chart
1663  substream and not exactly to the leading BOF record. To read this
1664  record correctly in the following, the stream has to rewind it, so
1665  that the next call to StartNextRecord() will find it correctly. */
1666  if( rStrm.GetRecId() != EXC_ID5_BOF )
1667  rStrm.RewindRecord();
1668  }
1669  else
1670  {
1671  if( (rStrm.GetNextRecId() == EXC_ID5_BOF) && rStrm.StartNextRecord() )
1672  {
1673  sal_uInt16 nBofType;
1674  rStrm.Seek( 2 );
1675  nBofType = rStrm.ReaduInt16();
1676  SAL_WARN_IF( nBofType != EXC_BOF_CHART, "sc.filter", "XclImpChartObj::ReadChartSubStream - no chart BOF record" );
1677  }
1678  else
1679  {
1680  SAL_INFO("sc.filter", "XclImpChartObj::ReadChartSubStream - missing chart substream");
1681  return;
1682  }
1683  }
1684 
1685  // read chart, even if BOF record contains wrong substream identifier
1686  mxChart = std::make_shared<XclImpChart>( GetRoot(), mbOwnTab );
1687  mxChart->ReadChartSubStream( rStrm );
1688  if( mbOwnTab )
1689  FinalizeTabChart();
1690 }
1691 
1692 void XclImpChartObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1693 {
1694  // read OBJ record and the following chart substream
1695  ReadFrameData( rStrm );
1696  rStrm.Ignore( 18 );
1697  ReadMacro3( rStrm, nMacroSize );
1698  // set frame format from OBJ record, it is used if chart itself is transparent
1699  if( mxChart )
1700  mxChart->UpdateObjFrame( maLineData, maFillData );
1701 }
1702 
1703 void XclImpChartObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
1704 {
1705  // read OBJ record and the following chart substream
1706  ReadFrameData( rStrm );
1707  rStrm.Ignore( 18 );
1708  ReadMacro4( rStrm, nMacroSize );
1709  // set frame format from OBJ record, it is used if chart itself is transparent
1710  if( mxChart )
1711  mxChart->UpdateObjFrame( maLineData, maFillData );
1712 }
1713 
1714 void XclImpChartObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
1715 {
1716  // read OBJ record and the following chart substream
1717  ReadFrameData( rStrm );
1718  rStrm.Ignore( 18 );
1719  ReadName5( rStrm, nNameLen );
1720  ReadMacro5( rStrm, nMacroSize );
1721  ReadChartSubStream( rStrm );
1722  // set frame format from OBJ record, it is used if chart itself is transparent
1723  if( mxChart )
1724  mxChart->UpdateObjFrame( maLineData, maFillData );
1725 }
1726 
1727 void XclImpChartObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 /*nSubRecSize*/ )
1728 {
1729  // read the following chart substream
1730  if( nSubRecId == EXC_ID_OBJEND )
1731  {
1732  // enable CONTINUE handling for the entire chart substream
1733  rStrm.ResetRecord( true );
1734  ReadChartSubStream( rStrm );
1735  /* disable CONTINUE handling again to be able to read
1736  following CONTINUE records as MSODRAWING records. */
1737  rStrm.ResetRecord( false );
1738  }
1739 }
1740 
1742 {
1743  return mxChart ? mxChart->GetProgressSize() : 1;
1744 }
1745 
1747 {
1748  SdrObjectUniquePtr xSdrObj;
1749  SfxObjectShell* pDocShell = GetDocShell();
1750  if( rDffConv.SupportsOleObjects() && SvtModuleOptions().IsChart() && pDocShell && mxChart && !mxChart->IsPivotChart() )
1751  {
1752  // create embedded chart object
1753  OUString aEmbObjName;
1754  OUString sBaseURL(GetRoot().GetMedium().GetBaseURL());
1755  Reference< XEmbeddedObject > xEmbObj = pDocShell->GetEmbeddedObjectContainer().
1756  CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aEmbObjName, &sBaseURL );
1757 
1758  /* Set the size to the embedded object, this prevents that font sizes
1759  of text objects are changed in the chart when the object is
1760  inserted into the draw page. */
1761  sal_Int64 nAspect = css::embed::Aspects::MSOLE_CONTENT;
1762  MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xEmbObj->getMapUnit( nAspect ) );
1763  Size aSize( OutputDevice::LogicToLogic( rAnchorRect.GetSize(), MapMode( MapUnit::Map100thMM ), MapMode( aUnit ) ) );
1764  css::awt::Size aAwtSize( aSize.Width(), aSize.Height() );
1765  xEmbObj->setVisualAreaSize( nAspect, aAwtSize );
1766 
1767  // #i121334# This call will change the chart's default background fill from white to transparent.
1768  // Add here again if this is wanted (see task description for details)
1769  // ChartHelper::AdaptDefaultsForChart( xEmbObj );
1770 
1771  // create the container OLE object
1772  xSdrObj.reset(
1773  new SdrOle2Obj(
1774  *GetDoc().GetDrawLayer(),
1775  svt::EmbeddedObjectRef(xEmbObj, nAspect),
1776  aEmbObjName,
1777  rAnchorRect));
1778  }
1779 
1780  return xSdrObj;
1781 }
1782 
1784 {
1785  const SdrOle2Obj* pSdrOleObj = dynamic_cast< const SdrOle2Obj* >( &rSdrObj );
1786  if( !(mxChart && pSdrOleObj) )
1787  return;
1788 
1789  const Reference< XEmbeddedObject >& xEmbObj = pSdrOleObj->GetObjRef();
1790  if( xEmbObj.is() && ::svt::EmbeddedObjectRef::TryRunningState( xEmbObj ) ) try
1791  {
1792  Reference< XEmbedPersist > xPersist( xEmbObj, UNO_QUERY_THROW );
1793  Reference< XModel > xModel( xEmbObj->getComponent(), UNO_QUERY_THROW );
1794  mxChart->Convert( xModel, rDffConv, xPersist->getEntryName(), rSdrObj.GetLogicRect() );
1795  }
1796  catch( const Exception& )
1797  {
1798  }
1799 }
1800 
1802 {
1803  /* #i44077# Calculate and store DFF anchor for sheet charts.
1804  Needed to get used area if this chart is inserted as OLE object. */
1805  OSL_ENSURE( mbOwnTab, "XclImpChartObj::FinalizeTabChart - not allowed for embedded chart objects" );
1806 
1807  // set uninitialized page to landscape
1808  if( !GetPageSettings().GetPageData().mbValid )
1810 
1811  // calculate size of the chart object
1812  const XclPageData& rPageData = GetPageSettings().GetPageData();
1813  Size aPaperSize = rPageData.GetScPaperSize();
1814 
1815  tools::Long nWidth = XclTools::GetHmmFromTwips( aPaperSize.Width() );
1816  tools::Long nHeight = XclTools::GetHmmFromTwips( aPaperSize.Height() );
1817 
1818  // subtract page margins, give some more extra space
1819  nWidth -= (XclTools::GetHmmFromInch( rPageData.mfLeftMargin + rPageData.mfRightMargin ) + 2000);
1820  nHeight -= (XclTools::GetHmmFromInch( rPageData.mfTopMargin + rPageData.mfBottomMargin ) + 1000);
1821 
1822  // print column/row headers?
1823  if( rPageData.mbPrintHeadings )
1824  {
1825  nWidth -= 2000;
1826  nHeight -= 1000;
1827  }
1828 
1829  // create the object anchor
1830  XclObjAnchor aAnchor;
1831  aAnchor.SetRect( GetRoot(), GetCurrScTab(), tools::Rectangle( 1000, 500, nWidth, nHeight ), MapUnit::Map100thMM );
1832  SetAnchor( aAnchor );
1833 }
1834 
1836  XclImpTextObj( rRoot ),
1837  maScPos( ScAddress::INITIALIZE_INVALID ),
1838  mnNoteFlags( 0 )
1839 {
1840  SetSimpleMacro( false );
1841  // caption object will be created manually
1842  SetInsertSdrObj( false );
1843 }
1844 
1845 void XclImpNoteObj::SetNoteData( const ScAddress& rScPos, sal_uInt16 nNoteFlags )
1846 {
1847  maScPos = rScPos;
1848  mnNoteFlags = nNoteFlags;
1849 }
1850 
1852 {
1853  // create formatted text
1854  XclImpTextObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
1855  OutlinerParaObject* pOutlinerObj = rSdrObj.GetOutlinerParaObject();
1856  if( maScPos.IsValid() && pOutlinerObj )
1857  {
1858  // create cell note with all data from drawing object
1860  GetDoc(), maScPos,
1861  rSdrObj.GetMergedItemSet().Clone(), // new object on heap expected
1862  new OutlinerParaObject( *pOutlinerObj ), // new object on heap expected
1863  rSdrObj.GetLogicRect(),
1865  }
1866 }
1867 
1869  mrRoot( rRoot ),
1870  meBindMode( eBindMode )
1871 {
1872 }
1873 
1875 {
1876 }
1877 
1879  const Reference< XShape >& rxShape, const tools::Rectangle& rAnchorRect ) const
1880 {
1881  mxShape = rxShape;
1883  if( xSdrObj )
1884  {
1885  xSdrObj->NbcSetSnapRect( rAnchorRect );
1886  // #i30543# insert into control layer
1887  xSdrObj->NbcSetLayer( SC_LAYER_CONTROLS );
1888  }
1889  return xSdrObj;
1890 }
1891 
1893 {
1894 
1895  Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
1896  if( !xCtrlModel.is() )
1897  return;
1898 
1899  // sheet links
1900  SfxObjectShell* pDocShell = mrRoot.GetDocShell();
1901  if(!pDocShell)
1902  return;
1903 
1904  Reference< XMultiServiceFactory > xFactory( pDocShell->GetModel(), UNO_QUERY );
1905  if( !xFactory.is() )
1906  return;
1907 
1908  // cell link
1909  if( mxCellLink ) try
1910  {
1911  Reference< XBindableValue > xBindable( xCtrlModel, UNO_QUERY_THROW );
1912 
1913  // create argument sequence for createInstanceWithArguments()
1914  CellAddress aApiAddress;
1916 
1917  NamedValue aValue;
1918  aValue.Name = SC_UNONAME_BOUNDCELL;
1919  aValue.Value <<= aApiAddress;
1920 
1921  Sequence< Any > aArgs( 1 );
1922  aArgs[ 0 ] <<= aValue;
1923 
1924  // create the CellValueBinding instance and set at the control model
1925  OUString aServiceName;
1926  switch( meBindMode )
1927  {
1928  case EXC_CTRL_BINDCONTENT: aServiceName = SC_SERVICENAME_VALBIND; break;
1929  case EXC_CTRL_BINDPOSITION: aServiceName = SC_SERVICENAME_LISTCELLBIND; break;
1930  }
1931  Reference< XValueBinding > xBinding(
1932  xFactory->createInstanceWithArguments( aServiceName, aArgs ), UNO_QUERY_THROW );
1933  xBindable->setValueBinding( xBinding );
1934  }
1935  catch( const Exception& )
1936  {
1937  }
1938 
1939  // source range
1940  if( !mxSrcRange )
1941  return;
1942 
1943  try
1944  {
1945  Reference< XListEntrySink > xEntrySink( xCtrlModel, UNO_QUERY_THROW );
1946 
1947  // create argument sequence for createInstanceWithArguments()
1948  CellRangeAddress aApiRange;
1950 
1951  NamedValue aValue;
1952  aValue.Name = SC_UNONAME_CELLRANGE;
1953  aValue.Value <<= aApiRange;
1954 
1955  Sequence< Any > aArgs( 1 );
1956  aArgs[ 0 ] <<= aValue;
1957 
1958  // create the EntrySource instance and set at the control model
1959  Reference< XListEntrySource > xEntrySource( xFactory->createInstanceWithArguments(
1960  SC_SERVICENAME_LISTSOURCE, aArgs ), UNO_QUERY_THROW );
1961  xEntrySink->setListEntrySource( xEntrySource );
1962  }
1963  catch( const Exception& )
1964  {
1965  }
1966 }
1967 
1969 {
1970  Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( mxShape );
1971  if( !xCtrlModel.is() )
1972  return;
1973 
1975 
1976  ScfPropertySet aPropSet( xCtrlModel );
1977 
1978  // #i51348# set object name at control model
1979  aPropSet.SetStringProperty( "Name", rDrawObj.GetObjName() );
1980 
1981  // control visible and printable?
1982  aPropSet.SetBoolProperty( "EnableVisible", rDrawObj.IsVisible() );
1983  aPropSet.SetBoolProperty( "Printable", rDrawObj.IsPrintable() );
1984 
1985  // virtual call for type specific processing
1986  DoProcessControl( aPropSet );
1987 }
1988 
1989 void XclImpControlHelper::ReadCellLinkFormula( XclImpStream& rStrm, bool bWithBoundSize )
1990 {
1991  ScRangeList aScRanges;
1992  ReadRangeList( aScRanges, rStrm, bWithBoundSize );
1993  // Use first cell of first range
1994  if ( !aScRanges.empty() )
1995  {
1996  const ScRange & rScRange = aScRanges.front();
1997  mxCellLink = std::make_shared<ScAddress>( rScRange.aStart );
1998  }
1999 }
2000 
2002 {
2003  ScRangeList aScRanges;
2004  ReadRangeList( aScRanges, rStrm, bWithBoundSize );
2005  // Use first range
2006  if ( !aScRanges.empty() )
2007  {
2008  const ScRange & rScRange = aScRanges.front();
2009  mxSrcRange = std::make_shared<ScRange>( rScRange );
2010  }
2011 }
2012 
2014 {
2015 }
2016 
2018 {
2019  XclTokenArray aXclTokArr;
2020  aXclTokArr.ReadSize( rStrm );
2021  rStrm.Ignore( 4 );
2022  aXclTokArr.ReadArray( rStrm );
2023  mrRoot.GetFormulaCompiler().CreateRangeList( rScRanges, EXC_FMLATYPE_CONTROL, aXclTokArr, rStrm );
2024 }
2025 
2026 void XclImpControlHelper::ReadRangeList( ScRangeList& rScRanges, XclImpStream& rStrm, bool bWithBoundSize )
2027 {
2028  if( bWithBoundSize )
2029  {
2030  sal_uInt16 nSize;
2031  nSize = rStrm.ReaduInt16();
2032  if( nSize > 0 )
2033  {
2034  rStrm.PushPosition();
2035  ReadRangeList( rScRanges, rStrm );
2036  rStrm.PopPosition();
2037  rStrm.Ignore( nSize );
2038  }
2039  }
2040  else
2041  {
2042  ReadRangeList( rScRanges, rStrm );
2043  }
2044 }
2045 
2047  XclImpTextObj( rRoot ),
2049 {
2050  SetSimpleMacro( false );
2051  SetCustomDffObj( true );
2052 }
2053 
2054 namespace {
2055 
2056 void lclExtractColor( sal_uInt8& rnColorIdx, const DffPropSet& rDffPropSet, sal_uInt32 nPropId )
2057 {
2058  if( rDffPropSet.IsProperty( nPropId ) )
2059  {
2060  sal_uInt32 nColor = rDffPropSet.GetPropertyValue( nPropId, 0 );
2061  if( (nColor & 0xFF000000) == 0x08000000 )
2062  rnColorIdx = ::extract_value< sal_uInt8 >( nColor, 0, 8 );
2063  }
2064 }
2065 
2066 } // namespace
2067 
2069 {
2071  lclExtractColor( maFillData.mnBackColorIdx, rDffPropSet, DFF_Prop_fillBackColor );
2072  lclExtractColor( maFillData.mnPattColorIdx, rDffPropSet, DFF_Prop_fillColor );
2074 
2076  lclExtractColor( maLineData.mnColorIdx, rDffPropSet, DFF_Prop_lineColor );
2078 }
2079 
2080 bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const
2081 {
2083 }
2084 
2086 {
2087  if( maTextData.mxString )
2088  {
2089  const XclFormatRunVec& rFormatRuns = maTextData.mxString->GetFormats();
2090  if( rFormatRuns.empty() )
2092  else
2093  GetFontBuffer().WriteFontProperties( rPropSet, EXC_FONTPROPSET_CONTROL, rFormatRuns.front().mnFontIdx );
2094  }
2095 }
2096 
2098 {
2099  if( maTextData.mxString )
2100  {
2101  OUString aLabel = maTextData.mxString->GetText();
2102  if( maTextData.maData.mnShortcut > 0 )
2103  {
2104  sal_Int32 nPos = aLabel.indexOf( static_cast< sal_Unicode >( maTextData.maData.mnShortcut ) );
2105  if( nPos != -1 )
2106  aLabel = aLabel.replaceAt( nPos, 0, "~" );
2107  }
2108  rPropSet.SetStringProperty( "Label", aLabel );
2109 
2110  //Excel Alt text <==> Aoo description
2111  //For TBX control, if user does not operate alt text, alt text will be set label text as default value in Excel.
2112  //In this case, DFF_Prop_wzDescription will not be set in excel file.
2113  //So In the end of SvxMSDffManager::ImportShape, description will not be set. But actually in excel,
2114  //the alt text is the label value. So here set description as label text first which is called before ImportShape.
2115  Reference< css::beans::XPropertySet > xPropset( mxShape, UNO_QUERY );
2116  try{
2117  if(xPropset.is())
2118  xPropset->setPropertyValue( "Description", makeAny(aLabel) );
2119  }catch( ... )
2120  {
2121  SAL_WARN("sc.filter", "Can't set a default text for TBX Control ");
2122  }
2123  }
2124  ConvertFont( rPropSet );
2125 }
2126 
2128 {
2129  SdrObjectUniquePtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
2130  rDffConv.Progress();
2131  return xSdrObj;
2132 }
2133 
2134 void XclImpTbxObjBase::DoPreProcessSdrObj( XclImpDffConverter& /*rDffConv*/, SdrObject& /*rSdrObj*/ ) const
2135 {
2136  // do not call DoPreProcessSdrObj() from base class (to skip text processing)
2137  ProcessControl( *this );
2138 }
2139 
2141  XclImpTbxObjBase( rRoot )
2142 {
2143 }
2144 
2146 {
2147  // label and text formatting
2148  ConvertLabel( rPropSet );
2149 
2150  /* Horizontal text alignment. For unknown reason, the property type is a
2151  simple sal_Int16 and not a com.sun.star.style.HorizontalAlignment. */
2152  sal_Int16 nHorAlign = 1;
2153  switch( maTextData.maData.GetHorAlign() )
2154  {
2155  case EXC_OBJ_HOR_LEFT: nHorAlign = 0; break;
2156  case EXC_OBJ_HOR_CENTER: nHorAlign = 1; break;
2157  case EXC_OBJ_HOR_RIGHT: nHorAlign = 2; break;
2158  }
2159  rPropSet.SetProperty( "Align", nHorAlign );
2160 
2161  // vertical text alignment
2162  namespace csss = ::com::sun::star::style;
2163  csss::VerticalAlignment eVerAlign = csss::VerticalAlignment_MIDDLE;
2164  switch( maTextData.maData.GetVerAlign() )
2165  {
2166  case EXC_OBJ_VER_TOP: eVerAlign = csss::VerticalAlignment_TOP; break;
2167  case EXC_OBJ_VER_CENTER: eVerAlign = csss::VerticalAlignment_MIDDLE; break;
2168  case EXC_OBJ_VER_BOTTOM: eVerAlign = csss::VerticalAlignment_BOTTOM; break;
2169  }
2170  rPropSet.SetProperty( "VerticalAlign", eVerAlign );
2171 
2172  // always wrap text automatically
2173  rPropSet.SetBoolProperty( "MultiLine", true );
2174 
2175  // default button
2177  rPropSet.SetBoolProperty( "DefaultButton", bDefButton );
2178 
2179  // button type (flags cannot be combined in OOo)
2180  namespace cssa = ::com::sun::star::awt;
2181  cssa::PushButtonType eButtonType = cssa::PushButtonType_STANDARD;
2183  eButtonType = cssa::PushButtonType_OK;
2185  eButtonType = cssa::PushButtonType_CANCEL;
2187  eButtonType = cssa::PushButtonType_HELP;
2188  // property type is short, not enum
2189  rPropSet.SetProperty( "PushButtonType", sal_Int16( eButtonType ) );
2190 }
2191 
2193 {
2194  return "com.sun.star.form.component.CommandButton";
2195 }
2196 
2198 {
2199  return EXC_TBX_EVENT_ACTION;
2200 }
2201 
2203  XclImpTbxObjBase( rRoot ),
2204  mnState( EXC_OBJ_CHECKBOX_UNCHECKED ),
2205  mnCheckBoxFlags( 0 )
2206 {
2207 }
2208 
2209 void XclImpCheckBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2210 {
2211  ReadFrameData( rStrm );
2212  rStrm.Ignore( 10 );
2213  maTextData.maData.mnFlags = rStrm.ReaduInt16();
2214  rStrm.Ignore( 20 );
2215  ReadName5( rStrm, nNameLen );
2216  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2217  ReadCellLinkFormula( rStrm, true );
2219  maTextData.ReadByteString( rStrm );
2220  mnState = rStrm.ReaduInt16();
2223  mnCheckBoxFlags = rStrm.ReaduInt16();
2224 }
2225 
2226 void XclImpCheckBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2227 {
2228  switch( nSubRecId )
2229  {
2230  case EXC_ID_OBJCBLS:
2231  // do not read EXC_ID_OBJCBLSDATA, not written by OOo Excel export
2232  mnState = rStrm.ReaduInt16();
2233  rStrm.Ignore( 4 );
2236  mnCheckBoxFlags = rStrm.ReaduInt16();
2237  break;
2238  case EXC_ID_OBJCBLSFMLA:
2239  ReadCellLinkFormula( rStrm, false );
2240  break;
2241  default:
2242  XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2243  }
2244 }
2245 
2247 {
2248  // label and text formatting
2249  ConvertLabel( rPropSet );
2250 
2251  // state
2252  bool bSupportsTristate = GetObjType() == EXC_OBJTYPE_CHECKBOX;
2253  sal_Int16 nApiState = 0;
2254  switch( mnState )
2255  {
2256  case EXC_OBJ_CHECKBOX_UNCHECKED: nApiState = 0; break;
2257  case EXC_OBJ_CHECKBOX_CHECKED: nApiState = 1; break;
2258  case EXC_OBJ_CHECKBOX_TRISTATE: nApiState = bSupportsTristate ? 2 : 1; break;
2259  }
2260  if( bSupportsTristate )
2261  rPropSet.SetBoolProperty( "TriState", nApiState == 2 );
2262  rPropSet.SetProperty( "DefaultState", nApiState );
2263 
2264  // box style
2265  namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2266  sal_Int16 nEffect = ::get_flagvalue( mnCheckBoxFlags, EXC_OBJ_CHECKBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2267  rPropSet.SetProperty( "VisualEffect", nEffect );
2268 
2269  // do not wrap text automatically
2270  rPropSet.SetBoolProperty( "MultiLine", false );
2271 
2272  // #i40279# always centered vertically
2273  namespace csss = ::com::sun::star::style;
2274  rPropSet.SetProperty( "VerticalAlign", csss::VerticalAlignment_MIDDLE );
2275 
2276  // background color
2277  if( maFillData.IsFilled() )
2278  {
2279  sal_Int32 nColor = static_cast< sal_Int32 >( GetSolidFillColor( maFillData ) );
2280  rPropSet.SetProperty( "BackgroundColor", nColor );
2281  }
2282 }
2283 
2285 {
2286  return "com.sun.star.form.component.CheckBox";
2287 }
2288 
2290 {
2291  return EXC_TBX_EVENT_ACTION;
2292 }
2293 
2295  XclImpCheckBoxObj( rRoot ),
2296  mnNextInGroup( 0 ),
2297  mnFirstInGroup( 1 )
2298 {
2299 }
2300 
2301 void XclImpOptionButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2302 {
2303  ReadFrameData( rStrm );
2304  rStrm.Ignore( 10 );
2305  maTextData.maData.mnFlags = rStrm.ReaduInt16();
2306  rStrm.Ignore( 32 );
2307  ReadName5( rStrm, nNameLen );
2308  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2309  ReadCellLinkFormula( rStrm, true );
2311  maTextData.ReadByteString( rStrm );
2312  mnState = rStrm.ReaduInt16();
2315  mnCheckBoxFlags = rStrm.ReaduInt16();
2316  mnNextInGroup = rStrm.ReaduInt16();
2317  mnFirstInGroup = rStrm.ReaduInt16();
2318 }
2319 
2320 void XclImpOptionButtonObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2321 {
2322  switch( nSubRecId )
2323  {
2324  case EXC_ID_OBJRBODATA:
2325  mnNextInGroup = rStrm.ReaduInt16();
2326  mnFirstInGroup = rStrm.ReaduInt16();
2327  break;
2328  default:
2329  XclImpCheckBoxObj::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2330  }
2331 }
2332 
2334 {
2336  // TODO: grouping
2338  if ( pTbxObj && pTbxObj->mnFirstInGroup )
2339  {
2340  // Group has terminated
2341  // traverse each RadioButton in group and
2342  // a) apply the groupname
2343  // b) propagate the linked cell from the lead radiobutton
2344  // c) apply the correct Ref value
2345  XclImpOptionButtonObj* pLeader = pTbxObj;
2346 
2347  sal_Int32 nRefVal = 1;
2348  do
2349  {
2350 
2351  Reference< XControlModel > xCtrlModel = XclControlHelper::GetControlModel( pTbxObj->mxShape );
2352  if ( xCtrlModel.is() )
2353  {
2354  ScfPropertySet aProps( xCtrlModel );
2355  OUString sGroupName = OUString::number( pLeader->GetDffShapeId() );
2356 
2357  aProps.SetStringProperty( "GroupName", sGroupName );
2358  aProps.SetStringProperty( "RefValue", OUString::number( nRefVal++ ) );
2359  if ( pLeader->HasCellLink() && !pTbxObj->HasCellLink() )
2360  {
2361  // propagate cell link info
2362  pTbxObj->mxCellLink = std::make_shared<ScAddress>( *pLeader->mxCellLink );
2363  pTbxObj->ApplySheetLinkProps();
2364  }
2365  pTbxObj = dynamic_cast< XclImpOptionButtonObj* >( GetObjectManager().GetSheetDrawing( GetTab() ).FindDrawObj( pTbxObj->mnNextInGroup ).get() );
2366  }
2367  else
2368  pTbxObj = nullptr;
2369  } while ( pTbxObj && ( pTbxObj->mnFirstInGroup != 1 ) );
2370  }
2371  else
2372  {
2373  // not the leader? try and find it
2374  }
2375 }
2376 
2378 {
2379  return "com.sun.star.form.component.RadioButton";
2380 }
2381 
2383 {
2384  return EXC_TBX_EVENT_ACTION;
2385 }
2386 
2388  XclImpTbxObjBase( rRoot )
2389 {
2390 }
2391 
2393 {
2394  // label and text formatting
2395  ConvertLabel( rPropSet );
2396 
2397  // text alignment (always top/left aligned)
2398  rPropSet.SetProperty( "Align", sal_Int16( 0 ) );
2399  namespace csss = ::com::sun::star::style;
2400  rPropSet.SetProperty( "VerticalAlign", csss::VerticalAlignment_TOP );
2401 
2402  // always wrap text automatically
2403  rPropSet.SetBoolProperty( "MultiLine", true );
2404 }
2405 
2407 {
2408  return "com.sun.star.form.component.FixedText";
2409 }
2410 
2412 {
2413  return EXC_TBX_EVENT_MOUSE;
2414 }
2415 
2417  XclImpTbxObjBase( rRoot ),
2418  mnGroupBoxFlags( 0 )
2419 {
2420 }
2421 
2422 void XclImpGroupBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2423 {
2424  ReadFrameData( rStrm );
2425  rStrm.Ignore( 10 );
2426  maTextData.maData.mnFlags = rStrm.ReaduInt16();
2427  rStrm.Ignore( 26 );
2428  ReadName5( rStrm, nNameLen );
2429  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2431  maTextData.ReadByteString( rStrm );
2434  mnGroupBoxFlags = rStrm.ReaduInt16();
2435 }
2436 
2437 void XclImpGroupBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2438 {
2439  switch( nSubRecId )
2440  {
2441  case EXC_ID_OBJGBODATA:
2444  mnGroupBoxFlags = rStrm.ReaduInt16();
2445  break;
2446  default:
2447  XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2448  }
2449 }
2450 
2452 {
2453  // label and text formatting
2454  ConvertLabel( rPropSet );
2455 }
2456 
2458 {
2459  return "com.sun.star.form.component.GroupBox";
2460 }
2461 
2463 {
2464  return EXC_TBX_EVENT_MOUSE;
2465 }
2466 
2468  XclImpTbxObjBase( rRoot )
2469 {
2470 }
2471 
2473 {
2474  // label and text formatting
2475  ConvertLabel( rPropSet );
2476 }
2477 
2479 {
2480  // dialog frame faked by a groupbox
2481  return "com.sun.star.form.component.GroupBox";
2482 }
2483 
2485 {
2486  return EXC_TBX_EVENT_MOUSE;
2487 }
2488 
2490  XclImpTbxObjBase( rRoot ),
2491  mnContentType( EXC_OBJ_EDIT_TEXT ),
2492  mnMultiLine( 0 ),
2493  mnScrollBar( 0 ),
2494  mnListBoxObjId( 0 )
2495 {
2496 }
2497 
2499 {
2501 }
2502 
2503 void XclImpEditObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2504 {
2505  ReadFrameData( rStrm );
2506  rStrm.Ignore( 10 );
2507  maTextData.maData.mnFlags = rStrm.ReaduInt16();
2508  rStrm.Ignore( 14 );
2509  ReadName5( rStrm, nNameLen );
2510  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2512  maTextData.ReadByteString( rStrm );
2513  mnContentType = rStrm.ReaduInt16();
2514  mnMultiLine = rStrm.ReaduInt16();
2515  mnScrollBar = rStrm.ReaduInt16();
2516  mnListBoxObjId = rStrm.ReaduInt16();
2517 }
2518 
2519 void XclImpEditObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2520 {
2521  switch( nSubRecId )
2522  {
2523  case EXC_ID_OBJEDODATA:
2524  mnContentType = rStrm.ReaduInt16();
2525  mnMultiLine = rStrm.ReaduInt16();
2526  mnScrollBar = rStrm.ReaduInt16();
2527  mnListBoxObjId = rStrm.ReaduInt16();
2528  break;
2529  default:
2530  XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2531  }
2532 }
2533 
2535 {
2536  if( maTextData.mxString )
2537  {
2538  OUString aText = maTextData.mxString->GetText();
2539  if( IsNumeric() )
2540  {
2541  // TODO: OUString::toDouble() does not handle local decimal separator
2542  rPropSet.SetProperty( "DefaultValue", aText.toDouble() );
2543  rPropSet.SetBoolProperty( "Spin", mnScrollBar != 0 );
2544  }
2545  else
2546  {
2547  rPropSet.SetProperty( "DefaultText", aText );
2548  rPropSet.SetBoolProperty( "MultiLine", mnMultiLine != 0 );
2549  rPropSet.SetBoolProperty( "VScroll", mnScrollBar != 0 );
2550  }
2551  }
2552  ConvertFont( rPropSet );
2553 }
2554 
2556 {
2557  return IsNumeric() ?
2558  OUString( "com.sun.star.form.component.NumericField" ) :
2559  OUString( "com.sun.star.form.component.TextField" );
2560 }
2561 
2563 {
2564  return EXC_TBX_EVENT_TEXT;
2565 }
2566 
2568  XclImpTbxObjBase( rRoot ),
2569  mnValue( 0 ),
2570  mnMin( 0 ),
2571  mnMax( 100 ),
2572  mnStep( 1 ),
2573  mnPageStep( 10 ),
2574  mnOrient( 0 ),
2575  mnThumbWidth( 1 ),
2576  mnScrollFlags( 0 )
2577 {
2578 }
2579 
2581 {
2582  rStrm.Ignore( 4 );
2583  mnValue = rStrm.ReaduInt16();
2584  mnMin = rStrm.ReaduInt16();
2585  mnMax = rStrm.ReaduInt16();
2586  mnStep = rStrm.ReaduInt16();
2587  mnPageStep = rStrm.ReaduInt16();
2588  mnOrient = rStrm.ReaduInt16();
2589  mnThumbWidth = rStrm.ReaduInt16();
2590  mnScrollFlags = rStrm.ReaduInt16();
2591 }
2592 
2593 void XclImpTbxObjScrollableBase::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2594 {
2595  switch( nSubRecId )
2596  {
2597  case EXC_ID_OBJSBS:
2598  ReadSbs( rStrm );
2599  break;
2600  case EXC_ID_OBJSBSFMLA:
2601  ReadCellLinkFormula( rStrm, false );
2602  break;
2603  default:
2604  XclImpTbxObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2605  }
2606 }
2607 
2610 {
2611 }
2612 
2613 void XclImpSpinButtonObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2614 {
2615  ReadFrameData( rStrm );
2616  ReadSbs( rStrm );
2617  ReadName5( rStrm, nNameLen );
2618  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2619  ReadCellLinkFormula( rStrm, true );
2620 }
2621 
2623 {
2624  // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2625  rPropSet.SetProperty( "Border", css::awt::VisualEffect::NONE );
2626  rPropSet.SetProperty< sal_Int32 >( "DefaultSpinValue", mnValue );
2627  rPropSet.SetProperty< sal_Int32 >( "SpinValueMin", mnMin );
2628  rPropSet.SetProperty< sal_Int32 >( "SpinValueMax", mnMax );
2629  rPropSet.SetProperty< sal_Int32 >( "SpinIncrement", mnStep );
2630 
2631  // Excel spin buttons always vertical
2632  rPropSet.SetProperty( "Orientation", css::awt::ScrollBarOrientation::VERTICAL );
2633 }
2634 
2636 {
2637  return "com.sun.star.form.component.SpinButton";
2638 }
2639 
2641 {
2642  return EXC_TBX_EVENT_VALUE;
2643 }
2644 
2647 {
2648 }
2649 
2650 void XclImpScrollBarObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2651 {
2652  ReadFrameData( rStrm );
2653  ReadSbs( rStrm );
2654  ReadName5( rStrm, nNameLen );
2655  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2656  ReadCellLinkFormula( rStrm, true );
2657 }
2658 
2660 {
2661  // Calc's "Border" property is not the 3D/flat style effect in Excel (#i34712#)
2662  rPropSet.SetProperty( "Border", css::awt::VisualEffect::NONE );
2663  rPropSet.SetProperty< sal_Int32 >( "DefaultScrollValue", mnValue );
2664  rPropSet.SetProperty< sal_Int32 >( "ScrollValueMin", mnMin );
2665  rPropSet.SetProperty< sal_Int32 >( "ScrollValueMax", mnMax );
2666  rPropSet.SetProperty< sal_Int32 >( "LineIncrement", mnStep );
2667  rPropSet.SetProperty< sal_Int32 >( "BlockIncrement", mnPageStep );
2668  rPropSet.SetProperty( "VisibleSize", ::std::min< sal_Int32 >( mnPageStep, 1 ) );
2669 
2670  namespace AwtScrollOrient = ::com::sun::star::awt::ScrollBarOrientation;
2671  sal_Int32 nApiOrient = ::get_flagvalue( mnOrient, EXC_OBJ_SCROLLBAR_HOR, AwtScrollOrient::HORIZONTAL, AwtScrollOrient::VERTICAL );
2672  rPropSet.SetProperty( "Orientation", nApiOrient );
2673 }
2674 
2676 {
2677  return "com.sun.star.form.component.ScrollBar";
2678 }
2679 
2681 {
2682  return EXC_TBX_EVENT_VALUE;
2683 }
2684 
2686  XclImpTbxObjScrollableBase( rRoot ),
2687  mnEntryCount( 0 ),
2688  mnSelEntry( 0 ),
2689  mnListFlags( 0 ),
2690  mnEditObjId( 0 ),
2691  mbHasDefFontIdx( false )
2692 {
2693 }
2694 
2696 {
2697  ReadSourceRangeFormula( rStrm, true );
2698  mnEntryCount = rStrm.ReaduInt16();
2699  mnSelEntry = rStrm.ReaduInt16();
2700  mnListFlags = rStrm.ReaduInt16();
2701  mnEditObjId = rStrm.ReaduInt16();
2702 }
2703 
2705 {
2706  // border style
2707  namespace AwtVisualEffect = ::com::sun::star::awt::VisualEffect;
2708  sal_Int16 nApiBorder = ::get_flagvalue( mnListFlags, EXC_OBJ_LISTBOX_FLAT, AwtVisualEffect::FLAT, AwtVisualEffect::LOOK3D );
2709  rPropSet.SetProperty( "Border", nApiBorder );
2710 
2711  // font formatting
2712  if( mbHasDefFontIdx )
2714  else
2716 }
2717 
2719  XclImpTbxObjListBase( rRoot )
2720 {
2721 }
2722 
2723 void XclImpListBoxObj::ReadFullLbsData( XclImpStream& rStrm, std::size_t nRecLeft )
2724 {
2725  std::size_t nRecEnd = rStrm.GetRecPos() + nRecLeft;
2726  ReadLbsData( rStrm );
2727  OSL_ENSURE( (rStrm.GetRecPos() == nRecEnd) || (rStrm.GetRecPos() + mnEntryCount == nRecEnd),
2728  "XclImpListBoxObj::ReadFullLbsData - invalid size of OBJLBSDATA record" );
2729  while (rStrm.IsValid())
2730  {
2731  if (rStrm.GetRecPos() >= nRecEnd)
2732  break;
2733  maSelection.push_back( rStrm.ReaduInt8() );
2734  }
2735 }
2736 
2737 void XclImpListBoxObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2738 {
2739  ReadFrameData( rStrm );
2740  ReadSbs( rStrm );
2741  rStrm.Ignore( 18 );
2743  rStrm.Ignore( 4 );
2744  ReadName5( rStrm, nNameLen );
2745  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2746  ReadCellLinkFormula( rStrm, true );
2747  ReadFullLbsData( rStrm, rStrm.GetRecLeft() );
2748  mbHasDefFontIdx = true;
2749 }
2750 
2751 void XclImpListBoxObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2752 {
2753  switch( nSubRecId )
2754  {
2755  case EXC_ID_OBJLBSDATA:
2756  ReadFullLbsData( rStrm, nSubRecSize );
2757  break;
2758  default:
2759  XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2760  }
2761 }
2762 
2764 {
2765  // listbox formatting
2766  SetBoxFormatting( rPropSet );
2767 
2768  // selection type
2769  sal_uInt8 nSelType = ::extract_value< sal_uInt8 >( mnListFlags, 4, 2 );
2770  bool bMultiSel = nSelType != EXC_OBJ_LISTBOX_SINGLE;
2771  rPropSet.SetBoolProperty( "MultiSelection", bMultiSel );
2772 
2773  // selection (do not set, if listbox is linked to a cell)
2774  if( HasCellLink() )
2775  return;
2776 
2777  ScfInt16Vec aSelVec;
2778 
2779  // multi selection: API expects sequence of list entry indexes
2780  if( bMultiSel )
2781  {
2782  sal_Int16 nIndex = 0;
2783  for( const auto& rItem : maSelection )
2784  {
2785  if( rItem != 0 )
2786  aSelVec.push_back( nIndex );
2787  ++nIndex;
2788  }
2789  }
2790  // single selection: mnSelEntry is one-based, API expects zero-based
2791  else if( mnSelEntry > 0 )
2792  aSelVec.push_back( static_cast< sal_Int16 >( mnSelEntry - 1 ) );
2793 
2794  if( !aSelVec.empty() )
2795  {
2796  Sequence<sal_Int16> aSelSeq(aSelVec.data(), static_cast<sal_Int32>(aSelVec.size()));
2797  rPropSet.SetProperty( "DefaultSelection", aSelSeq );
2798  }
2799 }
2800 
2802 {
2803  return "com.sun.star.form.component.ListBox";
2804 }
2805 
2807 {
2808  return EXC_TBX_EVENT_CHANGE;
2809 }
2810 
2812  XclImpTbxObjListBase( rRoot ),
2813  mnLeft( 0 ),
2814  mnTop( 0 ),
2815  mnRight( 0 ),
2816  mnBottom( 0 ),
2817  mnDropDownFlags( 0 ),
2818  mnLineCount( 0 ),
2819  mnMinWidth( 0 )
2820 {
2821 }
2822 
2824 {
2825  return ::extract_value< sal_uInt8 >( mnDropDownFlags, 0, 2 );
2826 }
2827 
2829 {
2830  ReadLbsData( rStrm );
2831  mnDropDownFlags = rStrm.ReaduInt16();
2832  mnLineCount = rStrm.ReaduInt16();
2833  mnMinWidth = rStrm.ReaduInt16();
2835  maTextData.ReadByteString( rStrm );
2836  // dropdowns of auto-filters have 'simple' style, they don't have a text area
2838  SetProcessSdrObj( false );
2839 }
2840 
2841 void XclImpDropDownObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 /*nMacroSize*/ )
2842 {
2843  ReadFrameData( rStrm );
2844  ReadSbs( rStrm );
2845  rStrm.Ignore( 18 );
2847  rStrm.Ignore( 14 );
2848  mnLeft = rStrm.ReaduInt16();
2849  mnTop = rStrm.ReaduInt16();
2850  mnRight = rStrm.ReaduInt16();
2851  mnBottom = rStrm.ReaduInt16();
2852  rStrm.Ignore( 4 );
2853  ReadName5( rStrm, nNameLen );
2854  ReadMacro5( rStrm, rStrm.ReaduInt16() ); // first macro size invalid and unused
2855  ReadCellLinkFormula( rStrm, true );
2856  ReadFullLbsData( rStrm );
2857  mbHasDefFontIdx = true;
2858 }
2859 
2860 void XclImpDropDownObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2861 {
2862  switch( nSubRecId )
2863  {
2864  case EXC_ID_OBJLBSDATA:
2865  ReadFullLbsData( rStrm );
2866  break;
2867  default:
2868  XclImpTbxObjListBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
2869  }
2870 }
2871 
2873 {
2874  // dropdown listbox formatting
2875  SetBoxFormatting( rPropSet );
2876  // enable dropdown button
2877  rPropSet.SetBoolProperty( "Dropdown", true );
2878  // dropdown line count
2879  rPropSet.SetProperty( "LineCount", mnLineCount );
2880 
2882  {
2883  // text of editable combobox
2884  if( maTextData.mxString )
2885  rPropSet.SetStringProperty( "DefaultText", maTextData.mxString->GetText() );
2886  }
2887  else
2888  {
2889  // selection (do not set, if dropdown is linked to a cell)
2890  if( !HasCellLink() && (mnSelEntry > 0) )
2891  {
2892  Sequence< sal_Int16 > aSelSeq( 1 );
2893  aSelSeq[ 0 ] = mnSelEntry - 1;
2894  rPropSet.SetProperty( "DefaultSelection", aSelSeq );
2895  }
2896  }
2897 }
2898 
2900 {
2902  OUString( "com.sun.star.form.component.ComboBox" ) :
2903  OUString( "com.sun.star.form.component.ListBox" );
2904 }
2905 
2907 {
2909 }
2910 
2912  XclImpRectObj( rRoot ),
2914  mnStorageId( 0 ),
2915  mnCtlsStrmPos( 0 ),
2916  mnCtlsStrmSize( 0 ),
2917  mbEmbedded( false ),
2918  mbLinked( false ),
2919  mbSymbol( false ),
2920  mbControl( false ),
2921  mbUseCtlsStrm( false )
2922 {
2923  SetAreaObj( true );
2924  SetSimpleMacro( true );
2925  SetCustomDffObj( true );
2926 }
2927 
2929 {
2930  OUStringBuffer aStrgName;
2931  if( (mbEmbedded || mbLinked) && !mbControl && (mnStorageId > 0) )
2932  {
2933  aStrgName = mbEmbedded ? OUStringLiteral(u"" EXC_STORAGE_OLE_EMBEDDED) : OUStringLiteral(u"" EXC_STORAGE_OLE_LINKED);
2934  static const char spcHexChars[] = "0123456789ABCDEF";
2935  for( sal_uInt8 nIndex = 32; nIndex > 0; nIndex -= 4 )
2936  aStrgName.append(OUStringChar( spcHexChars[ ::extract_value< sal_uInt8 >( mnStorageId, nIndex - 4, 4 ) ] ));
2937  }
2938  return aStrgName.makeStringAndClear();
2939 }
2940 
2941 void XclImpPictureObj::DoReadObj3( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2942 {
2943  sal_uInt16 nLinkSize;
2944  ReadFrameData( rStrm );
2945  rStrm.Ignore( 6 );
2946  nLinkSize = rStrm.ReaduInt16();
2947  rStrm.Ignore( 2 );
2948  ReadFlags3( rStrm );
2949  ReadMacro3( rStrm, nMacroSize );
2950  ReadPictFmla( rStrm, nLinkSize );
2951 
2952  if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2954 }
2955 
2956 void XclImpPictureObj::DoReadObj4( XclImpStream& rStrm, sal_uInt16 nMacroSize )
2957 {
2958  sal_uInt16 nLinkSize;
2959  ReadFrameData( rStrm );
2960  rStrm.Ignore( 6 );
2961  nLinkSize = rStrm.ReaduInt16();
2962  rStrm.Ignore( 2 );
2963  ReadFlags3( rStrm );
2964  ReadMacro4( rStrm, nMacroSize );
2965  ReadPictFmla( rStrm, nLinkSize );
2966 
2967  if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2969 }
2970 
2971 void XclImpPictureObj::DoReadObj5( XclImpStream& rStrm, sal_uInt16 nNameLen, sal_uInt16 nMacroSize )
2972 {
2973  sal_uInt16 nLinkSize;
2974  ReadFrameData( rStrm );
2975  rStrm.Ignore( 6 );
2976  nLinkSize = rStrm.ReaduInt16();
2977  rStrm.Ignore( 2 );
2978  ReadFlags3( rStrm );
2979  rStrm.Ignore( 4 );
2980  ReadName5( rStrm, nNameLen );
2981  ReadMacro5( rStrm, nMacroSize );
2982  ReadPictFmla( rStrm, nLinkSize );
2983 
2984  if( (rStrm.GetNextRecId() == EXC_ID3_IMGDATA) && rStrm.StartNextRecord() )
2985  {
2986  // page background is stored as hidden picture with name "__BkgndObj"
2987  if ( IsHidden() && (GetObjName() == "__BkgndObj") )
2988  GetPageSettings().ReadImgData( rStrm );
2989  else
2991  }
2992 }
2993 
2994 void XclImpPictureObj::DoReadObj8SubRec( XclImpStream& rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize )
2995 {
2996  switch( nSubRecId )
2997  {
2998  case EXC_ID_OBJFLAGS:
2999  ReadFlags8( rStrm );
3000  break;
3001  case EXC_ID_OBJPICTFMLA:
3002  ReadPictFmla( rStrm, rStrm.ReaduInt16() );
3003  break;
3004  default:
3005  XclImpDrawObjBase::DoReadObj8SubRec( rStrm, nSubRecId, nSubRecSize );
3006  }
3007 }
3008 
3010 {
3011  // try to create an OLE object or form control
3012  SdrObjectUniquePtr xSdrObj( rDffConv.CreateSdrObject( *this, rAnchorRect ) );
3013 
3014  // insert a graphic replacement for unsupported ole object ( if none already
3015  // exists ) Hmm ok, it's possibly that there has been some imported
3016  // graphic at a base level but unlikely, normally controls have a valid
3017  // preview in the IMGDATA record ( see below )
3018  // It might be possible to push such an imported graphic up to this
3019  // XclImpPictureObj instance but there are so many layers of indirection I
3020  // don't see an easy way. This way at least ensures that we can
3021  // avoid a 'blank' shape that can result from a failed control import
3022  if ( !xSdrObj && IsOcxControl() && maGraphic.GetType() == GraphicType::NONE )
3023  {
3024  const_cast< XclImpPictureObj* >( this )->maGraphic =
3026  }
3027  // no OLE - create a plain picture from IMGDATA record data
3028  if( !xSdrObj && (maGraphic.GetType() != GraphicType::NONE) )
3029  {
3030  xSdrObj.reset(
3031  new SdrGrafObj(
3032  *GetDoc().GetDrawLayer(),
3033  maGraphic,
3034  rAnchorRect));
3035  ConvertRectStyle( *xSdrObj );
3036  }
3037 
3038  rDffConv.Progress();
3039  return xSdrObj;
3040 }
3041 
3043 {
3044  if( IsOcxControl() )
3045  {
3046  OUString sName( GetObjectManager().GetOleNameOverride( GetTab(), GetObjId() ) );
3047  if (!sName.isEmpty())
3048  return sName;
3049  }
3051 }
3052 
3054 {
3055  if( IsOcxControl() )
3056  {
3057  // do not call XclImpRectObj::DoPreProcessSdrObj(), it would trace missing "printable" feature
3058  ProcessControl( *this );
3059  }
3060  else if( mbEmbedded || mbLinked )
3061  {
3062  // trace missing "printable" feature
3063  XclImpRectObj::DoPreProcessSdrObj( rDffConv, rSdrObj );
3064 
3065  SfxObjectShell* pDocShell = GetDocShell();
3066  SdrOle2Obj* pOleSdrObj = dynamic_cast< SdrOle2Obj* >( &rSdrObj );
3067  if( pOleSdrObj && pDocShell )
3068  {
3070  Reference< XEmbeddedObject > xEmbObj = pOleSdrObj->GetObjRef();
3071  OUString aOldName( pOleSdrObj->GetPersistName() );
3072 
3073  /* The object persistence should be already in the storage, but
3074  the object still might not be inserted into the container. */
3075  if( rEmbObjCont.HasEmbeddedObject( aOldName ) )
3076  {
3077  if( !rEmbObjCont.HasEmbeddedObject( xEmbObj ) )
3078  // filter code is allowed to call the following method
3079  rEmbObjCont.AddEmbeddedObject( xEmbObj, aOldName );
3080  }
3081  else
3082  {
3083  /* If the object is still not in container it must be inserted
3084  there, the name must be generated in this case. */
3085  OUString aNewName;
3086  rEmbObjCont.InsertEmbeddedObject( xEmbObj, aNewName );
3087  if( aOldName != aNewName )
3088  // SetPersistName, not SetName
3089  pOleSdrObj->SetPersistName( aNewName );
3090  }
3091  }
3092  }
3093 }
3094 
3096 {
3097  sal_uInt16 nFlags;
3098  nFlags = rStrm.ReaduInt16();
3099  mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
3100 }
3101 
3103 {
3104  sal_uInt16 nFlags;
3105  nFlags = rStrm.ReaduInt16();
3106  mbSymbol = ::get_flag( nFlags, EXC_OBJ_PIC_SYMBOL );
3109  OSL_ENSURE( mbControl || !mbUseCtlsStrm, "XclImpPictureObj::ReadFlags8 - CTLS stream for controls only" );
3111 }
3112 
3113 void XclImpPictureObj::ReadPictFmla( XclImpStream& rStrm, sal_uInt16 nLinkSize )
3114 {
3115  std::size_t nLinkEnd = rStrm.GetRecPos() + nLinkSize;
3116  if( nLinkSize >= 6 )
3117  {
3118  sal_uInt16 nFmlaSize;
3119  nFmlaSize = rStrm.ReaduInt16();
3120  OSL_ENSURE( nFmlaSize > 0, "XclImpPictureObj::ReadPictFmla - missing link formula" );
3121  // BIFF3/BIFF4 do not support storages, nothing to do here
3122  if( (nFmlaSize > 0) && (GetBiff() >= EXC_BIFF5) )
3123  {
3124  rStrm.Ignore( 4 );
3125  sal_uInt8 nToken;
3126  nToken = rStrm.ReaduInt8();
3127 
3128  // different processing for linked vs. embedded OLE objects
3130  {
3131  mbLinked = true;
3132  switch( GetBiff() )
3133  {
3134  case EXC_BIFF5:
3135  {
3136  sal_Int16 nRefIdx;
3137  sal_uInt16 nNameIdx;
3138  nRefIdx = rStrm.ReadInt16();
3139  rStrm.Ignore( 8 );
3140  nNameIdx = rStrm.ReaduInt16();
3141  rStrm.Ignore( 12 );
3142  const ExtName* pExtName = GetOldRoot().pExtNameBuff->GetNameByIndex( nRefIdx, nNameIdx );
3143  if( pExtName && pExtName->IsOLE() )
3144  mnStorageId = pExtName->nStorageId;
3145  }
3146  break;
3147  case EXC_BIFF8:
3148  {
3149  sal_uInt16 nXti, nExtName;
3150  nXti = rStrm.ReaduInt16();
3151  nExtName = rStrm.ReaduInt16();
3152  const XclImpExtName* pExtName = GetLinkManager().GetExternName( nXti, nExtName );
3153  if( pExtName && (pExtName->GetType() == xlExtOLE) )
3154  mnStorageId = pExtName->GetStorageId();
3155  }
3156  break;
3157  default:
3158  DBG_ERROR_BIFF();
3159  }
3160  }
3162  {
3163  mbEmbedded = true;
3164  OSL_ENSURE( nFmlaSize == 5, "XclImpPictureObj::ReadPictFmla - unexpected formula size" );
3165  rStrm.Ignore( nFmlaSize - 1 ); // token ID already read
3166  if( nFmlaSize & 1 )
3167  rStrm.Ignore( 1 ); // padding byte
3168 
3169  // a class name may follow inside the picture link
3170  if( rStrm.GetRecPos() + 2 <= nLinkEnd )
3171  {
3172  sal_uInt16 nLen = rStrm.ReaduInt16();
3173  if( nLen > 0 )
3174  maClassName = (GetBiff() == EXC_BIFF8) ? rStrm.ReadUniString( nLen ) : rStrm.ReadRawByteString( nLen );
3175  }
3176  }
3177  // else: ignore other formulas, e.g. pictures linked to cell ranges
3178  }
3179  }
3180 
3181  // seek behind picture link data
3182  rStrm.Seek( nLinkEnd );
3183 
3184  // read additional data for embedded OLE objects following the picture link
3185  if( IsOcxControl() )
3186  {
3187  // #i26521# form controls to be ignored
3188  if( maClassName == "Forms.HTML:Hidden.1" )
3189  {
3190  SetProcessSdrObj( false );
3191  return;
3192  }
3193 
3194  if( rStrm.GetRecLeft() <= 8 ) return;
3195 
3196  // position and size of control data in 'Ctls' stream
3197  mnCtlsStrmPos = static_cast< std::size_t >( rStrm.ReaduInt32() );
3198  mnCtlsStrmSize = static_cast< std::size_t >( rStrm.ReaduInt32() );
3199 
3200  if( rStrm.GetRecLeft() <= 8 ) return;
3201 
3202  // additional string (16-bit characters), e.g. for progress bar control
3203  sal_uInt32 nAddStrSize;
3204  nAddStrSize = rStrm.ReaduInt32();
3205  OSL_ENSURE( rStrm.GetRecLeft() >= nAddStrSize + 4, "XclImpPictureObj::ReadPictFmla - missing data" );
3206  if( rStrm.GetRecLeft() >= nAddStrSize + 4 )
3207  {
3208  rStrm.Ignore( nAddStrSize );
3209  // cell link and source range
3210  ReadCellLinkFormula( rStrm, true );
3211  ReadSourceRangeFormula( rStrm, true );
3212  }
3213  }
3214  else if( mbEmbedded && (rStrm.GetRecLeft() >= 4) )
3215  {
3216  mnStorageId = rStrm.ReaduInt32();
3217  }
3218 }
3219 
3220 // DFF stream conversion ======================================================
3221 
3222 void XclImpSolverContainer::InsertSdrObjectInfo( SdrObject& rSdrObj, sal_uInt32 nDffShapeId, ShapeFlag nDffFlags )
3223 {
3224  if( nDffShapeId > 0 )
3225  {
3226  maSdrInfoMap[ nDffShapeId ].Set( &rSdrObj, nDffFlags );
3227  maSdrObjMap[ &rSdrObj ] = nDffShapeId;
3228  }
3229 }
3230 
3232 {
3233  // remove info of passed object from the maps
3234  XclImpSdrObjMap::iterator aIt = maSdrObjMap.find( &rSdrObj );
3235  if( aIt != maSdrObjMap.end() )
3236  {
3237  maSdrInfoMap.erase( aIt->second );
3238  maSdrObjMap.erase( aIt );
3239  }
3240 
3241  // remove info of all child objects of a group object
3242  if( SdrObjGroup* pGroupObj = dynamic_cast< SdrObjGroup* >( &rSdrObj ) )
3243  {
3244  if( SdrObjList* pSubList = pGroupObj->GetSubList() )
3245  {
3246  // iterate flat over the list because this function already works recursively
3247  SdrObjListIter aObjIt( pSubList, SdrIterMode::Flat );
3248  for( SdrObject* pChildObj = aObjIt.Next(); pChildObj; pChildObj = aObjIt.Next() )
3249  RemoveSdrObjectInfo( *pChildObj );
3250  }
3251  }
3252 }
3253 
3255 {
3256  for (auto const & pRule : aCList)
3257  {
3258  UpdateConnection( pRule->nShapeA, pRule->pAObj, &pRule->nSpFlagsA );
3259  UpdateConnection( pRule->nShapeB, pRule->pBObj, &pRule->nSpFlagsB );
3260  UpdateConnection( pRule->nShapeC, pRule->pCObj );
3261  }
3262 }
3263 
3265 {
3266  aCList.clear();
3267  maSdrInfoMap.clear();
3268  maSdrObjMap.clear();
3269 }
3270 
3271 void XclImpSolverContainer::UpdateConnection( sal_uInt32 nDffShapeId, SdrObject*& rpSdrObj, ShapeFlag* pnDffFlags )
3272 {
3273  XclImpSdrInfoMap::const_iterator aIt = maSdrInfoMap.find( nDffShapeId );
3274  if( aIt != maSdrInfoMap.end() )
3275  {
3276  rpSdrObj = aIt->second.mpSdrObj;
3277  if( pnDffFlags )
3278  *pnDffFlags = aIt->second.mnDffFlags;
3279  }
3280 }
3281 
3283  SvxMSDffManager( rDffStrm, rRoot.GetBasePath(), 0, nullptr, rRoot.GetDoc().GetDrawLayer(), 1440, COL_DEFAULT, nullptr ),
3284  XclImpRoot( rRoot )
3285 {
3287 }
3288 
3290 {
3291 }
3292 
3293 bool XclImpSimpleDffConverter::GetColorFromPalette( sal_uInt16 nIndex, Color& rColor ) const
3294 {
3295  Color nColor = GetPalette().GetColor( nIndex );
3296 
3297  if( nColor == COL_AUTO )
3298  return false;
3299 
3300  rColor = nColor;
3301  return true;
3302 }
3303 
3305  XclImpDrawing& rDrawing, SdrModel& rSdrModel, SdrPage& rSdrPage ) :
3306  mrDrawing( rDrawing ),
3307  mrSdrModel( rSdrModel ),
3308  mrSdrPage( rSdrPage ),
3309  mnLastCtrlIndex( -1 ),
3310  mbHasCtrlForm( false )
3311 {
3312 }
3313 
3314 constexpr OUStringLiteral gaStdFormName( u"Standard" );
3315 
3317  XclImpSimpleDffConverter( rRoot, rDffStrm ),
3318  oox::ole::MSConvertOCXControls( rRoot.GetDocShell()->GetModel() ),
3319  mnOleImpFlags( 0 ),
3320  mbNotifyMacroEventRead(false)
3321 {
3322  const SvtFilterOptions& rFilterOpt = SvtFilterOptions::Get();
3323  if( rFilterOpt.IsMathType2Math() )
3325  if( rFilterOpt.IsWinWord2Writer() )
3327  if( rFilterOpt.IsPowerPoint2Impress() )
3329 
3330  // try to open the 'Ctls' storage stream containing OCX control properties
3332 
3333  // default text margin (convert EMU to drawing layer units)
3336 }
3337 
3339 {
3340 }
3341 
3342 OUString XclImpObjectManager::GetOleNameOverride( SCTAB nTab, sal_uInt16 nObjId )
3343 {
3344  OUString sOleName;
3345  OUString sCodeName = GetExtDocOptions().GetCodeName( nTab );
3346 
3347  if (mxOleCtrlNameOverride.is() && mxOleCtrlNameOverride->hasByName(sCodeName))
3348  {
3349  Reference< XIndexContainer > xIdToOleName;
3350  mxOleCtrlNameOverride->getByName( sCodeName ) >>= xIdToOleName;
3351  xIdToOleName->getByIndex( nObjId ) >>= sOleName;
3352  }
3353 
3354  return sOleName;
3355 }
3356 
3357 void XclImpDffConverter::StartProgressBar( std::size_t nProgressSize )
3358 {
3359  mxProgress = std::make_shared<ScfProgressBar>( GetDocShell(), STR_PROGRESS_CALCULATING );
3360  mxProgress->AddSegment( nProgressSize );
3361  mxProgress->Activate();
3362 }
3363 
3364 void XclImpDffConverter::Progress( std::size_t nDelta )
3365 {
3366  OSL_ENSURE( mxProgress, "XclImpDffConverter::Progress - invalid call, no progress bar" );
3367  mxProgress->Progress( nDelta );
3368 }
3369 
3371 {
3372  XclImpDffConvDataRef xConvData = std::make_shared<XclImpDffConvData>( rDrawing, rSdrModel, rSdrPage );
3373  maDataStack.push_back( xConvData );
3374  SetModel( &xConvData->mrSdrModel, 1440 );
3375 }
3376 
3378 {
3379  if( !rDrawObj.IsProcessSdrObj() )
3380  return;
3381 
3382  const XclObjAnchor* pAnchor = rDrawObj.GetAnchor();
3383  if(!pAnchor)
3384  return;
3385 
3386  tools::Rectangle aAnchorRect = GetConvData().mrDrawing.CalcAnchorRect( *pAnchor, false );
3387  if( rDrawObj.IsValidSize( aAnchorRect ) )
3388  {
3389  // CreateSdrObject() recursively creates embedded child objects
3390  SdrObjectUniquePtr xSdrObj( rDrawObj.CreateSdrObject( *this, aAnchorRect, false ) );
3391  if( xSdrObj )
3392  rDrawObj.PreProcessSdrObject( *this, *xSdrObj );
3393  // call InsertSdrObject() also, if SdrObject is missing
3394  InsertSdrObject( rObjList, rDrawObj, xSdrObj.release() );
3395  }
3396 }
3397 
3399 {
3400  SdrPage& rSdrPage = GetConvData().mrSdrPage;
3401  for( const auto& rxDrawObj : rDrawObjs )
3402  ProcessObject( rSdrPage, *rxDrawObj );
3403 }
3404 
3406 {
3407  if( rDffStrm.TellEnd() > 0 )
3408  {
3409  rDffStrm.Seek( STREAM_SEEK_TO_BEGIN );
3410  DffRecordHeader aHeader;
3411  ReadDffRecordHeader( rDffStrm, aHeader );
3412  OSL_ENSURE( aHeader.nRecType == DFF_msofbtDgContainer, "XclImpDffConverter::ProcessDrawing - unexpected record" );
3413  if( aHeader.nRecType == DFF_msofbtDgContainer )
3414  ProcessDgContainer( rDffStrm, aHeader );
3415  }
3416 }
3417 
3419 {
3420  OSL_ENSURE( !maDataStack.empty(), "XclImpDffConverter::FinalizeDrawing - no drawing manager on stack" );
3421  maDataStack.pop_back();
3422  // restore previous model at core DFF converter
3423  if( !maDataStack.empty() )
3424  SetModel( &maDataStack.back()->mrSdrModel, 1440 );
3425 }
3426 
3428 {
3430  return;
3432  mbNotifyMacroEventRead = true;
3433 }
3434 
3436 {
3437  SdrObjectUniquePtr xSdrObj;
3438 
3439  OUString aServiceName = rTbxObj.GetServiceName();
3440  if( SupportsOleObjects() && !aServiceName.isEmpty() ) try
3441  {
3442  // create the form control from scratch
3443  Reference< XFormComponent > xFormComp( ScfApiHelper::CreateInstance( GetDocShell(), aServiceName ), UNO_QUERY_THROW );
3444  // set controls form, needed in virtual function InsertControl()
3445  InitControlForm();
3446  // try to insert the control into the form
3447  css::awt::Size aDummySize;
3448  Reference< XShape > xShape;
3449  XclImpDffConvData& rConvData = GetConvData();
3450  if( rConvData.mxCtrlForm.is() && InsertControl( xFormComp, aDummySize, &xShape, true ) )
3451  {
3452  xSdrObj = rTbxObj.CreateSdrObjectFromShape( xShape, rAnchorRect );
3453  // try to attach a macro to the control
3454  ScriptEventDescriptor aDescriptor;
3455  if( (rConvData.mnLastCtrlIndex >= 0) && rTbxObj.FillMacroDescriptor( aDescriptor ) )
3456  {
3458  Reference< XEventAttacherManager > xEventMgr( rConvData.mxCtrlForm, UNO_QUERY_THROW );
3459  xEventMgr->registerScriptEvent( rConvData.mnLastCtrlIndex, aDescriptor );
3460  }
3461  }
3462  }
3463  catch( const Exception& )
3464  {
3465  }
3466 
3467  return xSdrObj;
3468 }
3469 
3471 {
3472  SdrObjectUniquePtr xSdrObj;
3473 
3474  if( SupportsOleObjects() )
3475  {
3476  if( rPicObj.IsOcxControl() )
3477  {
3478  if( mxCtlsStrm.is() ) try
3479  {
3480  /* set controls form, needed in virtual function InsertControl()
3481  called from ReadOCXExcelKludgeStream() */
3482  InitControlForm();
3483 
3484  // read from mxCtlsStrm into xShape, insert the control model into the form
3485  Reference< XShape > xShape;
3486  if( GetConvData().mxCtrlForm.is() )
3487  {
3488  Reference< XFormComponent > xFComp;
3489  ReadOCXCtlsStream( mxCtlsStrm, xFComp, rPicObj.GetCtlsStreamPos(), rPicObj.GetCtlsStreamSize() );
3490  // recreate the method formerly known as ReadOCXExcelKludgeStream()
3491  if ( xFComp.is() )
3492  {
3493  css::awt::Size aSz; // not used in import
3494  ScfPropertySet aPropSet( xFComp );
3495  aPropSet.SetStringProperty( "Name", rPicObj.GetObjName() );
3496  InsertControl( xFComp, aSz,&xShape,true);
3497  xSdrObj = rPicObj.CreateSdrObjectFromShape( xShape, rAnchorRect );
3498  }
3499  }
3500  }
3501  catch( const Exception& )
3502  {
3503  }
3504  }
3505  else
3506  {
3507  SfxObjectShell* pDocShell = GetDocShell();
3509  OUString aStrgName = rPicObj.GetOleStorageName();
3510  if( pDocShell && xSrcStrg.is() && (!aStrgName.isEmpty()) )
3511  {
3512  // first try to resolve graphic from DFF storage
3513  Graphic aGraphic;
3514  tools::Rectangle aVisArea;
3515  if( !GetBLIP( GetPropertyValue( DFF_Prop_pib, 0 ), aGraphic, &aVisArea ) )
3516  {
3517  // if not found, use graphic from object (imported from IMGDATA record)
3518  aGraphic = rPicObj.GetGraphic();
3519  }
3520  if( aGraphic.GetType() != GraphicType::NONE )
3521  {
3522  ErrCode nError = ERRCODE_NONE;
3523  namespace cssea = ::com::sun::star::embed::Aspects;
3524  sal_Int64 nAspects = rPicObj.IsSymbol() ? cssea::MSOLE_ICON : cssea::MSOLE_CONTENT;
3525  xSdrObj.reset(
3527  GetConvData().mrSdrModel,
3528  aStrgName,
3529  xSrcStrg,
3530  pDocShell->GetStorage(),
3531  aGraphic,
3532  rAnchorRect,
3533  aVisArea,
3534  nullptr,
3535  nError,
3536  mnOleImpFlags,
3537  nAspects,
3538  GetRoot().GetMedium().GetBaseURL()));
3539  }
3540  }
3541  }
3542  }
3543 
3544  return xSdrObj;
3545 }
3546 
3548 {
3550 }
3551 
3552 // virtual functions ----------------------------------------------------------
3553 
3555  DffRecordHeader& rHeader, DffObjData& rObjData )
3556 {
3557  // find the OBJ record data related to the processed shape
3558  XclImpDffConvData& rConvData = GetConvData();
3559  XclImpDrawObjBase* pDrawObj = rConvData.mrDrawing.FindDrawObj( rObjData.rSpHd ).get();
3560  if(!pDrawObj)
3561  return;
3562 
3563  OSL_ENSURE( rHeader.nRecType == DFF_msofbtClientAnchor, "XclImpDffConverter::ProcessClientAnchor2 - no client anchor record" );
3564  XclObjAnchor aAnchor;
3565  rHeader.SeekToContent( rDffStrm );
3566  sal_uInt8 nFlags(0);
3567  rDffStrm.ReadUChar( nFlags );
3568  rDffStrm.SeekRel( 1 ); // flags
3569  rDffStrm >> aAnchor; // anchor format equal to BIFF5 OBJ records
3570 
3571  pDrawObj->SetAnchor( aAnchor );
3572  rObjData.aChildAnchor = rConvData.mrDrawing.CalcAnchorRect( aAnchor, true );
3573  rObjData.bChildAnchor = true;
3574  // page anchoring is the best approximation we have if mbMove
3575  // is set
3576  rObjData.bPageAnchor = ( nFlags & 0x1 );
3577 }
3578 
3579 namespace {
3580 
3581 struct XclImpDrawObjClientData : public SvxMSDffClientData
3582 {
3583  const XclImpDrawObjBase* m_pTopLevelObj;
3584 
3585  XclImpDrawObjClientData()
3586  : m_pTopLevelObj(nullptr)
3587  {
3588  }
3589  virtual void NotifyFreeObj(SdrObject*) override {}
3590 };
3591 
3592 }
3593 
3595  SvxMSDffClientData& rClientData, tools::Rectangle& /*rTextRect*/, SdrObject* pOldSdrObj )
3596 {
3597  XclImpDffConvData& rConvData = GetConvData();
3598 
3599  /* pOldSdrObj passes a generated SdrObject. This function owns this object
3600  and can modify it. The function has either to return it back to caller
3601  or to delete it by itself. */
3602  SdrObjectUniquePtr xSdrObj( pOldSdrObj );
3603 
3604  // find the OBJ record data related to the processed shape
3605  XclImpDrawObjRef xDrawObj = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd );
3606  const tools::Rectangle& rAnchorRect = rDffObjData.aChildAnchor;
3607 
3608  // Do not process the global page group shape
3609  bool bGlobalPageGroup( rDffObjData.nSpFlags & ShapeFlag::Patriarch );
3610  if( !xDrawObj || !xDrawObj->IsProcessSdrObj() || bGlobalPageGroup )
3611  return nullptr; // simply return, xSdrObj will be destroyed
3612 
3613  /* Pass pointer to top-level object back to caller. If the processed
3614  object is embedded in a group, the pointer is already set to the
3615  top-level parent object. */
3616  XclImpDrawObjClientData& rDrawObjClientData = static_cast<XclImpDrawObjClientData&>(rClientData);
3617  const bool bIsTopLevel = !rDrawObjClientData.m_pTopLevelObj;
3618  if (bIsTopLevel )
3619  rDrawObjClientData.m_pTopLevelObj = xDrawObj.get();
3620 
3621  // connectors don't have to be area objects
3622  if( dynamic_cast< SdrEdgeObj* >( xSdrObj.get() ) )
3623  xDrawObj->SetAreaObj( false );
3624 
3625  /* Check for valid size for all objects. Needed to ignore lots of invisible
3626  phantom objects from deleted rows or columns (for performance reasons).
3627  #i30816# Include objects embedded in groups.
3628  #i58780# Ignore group shapes, size is not initialized. */
3629  bool bEmbeddedGroup = !bIsTopLevel && dynamic_cast< SdrObjGroup* >( xSdrObj.get() );
3630  if( !bEmbeddedGroup && !xDrawObj->IsValidSize( rAnchorRect ) )
3631  return nullptr; // simply return, xSdrObj will be destroyed
3632 
3633  // set shape information from DFF stream
3634  OUString aObjName = GetPropertyString( DFF_Prop_wzName, rDffStrm );
3635  OUString aHyperlink = ReadHlinkProperty( rDffStrm );
3637  bool bAutoMargin = GetPropertyBool( DFF_Prop_AutoTextMargin );
3638  xDrawObj->SetDffData( rDffObjData, aObjName, aHyperlink, bVisible, bAutoMargin );
3639 
3640  /* Connect textbox data (string, alignment, text orientation) to object.
3641  don't ask for a text-ID, DFF export doesn't set one. */
3642  if( XclImpTextObj* pTextObj = dynamic_cast< XclImpTextObj* >( xDrawObj.get() ) )
3643  if( const XclImpObjTextData* pTextData = rConvData.mrDrawing.FindTextData( rDffObjData.rSpHd ) )
3644  pTextObj->SetTextData( *pTextData );
3645 
3646  // copy line and fill formatting of TBX form controls from DFF properties
3647  if( XclImpTbxObjBase* pTbxObj = dynamic_cast< XclImpTbxObjBase* >( xDrawObj.get() ) )
3648  pTbxObj->SetDffProperties( *this );
3649 
3650  // try to create a custom SdrObject that overwrites the passed object
3651  SdrObjectUniquePtr xNewSdrObj( xDrawObj->CreateSdrObject( *this, rAnchorRect, true ) );
3652  if( xNewSdrObj )
3653  xSdrObj = std::move( xNewSdrObj );
3654 
3655  // process the SdrObject
3656  if( xSdrObj )
3657  {
3658  // filled without color -> set system window color
3660  xSdrObj->SetMergedItem( XFillColorItem( EMPTY_OUSTRING, GetPalette().GetColor( EXC_COLOR_WINDOWBACK ) ) );
3661 
3662  // additional processing on the SdrObject
3663  xDrawObj->PreProcessSdrObject( *this, *xSdrObj );
3664 
3665  /* If the SdrObject will not be inserted into the draw page, delete it
3666  here. Happens e.g. for notes: The PreProcessSdrObject() call above
3667  has inserted the note into the document, and the SdrObject is not
3668  needed anymore. */
3669  if( !xDrawObj->IsInsertSdrObj() )
3670  xSdrObj.reset();
3671  }
3672 
3673  if( xSdrObj )
3674  {
3675  /* Store the relation between shape ID and SdrObject for connectors.
3676  Must be done here (and not in InsertSdrObject() function),
3677  otherwise all SdrObjects embedded in groups would be lost. */
3678  rConvData.maSolverCont.InsertSdrObjectInfo( *xSdrObj, xDrawObj->GetDffShapeId(), xDrawObj->GetDffFlags() );
3679 
3680  /* If the drawing object is embedded in a group object, call
3681  PostProcessSdrObject() here. For top-level objects this will be
3682  done automatically in InsertSdrObject() but grouped shapes are
3683  inserted into their groups somewhere in the SvxMSDffManager base
3684  class without chance of notification. Unfortunately, now this is
3685  called before the object is really inserted into its group object,
3686  but that should not have any effect for grouped objects. */
3687  if( !bIsTopLevel )
3688  xDrawObj->PostProcessSdrObject( *this, *xSdrObj );
3689  }
3690 
3691  return xSdrObj.release();
3692 }
3693 
3695 {
3696  XclImpDffConvData& rConvData = GetConvData();
3697 
3698  /* pOldSdrObj passes a generated SdrObject. This function owns this object
3699  and can modify it. The function has either to return it back to caller
3700  or to delete it by itself. */
3701  SdrObjectUniquePtr xSdrObj( pOldSdrObj );
3702 
3703  // find the OBJ record data related to the processed shape
3704  XclImpDrawObjRef xDrawObj = rConvData.mrDrawing.FindDrawObj( rDffObjData.rSpHd );
3705 
3706  if( xSdrObj && xDrawObj )
3707  {
3708  // cell anchoring
3709  if ( !rDffObjData.bPageAnchor )
3710  ScDrawLayer::SetCellAnchoredFromPosition( *xSdrObj, GetDoc(), xDrawObj->GetTab(), false );
3711  }
3712 
3713  return xSdrObj.release();
3714 }
3715 
3716 bool XclImpDffConverter::InsertControl( const Reference< XFormComponent >& rxFormComp,
3717  const css::awt::Size& /*rSize*/, Reference< XShape >* pxShape,
3718  bool /*bFloatingCtrl*/ )
3719 {
3720  if( GetDocShell() ) try
3721  {
3722  XclImpDffConvData& rConvData = GetConvData();
3723  Reference< XIndexContainer > xFormIC( rConvData.mxCtrlForm, UNO_QUERY_THROW );
3724  Reference< XControlModel > xCtrlModel( rxFormComp, UNO_QUERY_THROW );
3725 
3726  // create the control shape
3727  Reference< XShape > xShape( ScfApiHelper::CreateInstance( GetDocShell(), "com.sun.star.drawing.ControlShape" ), UNO_QUERY_THROW );
3728  Reference< XControlShape > xCtrlShape( xShape, UNO_QUERY_THROW );
3729 
3730  // insert the new control into the form
3731  sal_Int32 nNewIndex = xFormIC->getCount();
3732  xFormIC->insertByIndex( nNewIndex, Any( rxFormComp ) );
3733  // on success: store new index of the control for later use (macro events)
3734  rConvData.mnLastCtrlIndex = nNewIndex;
3735 
3736  // set control model at control shape and pass back shape to caller
3737  xCtrlShape->setControl( xCtrlModel );
3738  if( pxShape ) *pxShape = xShape;
3739  return true;
3740  }
3741  catch( const Exception& )
3742  {
3743  OSL_FAIL( "XclImpDffConverter::InsertControl - cannot create form control" );
3744  }
3745 
3746  return false;
3747 }
3748 
3749 // private --------------------------------------------------------------------
3750 
3752 {
3753  OSL_ENSURE( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3754  return *maDataStack.back();
3755 }
3756 
3758 {
3759  OSL_ENSURE( !maDataStack.empty(), "XclImpDffConverter::GetConvData - no drawing manager on stack" );
3760  return *maDataStack.back();
3761 }
3762 
3764 {
3765  /* Reads hyperlink data from a complex DFF property. Contents of this
3766  property are equal to the HLINK record, import of this record is
3767  implemented in class XclImpHyperlink. This function has to create an
3768  instance of the XclImpStream class to be able to reuse the
3769  functionality of XclImpHyperlink. */
3770  OUString aString;
3771  sal_uInt32 nBufferSize = GetPropertyValue( DFF_Prop_pihlShape, 0 );
3772  if( (0 < nBufferSize) && (nBufferSize <= 0xFFFF) && SeekToContent( DFF_Prop_pihlShape, rDffStrm ) )
3773  {
3774  // create a faked BIFF record that can be read by XclImpStream class
3775  SvMemoryStream aMemStream;
3776  aMemStream.WriteUInt16( 0 ).WriteUInt16( nBufferSize );
3777 
3778  // copy from DFF stream to memory stream
3779  ::std::vector< sal_uInt8 > aBuffer( nBufferSize );
3780  sal_uInt8* pnData = aBuffer.data();
3781  if (rDffStrm.ReadBytes(pnData, nBufferSize) == nBufferSize)
3782  {
3783  aMemStream.WriteBytes(pnData, nBufferSize);
3784 
3785  // create BIFF import stream to be able to use XclImpHyperlink class
3786  XclImpStream aXclStrm( aMemStream, GetRoot() );
3787  if( aXclStrm.StartNextRecord() )
3788  aString = XclImpHyperlink::ReadEmbeddedData( aXclStrm );
3789  }
3790  }
3791  return aString;
3792 }
3793 
3795 {
3796  std::size_t nEndPos = rDgHeader.GetRecEndFilePos();
3797  bool isBreak(false);
3798  while (!isBreak && rDffStrm.good() && rDffStrm.Tell() < nEndPos)
3799  {
3800  DffRecordHeader aHeader;
3801  ReadDffRecordHeader( rDffStrm, aHeader );
3802  switch( aHeader.nRecType )
3803  {
3805  isBreak = !ProcessSolverContainer( rDffStrm, aHeader );
3806  break;
3808  isBreak = !ProcessShGrContainer( rDffStrm, aHeader );
3809  break;
3810  default:
3811  isBreak = !aHeader.SeekToEndOfRecord( rDffStrm );
3812  }
3813  }
3814  // seek to end of drawing page container
3815  isBreak = !rDgHeader.SeekToEndOfRecord( rDffStrm );
3816 
3817  // #i12638# #i37900# connector rules
3819  rSolverCont.UpdateConnectorRules();
3820  SolveSolver( rSolverCont );
3821  rSolverCont.RemoveConnectorRules();
3822  return !isBreak;
3823 }
3824 
3826 {
3827  std::size_t nEndPos = rShGrHeader.GetRecEndFilePos();
3828  bool isBreak(false);
3829  while (!isBreak && rDffStrm.good() && rDffStrm.Tell() < nEndPos)
3830  {
3831  DffRecordHeader aHeader;
3832  ReadDffRecordHeader( rDffStrm, aHeader );
3833  switch( aHeader.nRecType )
3834  {
3836  case DFF_msofbtSpContainer:
3837  isBreak = !ProcessShContainer( rDffStrm, aHeader );
3838  break;
3839  default:
3840  isBreak = !aHeader.SeekToEndOfRecord( rDffStrm );
3841  }
3842  }
3843  // seek to end of shape group container
3844  return rShGrHeader.SeekToEndOfRecord( rDffStrm ) && !isBreak;
3845 }
3846 
3848 {
3849  // solver container wants to read the solver container header again
3850  rSolverHeader.SeekToBegOfRecord( rDffStrm );
3851  // read the entire solver container
3852  ReadSvxMSDffSolverContainer( rDffStrm, GetConvData().maSolverCont );
3853  // seek to end of solver container
3854  return rSolverHeader.SeekToEndOfRecord( rDffStrm );
3855 }
3856 
3858 {
3859  rShHeader.SeekToBegOfRecord( rDffStrm );
3860  tools::Rectangle aDummy;
3861  XclImpDrawObjClientData aDrawObjClientData;
3862  /* The call to ImportObj() creates and returns a new SdrObject for the
3863  processed shape. We take ownership of the returned object here. If the
3864  shape is a group object, all embedded objects are created recursively,
3865  and the returned group object contains them all. ImportObj() calls the
3866  virtual functions ProcessClientAnchor2() and ProcessObj() and writes
3867  the pointer to the related draw object data (OBJ record) into aDrawObjClientData. */
3868  SdrObjectUniquePtr xSdrObj( ImportObj( rDffStrm, aDrawObjClientData, aDummy, aDummy, /*nCalledByGroup*/0, /*pShapeId*/nullptr ) );
3869  if (aDrawObjClientData.m_pTopLevelObj && xSdrObj )
3870  InsertSdrObject( GetConvData().mrSdrPage, *aDrawObjClientData.m_pTopLevelObj, xSdrObj.release() );
3871  return rShHeader.SeekToEndOfRecord( rDffStrm );
3872 }
3873 
3875 {
3876  XclImpDffConvData& rConvData = GetConvData();
3877  /* Take ownership of the passed object. If insertion fails (e.g. rDrawObj
3878  states to skip insertion), the object is automatically deleted. */
3879  SdrObjectUniquePtr xSdrObj( pSdrObj );
3880  if( xSdrObj && rDrawObj.IsInsertSdrObj() )
3881  {
3882  rObjList.NbcInsertObject( xSdrObj.release() );
3883  // callback to drawing manager for e.g. tracking of used sheet area
3884  rConvData.mrDrawing.OnObjectInserted( rDrawObj );
3885  // callback to drawing object for post processing (use pSdrObj, xSdrObj already released)
3886  rDrawObj.PostProcessSdrObject( *this, *pSdrObj );
3887  }
3888  /* SdrObject still here? Insertion failed, remove data from shape ID map.
3889  The SdrObject will be destructed then. */
3890  if( xSdrObj )
3891  rConvData.maSolverCont.RemoveSdrObjectInfo( *xSdrObj );
3892 }
3893 
3895 {
3896  XclImpDffConvData& rConvData = GetConvData();
3897  if( rConvData.mbHasCtrlForm )
3898  return;
3899 
3900  rConvData.mbHasCtrlForm = true;
3901  if( !SupportsOleObjects() )
3902  return;
3903 
3904  try
3905  {
3906  Reference< XFormsSupplier > xFormsSupplier( rConvData.mrSdrPage.getUnoPage(), UNO_QUERY_THROW );
3907  Reference< XNameContainer > xFormsNC( xFormsSupplier->getForms(), UNO_SET_THROW );
3908  // find or create the Standard form used to insert the imported controls
3909  if( xFormsNC->hasByName( gaStdFormName ) )
3910  {
3911  xFormsNC->getByName( gaStdFormName ) >>= rConvData.mxCtrlForm;
3912  }
3913  else if( SfxObjectShell* pDocShell = GetDocShell() )
3914  {
3915  rConvData.mxCtrlForm.set( ScfApiHelper::CreateInstance( pDocShell, "com.sun.star.form.component.Form" ), UNO_QUERY_THROW );
3916  xFormsNC->insertByName( gaStdFormName, Any( rConvData.mxCtrlForm ) );
3917  }
3918  }
3919  catch( const Exception& )
3920  {
3921  }
3922 }
3923 
3924 // Drawing manager ============================================================
3925 
3926 XclImpDrawing::XclImpDrawing( const XclImpRoot& rRoot, bool bOleObjects ) :
3927  XclImpRoot( rRoot ),
3928  mbOleObjs( bOleObjects )
3929 {
3930 }
3931 
3933 {
3934 }
3935 
3937 {
3938  Graphic aGraphic;
3939  sal_uInt16 nFormat = rStrm.ReaduInt16();
3940  rStrm.Ignore( 2 );//nEnv
3941  sal_uInt32 nDataSize = rStrm.ReaduInt32();
3942  if( nDataSize <= rStrm.GetRecLeft() )
3943  {
3944  switch( nFormat )
3945  {
3946  case EXC_IMGDATA_WMF: ReadWmf( aGraphic, rStrm ); break;
3947  case EXC_IMGDATA_BMP: ReadBmp( aGraphic, rRoot, rStrm ); break;
3948  default: OSL_FAIL( "XclImpDrawing::ReadImgData - unknown image format" );
3949  }
3950  }
3951  return aGraphic;
3952 }
3953 
3955 {
3956  XclImpDrawObjRef xDrawObj;
3957 
3958  /* #i61786# In BIFF8 streams, OBJ records may occur without MSODRAWING
3959  records. In this case, the OBJ records are in BIFF5 format. Do a sanity
3960  check here that there is no DFF data loaded before. */
3961  OSL_ENSURE( maDffStrm.Tell() == 0, "XclImpDrawing::ReadObj - unexpected DFF stream data, OBJ will be ignored" );
3962  if( maDffStrm.Tell() == 0 ) switch( GetBiff() )
3963  {
3964  case EXC_BIFF3:
3965  xDrawObj = XclImpDrawObjBase::ReadObj3( GetRoot(), rStrm );
3966  break;
3967  case EXC_BIFF4:
3968  xDrawObj = XclImpDrawObjBase::ReadObj4( GetRoot(), rStrm );
3969  break;
3970  case EXC_BIFF5:
3971  case EXC_BIFF8:
3972  xDrawObj = XclImpDrawObjBase::ReadObj5( GetRoot(), rStrm );
3973  break;
3974  default:
3975  DBG_ERROR_BIFF();
3976  }
3977 
3978  if( xDrawObj )
3979  {
3980  // insert into maRawObjs or into the last open group object
3981  maRawObjs.InsertGrouped( xDrawObj );
3982  // to be able to find objects by ID
3983  maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
3984  }
3985 }
3986 
3988 {
3990  // disable internal CONTINUE handling
3991  rStrm.ResetRecord( false );
3992  // read leading MSODRAWING record
3993  ReadDffRecord( rStrm );
3994 
3995  // read following drawing records, but do not start following unrelated record
3996  bool bLoop = true;
3997  while( bLoop ) switch( rStrm.GetNextRecId() )
3998  {
3999  case EXC_ID_MSODRAWING:
4000  case EXC_ID_MSODRAWINGSEL:
4001  case EXC_ID_CONT:
4002  rStrm.StartNextRecord();
4003  ReadDffRecord( rStrm );
4004  break;
4005  case EXC_ID_OBJ:
4006  rStrm.StartNextRecord();
4007  ReadObj8( rStrm );
4008  break;
4009  case EXC_ID_TXO:
4010  rStrm.StartNextRecord();
4011  ReadTxo( rStrm );
4012  break;
4013  default:
4014  bLoop = false;
4015  }
4016 
4017  // re-enable internal CONTINUE handling
4018  rStrm.ResetRecord( true );
4019 }
4020 
4022 {
4023  /* maObjMap stores objects by position of the client data (OBJ record) in
4024  the DFF stream, which is always behind shape start position of the
4025  passed header. The function upper_bound() finds the first element in
4026  the map whose key is greater than the start position of the header. Its
4027  end position is used to test whether the found object is really related
4028  to the shape. */
4029  XclImpDrawObjRef xDrawObj;
4030  XclImpObjMap::const_iterator aIt = maObjMap.upper_bound( rHeader.GetRecBegFilePos() );
4031  if( (aIt != maObjMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
4032  xDrawObj = aIt->second;
4033  return xDrawObj;
4034 }
4035 
4037 {
4038  XclImpDrawObjRef xDrawObj;
4039  XclImpObjMapById::const_iterator aIt = maObjMapId.find( nObjId );
4040  if( aIt != maObjMapId.end() )
4041  xDrawObj = aIt->second;
4042  return xDrawObj;
4043 }
4044 
4046 {
4047  /* maTextMap stores textbox data by position of the client data (TXO
4048  record) in the DFF stream, which is always behind shape start position
4049  of the passed header. The function upper_bound() finds the first
4050  element in the map whose key is greater than the start position of the
4051  header. Its end position is used to test whether the found object is
4052  really related to the shape. */
4053  XclImpObjTextMap::const_iterator aIt = maTextMap.upper_bound( rHeader.GetRecBegFilePos() );
4054  if( (aIt != maTextMap.end()) && (aIt->first <= rHeader.GetRecEndFilePos()) )
4055  return aIt->second.get();
4056  return nullptr;
4057 }
4058 
4059 void XclImpDrawing::SetSkipObj( sal_uInt16 nObjId )
4060 {
4061  maSkipObjs.push_back( nObjId );
4062 }
4063 
4065 {
4066  return std::accumulate(maObjMap.begin(), maObjMap.end(), maRawObjs.GetProgressSize(),
4067  [](const std::size_t& rSum, const XclImpObjMap::value_type& rEntry) { return rSum + rEntry.second->GetProgressSize(); });
4068 }
4069 
4071 {
4072  //rhbz#636521, disable undo during conversion. faster, smaller and stops
4073  //temp objects being inserted into the undo list
4074  bool bOrigUndoStatus = rSdrModel.IsUndoEnabled();
4075  rSdrModel.EnableUndo(false);
4076  // register this drawing manager at the passed (global) DFF manager
4077  rDffConv.InitializeDrawing( *this, rSdrModel, rSdrPage );
4078  // process list of objects to be skipped
4079  for( const auto& rSkipObj : maSkipObjs )
4080  if( XclImpDrawObjBase* pDrawObj = FindDrawObj( rSkipObj ).get() )
4081  pDrawObj->SetProcessSdrObj( false );
4082  // process drawing objects without DFF data
4083  rDffConv.ProcessDrawing( maRawObjs );
4084  // process all objects in the DFF stream
4085  rDffConv.ProcessDrawing( maDffStrm );
4086  // unregister this drawing manager at the passed (global) DFF manager
4087  rDffConv.FinalizeDrawing();
4088  rSdrModel.EnableUndo(bOrigUndoStatus);
4089 }
4090 
4091 // protected ------------------------------------------------------------------
4092 
4094 {
4095  OSL_ENSURE( rxDrawObj, "XclImpDrawing::AppendRawObject - unexpected empty reference" );
4096  maRawObjs.push_back( rxDrawObj );
4097 }
4098 
4099 // private --------------------------------------------------------------------
4100 
4101 void XclImpDrawing::ReadWmf( Graphic& rGraphic, XclImpStream& rStrm ) // static helper
4102 {
4103  // extract graphic data from IMGDATA and following CONTINUE records
4104  rStrm.Ignore( 8 );
4105  SvMemoryStream aMemStrm;
4106  rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
4107  aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
4108  // import the graphic from memory stream
4109  GDIMetaFile aGDIMetaFile;
4110  if( ::ReadWindowMetafile( aMemStrm, aGDIMetaFile ) )
4111  rGraphic = aGDIMetaFile;
4112 }
4113 
4114 void XclImpDrawing::ReadBmp( Graphic& rGraphic, const XclImpRoot& rRoot, XclImpStream& rStrm ) // static helper
4115 {
4116  // extract graphic data from IMGDATA and following CONTINUE records
4117  SvMemoryStream aMemStrm;
4118 
4119  /* Excel 3 and 4 seem to write broken BMP data. Usually they write a
4120  DIBCOREHEADER (12 bytes) containing width, height, planes = 1, and
4121  pixel depth = 32 bit. After that, 3 unused bytes are added before the
4122  actual pixel data. This does even confuse Excel 5 and later, which
4123  cannot read the image data correctly. */
4124  if( rRoot.GetBiff() <= EXC_BIFF4 )
4125  {
4126  rStrm.PushPosition();
4127  sal_uInt32 nHdrSize;
4128  sal_uInt16 nWidth, nHeight, nPlanes, nDepth;
4129  nHdrSize = rStrm.ReaduInt32();
4130  nWidth = rStrm.ReaduInt16();
4131  nHeight = rStrm.ReaduInt16();
4132  nPlanes = rStrm.ReaduInt16();
4133  nDepth = rStrm.ReaduInt16();
4134  if( (nHdrSize == 12) && (nPlanes == 1) && (nDepth == 32) )
4135  {
4136  rStrm.Ignore( 3 );
4137  aMemStrm.SetEndian( SvStreamEndian::LITTLE );
4138  aMemStrm.WriteUInt32( nHdrSize ).WriteUInt16( nWidth ).WriteUInt16( nHeight ).WriteUInt16( nPlanes ).WriteUInt16( nDepth );
4139  rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
4140  }
4141  rStrm.PopPosition();
4142  }
4143 
4144  // no special handling above -> just copy the remaining record data
4145  if( aMemStrm.Tell() == 0 )
4146  rStrm.CopyToStream( aMemStrm, rStrm.GetRecLeft() );
4147 
4148  // import the graphic from memory stream
4149  aMemStrm.Seek( STREAM_SEEK_TO_BEGIN );
4150  Bitmap aBitmap;
4151  if( ReadDIB(aBitmap, aMemStrm, false) ) // read DIB without file header
4152  rGraphic = BitmapEx(aBitmap);
4153 }
4154 
4156 {
4158  rStrm.CopyRecordToStream( maDffStrm );
4159 }
4160 
4162 {
4163  XclImpDrawObjRef xDrawObj = XclImpDrawObjBase::ReadObj8( GetRoot(), rStrm );
4164  // store the new object in the internal containers
4165  maObjMap[ maDffStrm.Tell() ] = xDrawObj;
4166  maObjMapId[ xDrawObj->GetObjId() ] = xDrawObj;
4167 }
4168 
4170 {
4171  XclImpObjTextRef xTextData = std::make_shared<XclImpObjTextData>();
4172  maTextMap[ maDffStrm.Tell() ] = xTextData;
4173 
4174  // 1) read the TXO record
4175  xTextData->maData.ReadTxo8( rStrm );
4176 
4177  // 2) first CONTINUE with string
4178  xTextData->mxString.reset();
4179  bool bValid = true;
4180  if( xTextData->maData.mnTextLen > 0 )
4181  {
4182  bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
4183  OSL_ENSURE( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
4184  if( bValid )
4185  xTextData->mxString = std::make_shared<XclImpString>( rStrm.ReadUniString( xTextData->maData.mnTextLen ) );
4186  }
4187 
4188  // 3) second CONTINUE with formatting runs
4189  if( xTextData->maData.mnFormatSize > 0 )
4190  {
4191  bValid = (rStrm.GetNextRecId() == EXC_ID_CONT) && rStrm.StartNextRecord();
4192  OSL_ENSURE( bValid, "XclImpDrawing::ReadTxo - missing CONTINUE record" );
4193  if( bValid )
4194  xTextData->ReadFormats( rStrm );
4195  }
4196 }
4197 
4199  XclImpDrawing( rRoot, true ),
4200  maScUsedArea( ScAddress::INITIALIZE_INVALID )
4201 {
4202  maScUsedArea.aStart.SetTab( nScTab );
4203  maScUsedArea.aEnd.SetTab( nScTab );
4204 }
4205 
4207 {
4208  switch( GetBiff() )
4209  {
4210  case EXC_BIFF2:
4211  case EXC_BIFF3:
4212  case EXC_BIFF4:
4213  case EXC_BIFF5:
4214  ReadNote3( rStrm );
4215  break;
4216  case EXC_BIFF8:
4217  ReadNote8( rStrm );
4218  break;
4219  default:
4220  DBG_ERROR_BIFF();
4221  }
4222 }
4223 
4225 {
4227  auto xChartObj = std::make_shared<XclImpChartObj>( GetRoot(), true );
4228  xChartObj->ReadChartSubStream( rStrm );
4229  // insert the chart as raw object without connected DFF data
4230  AppendRawObject( xChartObj );
4231 }
4232 
4234 {
4235  if( SdrModel* pSdrModel = GetDoc().GetDrawLayer() )
4236  if( SdrPage* pSdrPage = GetSdrPage( maScUsedArea.aStart.Tab() ) )
4237  ImplConvertObjects( rDffConv, *pSdrModel, *pSdrPage );
4238 }
4239 
4240 tools::Rectangle XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool /*bDffAnchor*/ ) const
4241 {
4242  return rAnchor.GetRect( GetRoot(), maScUsedArea.aStart.Tab(), MapUnit::Map100thMM );
4243 }
4244 
4246 {
4247  ScRange aScObjArea = rDrawObj.GetUsedArea( maScUsedArea.aStart.Tab() );
4248  if( aScObjArea.IsValid() )
4249  maScUsedArea.ExtendTo( aScObjArea );
4250 }
4251 
4252 // private --------------------------------------------------------------------
4253 
4255 {
4256  XclAddress aXclPos;
4257  rStrm >> aXclPos;
4258  sal_uInt16 nTotalLen = rStrm.ReaduInt16();
4259 
4260  ScAddress aScNotePos( ScAddress::UNINITIALIZED );
4261  if( !GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
4262  return;
4263 
4264  sal_uInt16 nPartLen = ::std::min( nTotalLen, static_cast< sal_uInt16 >( rStrm.GetRecLeft() ) );
4265  OUStringBuffer aNoteText = rStrm.ReadRawByteString( nPartLen );
4266  nTotalLen = nTotalLen - nPartLen;
4267  while (true)
4268  {
4269  if (!nTotalLen)
4270  break;
4271  if (rStrm.GetNextRecId() != EXC_ID_NOTE)
4272  break;
4273  if (!rStrm.StartNextRecord())
4274  break;
4275  rStrm >> aXclPos;
4276  nPartLen = rStrm.ReaduInt16();
4277  OSL_ENSURE( aXclPos.mnRow == 0xFFFF, "XclImpObjectManager::ReadNote3 - missing continuation NOTE record" );
4278  if( aXclPos.mnRow == 0xFFFF )
4279  {
4280  OSL_ENSURE( nPartLen <= nTotalLen, "XclImpObjectManager::ReadNote3 - string too long" );
4281  aNoteText.append(rStrm.ReadRawByteString( nPartLen ));
4282  nTotalLen = nTotalLen - ::std::min( nTotalLen, nPartLen );
4283  }
4284  else
4285  {
4286  // seems to be a new note, record already started -> load the note
4287  rStrm.Seek( EXC_REC_SEEK_TO_BEGIN );
4288  ReadNote( rStrm );
4289  nTotalLen = 0;
4290  }
4291  }
4292  ScNoteUtil::CreateNoteFromString( GetDoc(), aScNotePos, aNoteText.makeStringAndClear(), false, false );
4293 }
4294 
4296 {
4297  XclAddress aXclPos;
4298  sal_uInt16 nFlags, nObjId;
4299  rStrm >> aXclPos;
4300  nFlags = rStrm.ReaduInt16();
4301  nObjId = rStrm.ReaduInt16();
4302 
4303  ScAddress aScNotePos( ScAddress::UNINITIALIZED );
4304  if( GetAddressConverter().ConvertAddress( aScNotePos, aXclPos, maScUsedArea.aStart.Tab(), true ) )
4305  if( nObjId != EXC_OBJ_INVALID_ID )
4306  if( XclImpNoteObj* pNoteObj = dynamic_cast< XclImpNoteObj* >( FindDrawObj( nObjId ).get() ) )
4307  pNoteObj->SetNoteData( aScNotePos, nFlags );
4308 }
4309 
4310 // The object manager =========================================================
4311 
4313  XclImpRoot( rRoot )
4314 {
4315  maDefObjNames[ EXC_OBJTYPE_GROUP ] = "Group";
4316  maDefObjNames[ EXC_OBJTYPE_LINE ] = ScResId( STR_SHAPE_LINE );
4317  maDefObjNames[ EXC_OBJTYPE_RECTANGLE ] = ScResId( STR_SHAPE_RECTANGLE );
4318  maDefObjNames[ EXC_OBJTYPE_OVAL ] = ScResId( STR_SHAPE_OVAL );
4319  maDefObjNames[ EXC_OBJTYPE_ARC ] = "Arc";
4320  maDefObjNames[ EXC_OBJTYPE_CHART ] = "Chart";
4321  maDefObjNames[ EXC_OBJTYPE_TEXT ] = "Text";
4322  maDefObjNames[ EXC_OBJTYPE_BUTTON ] = ScResId( STR_FORM_BUTTON );
4323  maDefObjNames[ EXC_OBJTYPE_PICTURE ] = "Picture";
4324  maDefObjNames[ EXC_OBJTYPE_POLYGON ] = "Freeform";
4325  maDefObjNames[ EXC_OBJTYPE_CHECKBOX ] = ScResId( STR_FORM_CHECKBOX );
4326  maDefObjNames[ EXC_OBJTYPE_OPTIONBUTTON ] = ScResId( STR_FORM_OPTIONBUTTON );
4327  maDefObjNames[ EXC_OBJTYPE_EDIT ] = "Edit Box";
4328  maDefObjNames[ EXC_OBJTYPE_LABEL ] = ScResId( STR_FORM_LABEL );
4329  maDefObjNames[ EXC_OBJTYPE_DIALOG ] = "Dialog Frame";
4330  maDefObjNames[ EXC_OBJTYPE_SPIN ] = ScResId( STR_FORM_SPINNER );
4331  maDefObjNames[ EXC_OBJTYPE_SCROLLBAR ] = ScResId( STR_FORM_SCROLLBAR );
4332  maDefObjNames[ EXC_OBJTYPE_LISTBOX ] = ScResId( STR_FORM_LISTBOX );
4333  maDefObjNames[ EXC_OBJTYPE_GROUPBOX ] = ScResId( STR_FORM_GROUPBOX );
4334  maDefObjNames[ EXC_OBJTYPE_DROPDOWN ] = ScResId( STR_FORM_DROPDOWN );
4335  maDefObjNames[ EXC_OBJTYPE_NOTE ] = "Comment";
4336  maDefObjNames[ EXC_OBJTYPE_DRAWING ] = ScResId( STR_SHAPE_AUTOSHAPE );
4337 }
4338 
4340 {
4341 }
4342 
4344 {
4346  // Excel continues this record with MSODRAWINGGROUP and CONTINUE records, hmm.
4347  rStrm.ResetRecord( true, EXC_ID_MSODRAWINGGROUP );
4349  rStrm.CopyRecordToStream( maDggStrm );
4350 }
4351 
4353 {
4354  XclImpSheetDrawingRef& rxDrawing = maSheetDrawings[ nScTab ];
4355  if( !rxDrawing )
4356  rxDrawing = std::make_shared<XclImpSheetDrawing>( GetRoot(), nScTab );
4357  return *rxDrawing;
4358 }
4359 
4361 {
4362  // do nothing if the document does not contain a drawing layer
4363  if( !GetDoc().GetDrawLayer() )
4364  return;
4365 
4366  // get total progress bar size for all sheet drawing managers
4367  std::size_t nProgressSize = std::accumulate(maSheetDrawings.begin(), maSheetDrawings.end(), std::size_t(0),
4368  [](const std::size_t& rSum, const XclImpSheetDrawingMap::value_type& rEntry) { return rSum + rEntry.second->GetProgressSize(); });
4369  // nothing to do if progress bar is zero (no objects present)
4370  if( nProgressSize == 0 )
4371  return;
4372 
4373  XclImpDffConverter aDffConv( GetRoot(), maDggStrm );
4374  aDffConv.StartProgressBar( nProgressSize );
4375  for( auto& rEntry : maSheetDrawings )
4376  rEntry.second->ConvertObjects( aDffConv );
4377 
4378  // #i112436# don't call ScChartListenerCollection::SetDirty here,
4379  // instead use InterpretDirtyCells in ScDocument::CalcAfterLoad.
4380 }
4381 
4383 {
4384  OUStringBuffer aDefName;
4385  DefObjNameMap::const_iterator aIt = maDefObjNames.find( rDrawObj.GetObjType() );
4386  if( aIt != maDefObjNames.end() )
4387  aDefName.append(aIt->second);
4388  return aDefName.append(' ').append(static_cast<sal_Int32>(rDrawObj.GetObjId())).makeStringAndClear();
4389 }
4390 
4392 {
4393  XclImpSheetDrawingMap::const_iterator aIt = maSheetDrawings.find( nScTab );
4394  if( aIt != maSheetDrawings.end() )
4395  return aIt->second->GetUsedArea();
4397 }
4398 
4399 // DFF property set helper ====================================================
4400 
4402  XclImpRoot( rRoot ),
4403  maDffConv( rRoot, maDummyStrm )
4404 {
4405 }
4406 
4408 {
4409  sal_uInt32 nPropSetSize;
4410 
4411  rStrm.PushPosition();
4412  rStrm.Ignore( 4 );
4413  nPropSetSize = rStrm.ReaduInt32();
4414  rStrm.PopPosition();
4415 
4416  mxMemStrm.reset( new SvMemoryStream );
4417  rStrm.CopyToStream( *mxMemStrm, 8 + nPropSetSize );
4419  maDffConv.ReadPropSet( *mxMemStrm, nullptr );
4420 }
4421 
4422 sal_uInt32 XclImpDffPropSet::GetPropertyValue( sal_uInt16 nPropId ) const
4423 {
4424  return maDffConv.GetPropertyValue( nPropId, 0 );
4425 }
4426 
4428 {
4429  if( mxMemStrm )
4430  maDffConv.ApplyAttributes( *mxMemStrm, rItemSet );
4431 }
4432 
4434 {
4435  rPropSet.Read( rStrm );
4436  return rStrm;
4437 }
4438 
4439 /* 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:3357
OUString ReadRawByteString(sal_uInt16 nChars)
Reads nChar byte characters and returns the string.
Definition: xistream.cxx:949
void ProcessObject(SdrObjList &rObjList, XclImpDrawObjBase &rDrawObj)
Processes BIFF5 drawing objects without DFF data, inserts into the passed object list.
Definition: xiescher.cxx:3377
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:2841
double mfRightMargin
Left margin in inches.
Definition: xlpage.hxx:112
bool is() const
void ConvertLabel(ScfPropertySet &rPropSet) const
Sets control label and text formatting.
Definition: xiescher.cxx:2097
sal_Int32 mnRight
void ReadFullLbsData(XclImpStream &rStrm)
Reads dropdown box settings.
Definition: xiescher.cxx:2828
std::size_t GetProgressSize() const
Returns the needed size on the progress bar for all contained objects.
Definition: xiescher.cxx:990
virtual SdrObjectUniquePtr DoCreateSdrObj(XclImpDffConverter &rDffConv, const tools::Rectangle &rAnchorRect) const override
Creates and returns a new SdrObject from the contained data.
Definition: xiescher.cxx:1047
SdrMetricItem makeSdrTextUpperDistItem(tools::Long mnHeight)
XclImpObjTextData maTextData
Definition: xiescher.hxx:398
#define DBG_ERROR_BIFF()
Definition: xltools.hxx:33
void SetPixelColor(const Color &rColor)
XclImpDropDownObj(const XclImpRoot &rRoot)
Definition: xiescher.cxx:2811
#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:3289
OBJ_PATHPOLY
OUString ReadHlinkProperty(SvStream &rDffStrm) const
Reads contents of a hyperlink property and returns the extracted URL.
Definition: xiescher.cxx:3763
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:996
bool SupportsOleObjects() const
Returns true, if the conversion of OLE objects is supported.
Definition: xiescher.cxx:3547
#define DFF_Prop_fFilled
SDRTEXTVERTADJUST_TOP
const sal_uInt16 EXC_ID_OBJSBS
Radio button group data.
Definition: xlescher.hxx:215
sal_uInt16 GetNextRecId()
Returns the record ID of the following record.
Definition: xistream.cxx:587
Helper base class for TBX and OCX form controls to manage spreadsheet links.
Definition: xiescher.hxx:457
SdrMetricItem makeSdrShadowYDistItem(tools::Long nDist)
void Seek(std::size_t nPos)
Seeks absolute in record content to the specified position.
Definition: xistream.cxx:781
sal_Int32 nIndex
Drawing manager of a single sheet.
Definition: xiescher.hxx:1110
void append(const basegfx::B2DPoint &rPoint, sal_uInt32 nCount)
virtual void DoReadObj8SubRec(XclImpStream &rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize) override
Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream.
Definition: xiescher.cxx:2437
const sal_uInt8 EXC_OBJ_LINE_MEDTRANS
Definition: xlescher.hxx:86
bool IsProcessSdrObj() const
Returns true, if the object is valid and will be processed.
Definition: xiescher.hxx:117
A note object, which is a specialized text box object.
Definition: xiescher.hxx:439
const sal_uInt8 EXC_OBJ_LINE_BL
Definition: xlescher.hxx:111
const sal_uInt16 EXC_ID_OBJEND
Definition: xlescher.hxx:206
XclImpButtonObj(const XclImpRoot &rRoot)
Definition: xiescher.cxx:2140
ScAddress aStart
Definition: address.hxx:499
const sal_uInt16 EXC_OBJ_POLY_CLOSED
Definition: xlescher.hxx:149
void SetDffData(const DffObjData &rDffObjData, const OUString &rObjName, const OUString &rHyperlink, bool bVisible, bool bAutoMargin)
Sets shape data from DFF stream.
Definition: xiescher.cxx:380
const sal_uInt16 EXC_OBJ_ORIENT_90CCW
Stacked top to bottom.
Definition: xlescher.hxx:134
bool bVisible
virtual XclTbxEventType DoGetEventType() const override
Returns the type of the macro event to be created.
Definition: xiescher.cxx:2462
virtual void DoProcessControl(ScfPropertySet &rPropSet) const override
Sets additional properties for the current form control.
Definition: xiescher.cxx:2872
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:2046
const OUString & GetMacroName() const
Returns associated macro name, if set, otherwise zero length string.
Definition: xiescher.hxx:95
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:104
std::size_t GetRecPos() const
Returns the position inside of the whole record content.
Definition: xistream.cxx:564
sal_uInt16 mnFormatSize
Definition: xlescher.hxx:383
#define EMPTY_OUSTRING
Definition: global.hxx:213
ReturnType get_flagvalue(Type nBitField, Type nMask, ReturnType nSet, ReturnType nUnset)
Returns nSet, if at least one bit of nMask is set in nBitField, otherwise nUnset. ...
Definition: ftools.hxx:80
css::uno::Reference< css::embed::XEmbeddedObject > const & GetObjRef() const
sal_uInt32 nShapeId
bool SeekToContent(sal_uInt32 nRecType, SvStream &rSt) const
virtual SdrObject * FinalizeObj(DffObjData &rDffObjData, SdrObject *pOldSdrObj) override
Finalize a DFF object, sets anchor after nested objs have been loaded.
Definition: xiescher.cxx:3694
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:2320
SvStream & WriteUInt16(sal_uInt16 nUInt16)
static sal_Int32 GetHmmFromInch(double fInches)
Returns the length in 1/100 mm calculated from a length in inches.
Definition: xltools.cxx:297
bool IsMathType2Math() const
static SdrOle2Obj * CreateSdrOLEFromStorage(SdrModel &rSdrModel, const OUString &rStorageName, tools::SvRef< SotStorage > const &rSrcStorage, const css::uno::Reference< css::embed::XStorage > &xDestStg, const Graphic &rGraf, const tools::Rectangle &rBoundRect, const tools::Rectangle &rVisArea, SvStream *pDataStrrm, ErrCode &rError, sal_uInt32 nConvertFlags, sal_Int64 nAspect, OUString const &rBaseURL)
sal_uInt16 GetRecId() const
Returns the current record ID.
Definition: xistream.hxx:353
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
const sal_uInt16 EXC_OBJTYPE_UNKNOWN
Definition: xlescher.hxx:71
SCROW Row() const
Definition: address.hxx:261
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:2301
const XclImpRoot & mrRoot
Definition: xiescher.hxx:494
const std::size_t EXC_REC_SEEK_TO_BEGIN
Definition: xlstream.hxx:26
virtual XclTbxEventType DoGetEventType() const override
Returns the type of the macro event to be created.
Definition: xiescher.cxx:2640
virtual void DoPreProcessSdrObj(XclImpDffConverter &rDffConv, SdrObject &rSdrObj) const override
Inserts the contained text data at the passed object.
Definition: xiescher.cxx:1496
sal_uInt16 mnOrient
Definition: xlescher.hxx:387
const sal_uInt16 EXC_OBJ_PIC_CONTROL
Definition: xlescher.hxx:155
sal_uInt8 mnPattern
Definition: xlescher.hxx:369
virtual void DoProcessControl(ScfPropertySet &rPropSet) const override
Sets additional properties for the current form control.
Definition: xiescher.cxx:2472
const sal_uInt16 EXC_ID_NOTE
Definition: xlescher.hxx:38
void FinalizeTabChart()
Calculates the object anchor of a sheet chart (chart fills one page).
Definition: xiescher.cxx:1801
const sal_uInt16 EXC_OBJ_EDIT_INTEGER
Definition: xlescher.hxx:173
Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
const sal_uInt16 EXC_OBJ_ORIENT_NONE
Definition: xlescher.hxx:132
sal_uInt16 mnRX
Y offset in top row (1/256 of row height).
Definition: xlescher.hxx:287
void SetName(const OUString &rStr, const bool bSetChanged=true)
virtual std::size_t DoGetProgressSize() const override
Returns a progress bar size that takes all group children into account.
Definition: xiescher.cxx:1042
const Color & GetBackgroundColor() const
std::shared_ptr< ScRange > mxSrcRange
Not derived from XclImpRoot to allow multiple inheritance.
Definition: xiescher.hxx:495
const sal_uInt16 EXC_OBJ_PIC_SYMBOL
Definition: xlescher.hxx:154
const sal_uInt8 EXC_TOKCLASS_REF
00-1F: Base tokens.
Definition: xlformula.hxx:43
bool ReadWindowMetafile(SvStream &rStream, GDIMetaFile &rMTF)
virtual void DoPreProcessSdrObj(XclImpDffConverter &rDffConv, SdrObject &rSdrObj) const override
Inserts the note into the document, sets visibility.
Definition: xiescher.cxx:1851
void SetPersistName(const OUString &rPersistName)
virtual void DoProcessControl(ScfPropertySet &rPropSet) const override
Sets additional properties for the current form control.
Definition: xiescher.cxx:2145
const sal_uInt8 EXC_OBJ_ARC_BL
Definition: xlescher.hxx:145
const sal_uInt16 EXC_ID_TXO
Definition: xlescher.hxx:276
const sal_uInt16 EXC_OBJ_INVALID_ID
Definition: xlescher.hxx:46
#define DFF_Prop_AutoTextMargin
MSO_Anchor
XclImpSpinButtonObj(const XclImpRoot &rRoot)
Definition: xiescher.cxx:2608
XclImpLineObj(const XclImpRoot &rRoot)
Definition: xiescher.cxx:1060
sal_Int32 GetDefaultTextMargin() const
Returns the default text margin in drawing layer units.
Definition: xiescher.hxx:950
virtual SdrObject * ProcessObj(SvStream &rDffStrm, DffObjData &rDffObjData, SvxMSDffClientData &rClientData, tools::Rectangle &rTextRect, SdrObject *pOldSdrObj) override
Processes a DFF object, reads properties from DFF stream.
Definition: xiescher.cxx:3594
const sal_uInt16 EXC_ID_OBJPICTFMLA
Option flags.
Definition: xlescher.hxx:212
virtual sal_uInt64 TellEnd()
void NotifyMacroEventRead()
Notify that this document contains a macro event handler.
Definition: xiescher.cxx:3427
sal_uInt16 mnContentType
Definition: xiescher.hxx:663
virtual void DoReadObj8SubRec(XclImpStream &rStrm, sal_uInt16 nSubRecId, sal_uInt16 nSubRecSize) override
Reads the contents of the specified subrecord of a BIFF8 OBJ record from stream.
Definition: xiescher.cxx:1727
XclImpNoteObj(const XclImpRoot &rRoot)
Definition: xiescher.cxx:1835
void RewindRecord()
Sets stream pointer before current record and invalidates stream.
Definition: xistream.cxx:501
static ScMacroInfo * GetMacroInfo(SdrObject *pObj, bool bCreate=false)
Definition: drwlayer.cxx:2630
XclImpObjMap maObjMap
Copy of the DFF page stream in memory.
Definition: xiescher.hxx:1102
void PostProcessSdrObject(XclImpDffConverter &rDffConv, SdrObject &rSdrObj) const
Additional processing for the passed SdrObject after insertion into the drawing page (calls virtual D...
Definition: xiescher.cxx:565
sal_uIntPtr sal_uLong
long Long
XclImpChartObj(const XclImpRoot &rRoot, bool bOwnTab=false)
Definition: xiescher.cxx:1647
sal_uInt16 mnSelEntry
Definition: xiescher.hxx:741
XclImpTextObj(const XclImpRoot &rRoot)
Definition: xiescher.cxx:1445
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
A group object.
Definition: xiescher.hxx:237
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:259
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:2956
OBJ_LINE
XclImpListBoxObj(const XclImpRoot &rRoot)
Definition: xiescher.cxx:2718
const sal_uInt16 EXC_OBJ_SCROLLBAR_HOR
Definition: xlescher.hxx:182
constexpr::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
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:1878
Base class for textbox based form controls.
Definition: xiescher.hxx:500
const sal_uInt16 EXC_ID_OBJCMO
Check box/radio button cell link.
Definition: xlescher.hxx:224
std::shared_ptr< XclImpDffConvData > XclImpDffConvDataRef
Definition: xiescher.hxx:1027