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