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