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