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