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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_sw.hxx" 24 #include <hintids.hxx> 25 #include <vcl/salbtype.hxx> // FRound 26 #include <tools/urlobj.hxx> 27 #include <svl/undo.hxx> 28 #ifndef SVTOOLS_FSTATHELPER_HXX 29 #include <svl/fstathelper.hxx> 30 #endif 31 #include <svtools/imap.hxx> 32 #include <svtools/filter.hxx> 33 #include <sot/storage.hxx> 34 #include <sfx2/linkmgr.hxx> 35 #include <editeng/boxitem.hxx> 36 #include <sot/formats.hxx> 37 #include <fmtfsize.hxx> 38 #include <fmturl.hxx> 39 #include <frmfmt.hxx> 40 #include <doc.hxx> 41 #include <frmatr.hxx> 42 #include <grfatr.hxx> 43 #include <swtypes.hxx> 44 #include <ndgrf.hxx> 45 #include <fmtcol.hxx> 46 #include <hints.hxx> 47 #include <swbaslnk.hxx> 48 #include <pagefrm.hxx> 49 #include <editsh.hxx> 50 #include <pam.hxx> 51 52 #include <unotools/ucbstreamhelper.hxx> 53 #include <com/sun/star/embed/ElementModes.hpp> 54 #include <com/sun/star/embed/XTransactedObject.hpp> 55 #include <tools/link.hxx> 56 #include <vcl/svapp.hxx> 57 #include <com/sun/star/io/XSeekable.hpp> 58 #include <retrieveinputstreamconsumer.hxx> 59 #include <drawinglayer/processor2d/objectinfoextractor2d.hxx> 60 #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx> 61 #include <unotools/cacheoptions.hxx> 62 63 using namespace com::sun::star; 64 65 #define SWAPGRAPHIC_TIMEOUT 5000 66 67 // For comments see same method used in svx 68 sal_uInt32 getCacheTimeInMs() 69 { 70 static bool bSetAtAll(true); 71 72 if(bSetAtAll) 73 { 74 static bool bSetToPreferenceTime(true); 75 76 if(bSetToPreferenceTime) 77 { 78 const SvtCacheOptions aCacheOptions; 79 const sal_Int32 nSeconds(aCacheOptions.GetGraphicManagerObjectReleaseTime()); 80 81 return nSeconds * 1000 / 12; 82 } 83 else 84 { 85 return SWAPGRAPHIC_TIMEOUT; 86 } 87 } 88 89 return 0; 90 } 91 92 // -------------------- 93 // SwGrfNode 94 // -------------------- 95 SwGrfNode::SwGrfNode( 96 const SwNodeIndex & rWhere, 97 const String& rGrfName, 98 const String& rFltName, 99 const Graphic* pGraphic, 100 SwGrfFmtColl *pGrfColl, 101 SwAttrSet* pAutoAttr ) 102 : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ), 103 maGrfObj(), 104 mpReplacementGraphic( 0 ), 105 mbLinkedInputStreamReady( false ), 106 mbIsStreamReadOnly( sal_False ) 107 { 108 maGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ), getCacheTimeInMs() ); 109 bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf = bFrameInPaint = bScaleImageMap = sal_False; 110 111 bGrafikArrived = sal_True; 112 ReRead( rGrfName, rFltName, pGraphic, 0, sal_False ); 113 } 114 115 SwGrfNode::SwGrfNode( 116 const SwNodeIndex & rWhere, 117 const GraphicObject& rGrfObj, 118 SwGrfFmtColl *pGrfColl, 119 SwAttrSet* pAutoAttr ) 120 : SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ), 121 maGrfObj( rGrfObj ), 122 mpReplacementGraphic( 0 ), 123 mbLinkedInputStreamReady( false ), 124 mbIsStreamReadOnly( sal_False ) 125 { 126 maGrfObj = rGrfObj; 127 maGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ), getCacheTimeInMs() ); 128 if ( rGrfObj.HasUserData() && rGrfObj.IsSwappedOut() ) 129 maGrfObj.SetSwapState(); 130 bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf = bFrameInPaint = bScaleImageMap = sal_False; 131 bGrafikArrived = sal_True; 132 } 133 134 // Konstruktor fuer den SW/G-Reader. Dieser ctor wird verwendet, 135 // wenn eine gelinkte Grafik gelesen wird. Sie liest diese NICHT ein. 136 137 SwGrfNode::SwGrfNode( 138 const SwNodeIndex & rWhere, 139 const String& rGrfName, 140 const String& rFltName, 141 SwGrfFmtColl *pGrfColl, 142 SwAttrSet* pAutoAttr ) 143 : 144 SwNoTxtNode( rWhere, ND_GRFNODE, pGrfColl, pAutoAttr ), 145 maGrfObj(), 146 mpReplacementGraphic( 0 ), 147 mbLinkedInputStreamReady( false ), 148 mbIsStreamReadOnly( sal_False ) 149 { 150 maGrfObj.SetSwapStreamHdl( LINK( this, SwGrfNode, SwapGraphic ), getCacheTimeInMs() ); 151 152 Graphic aGrf; 153 aGrf.SetDefaultType(); 154 maGrfObj.SetGraphic( aGrf, rGrfName ); 155 156 bInSwapIn = bChgTwipSize = bChgTwipSizeFromPixel = bLoadLowResGrf = 157 bFrameInPaint = bScaleImageMap = sal_False; 158 bGrafikArrived = sal_True; 159 160 InsertLink( rGrfName, rFltName ); 161 if ( IsLinkedFile() ) 162 { 163 INetURLObject aUrl( rGrfName ); 164 if ( INET_PROT_FILE == aUrl.GetProtocol() && 165 FStatHelper::IsDocument( aUrl.GetMainURL( INetURLObject::NO_DECODE ) ) ) 166 { 167 // File vorhanden, Verbindung herstellen ohne ein Update 168 ( (SwBaseLink*) &refLink )->Connect(); 169 } 170 } 171 } 172 173 sal_Bool SwGrfNode::ReRead( 174 const String& rGrfName, 175 const String& rFltName, 176 const Graphic* pGraphic, 177 const GraphicObject* pGrfObj, 178 sal_Bool bNewGrf ) 179 { 180 sal_Bool bReadGrf = sal_False, bSetTwipSize = sal_True; 181 delete mpReplacementGraphic; 182 mpReplacementGraphic = 0; 183 184 ASSERT( pGraphic || pGrfObj || rGrfName.Len(), 185 "GraphicNode without a name, Graphic or GraphicObject" ); 186 187 if ( GetDoc()->GetLinkManager().urlIsVendor( rGrfName ) ) 188 return sal_False; 189 190 // ReadRead mit Namen 191 if ( refLink.Is() ) 192 { 193 ASSERT( !bInSwapIn, "ReRead: stehe noch im SwapIn" ); 194 195 if ( rGrfName.Len() ) 196 { 197 // Besonderheit: steht im FltNamen DDE, handelt es sich um eine 198 // DDE-gelinkte Grafik 199 String sCmd( rGrfName ); 200 if ( rFltName.Len() ) 201 { 202 sal_uInt16 nNewType; 203 if ( rFltName.EqualsAscii( "DDE" ) ) 204 nNewType = OBJECT_CLIENT_DDE; 205 else 206 { 207 sfx2::MakeLnkName( sCmd, 0, rGrfName, aEmptyStr, &rFltName ); 208 nNewType = OBJECT_CLIENT_GRF; 209 } 210 211 if ( nNewType != refLink->GetObjType() ) 212 { 213 refLink->Disconnect(); 214 ( (SwBaseLink*) &refLink )->SetObjType( nNewType ); 215 } 216 } 217 218 refLink->SetLinkSourceName( sCmd ); 219 } 220 else // kein Name mehr, Link aufheben 221 { 222 GetDoc()->GetLinkManager().Remove( refLink ); 223 refLink.Clear(); 224 } 225 226 if ( pGraphic ) 227 { 228 maGrfObj.SetGraphic( *pGraphic, rGrfName ); 229 onGraphicChanged(); 230 bReadGrf = sal_True; 231 } 232 else if ( pGrfObj ) 233 { 234 maGrfObj = *pGrfObj; 235 if ( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() ) 236 maGrfObj.SetSwapState(); 237 maGrfObj.SetLink( rGrfName ); 238 onGraphicChanged(); 239 bReadGrf = sal_True; 240 } 241 else 242 { 243 // MIB 25.02.97: Daten der alten Grafik zuruecksetzen, damit 244 // die korrekte Ersatz-Darstellung erscheint, wenn die 245 // der neue Link nicht geladen werden konnte. 246 Graphic aGrf; 247 aGrf.SetDefaultType(); 248 maGrfObj.SetGraphic( aGrf, rGrfName ); 249 250 if ( refLink.Is() ) 251 { 252 if ( getLayoutFrm( GetDoc()->GetCurrentLayout() ) ) 253 { 254 SwMsgPoolItem aMsgHint( RES_GRF_REREAD_AND_INCACHE ); 255 ModifyNotification( &aMsgHint, &aMsgHint ); 256 } 257 else if ( bNewGrf ) 258 { 259 //TODO refLink->setInputStream(getInputStream()); 260 ( (SwBaseLink*) &refLink )->SwapIn(); 261 } 262 } 263 onGraphicChanged(); 264 bSetTwipSize = sal_False; 265 } 266 } 267 else if ( pGraphic && !rGrfName.Len() ) 268 { 269 // MIB 27.02.2001: Old stream must be deleted before the new one is set. 270 if ( HasEmbeddedStreamName() ) 271 DelStreamName(); 272 273 maGrfObj.SetGraphic( *pGraphic ); 274 onGraphicChanged(); 275 bReadGrf = sal_True; 276 } 277 else if ( pGrfObj && !rGrfName.Len() ) 278 { 279 // MIB 27.02.2001: Old stream must be deleted before the new one is set. 280 if ( HasEmbeddedStreamName() ) 281 DelStreamName(); 282 283 maGrfObj = *pGrfObj; 284 onGraphicChanged(); 285 if ( pGrfObj->HasUserData() && pGrfObj->IsSwappedOut() ) 286 maGrfObj.SetSwapState(); 287 bReadGrf = sal_True; 288 } 289 else if ( !bNewGrf && GRAPHIC_NONE != maGrfObj.GetType() ) 290 return sal_True; 291 292 else 293 { 294 if ( HasEmbeddedStreamName() ) 295 DelStreamName(); 296 297 // einen neuen Grafik-Link anlegen 298 InsertLink( rGrfName, rFltName ); 299 300 if ( GetNodes().IsDocNodes() ) 301 { 302 if ( pGraphic ) 303 { 304 maGrfObj.SetGraphic( *pGraphic, rGrfName ); 305 onGraphicChanged(); 306 bReadGrf = sal_True; 307 // Verbindung herstellen ohne ein Update; Grafik haben wir! 308 ( (SwBaseLink*) &refLink )->Connect(); 309 } 310 else if ( pGrfObj ) 311 { 312 maGrfObj = *pGrfObj; 313 maGrfObj.SetLink( rGrfName ); 314 onGraphicChanged(); 315 bReadGrf = sal_True; 316 // Verbindung herstellen ohne ein Update; Grafik haben wir! 317 ( (SwBaseLink*) &refLink )->Connect(); 318 } 319 else 320 { 321 Graphic aGrf; 322 aGrf.SetDefaultType(); 323 maGrfObj.SetGraphic( aGrf, rGrfName ); 324 onGraphicChanged(); 325 if ( bNewGrf ) 326 { 327 ( (SwBaseLink*) &refLink )->SwapIn(); 328 } 329 } 330 } 331 } 332 333 // Bug 39281: Size nicht sofort loeschen - Events auf ImageMaps 334 // sollten nicht beim Austauschen nicht ins "leere greifen" 335 if ( bSetTwipSize ) 336 SetTwipSize( ::GetGraphicSizeTwip( maGrfObj.GetGraphic(), 0 ) ); 337 338 // erzeuge noch einen Update auf die Frames 339 if ( bReadGrf && bNewGrf ) 340 { 341 SwMsgPoolItem aMsgHint( RES_UPDATE_ATTR ); 342 ModifyNotification( &aMsgHint, &aMsgHint ); 343 } 344 345 return bReadGrf; 346 } 347 348 SwGrfNode::~SwGrfNode() 349 { 350 delete mpReplacementGraphic; 351 mpReplacementGraphic = 0; 352 353 mpThreadConsumer.reset(); 354 355 SwDoc* pDoc = GetDoc(); 356 if ( refLink.Is() ) 357 { 358 ASSERT( !bInSwapIn, "DTOR: stehe noch im SwapIn" ); 359 pDoc->GetLinkManager().Remove( refLink ); 360 refLink->Disconnect(); 361 } 362 else 363 { 364 // #i40014# - A graphic node, which are in linked 365 // section, whose link is another section is the document, doesn't 366 // have to remove the stream from the storage. 367 // Because it's hard to detect this case here and it would only fix 368 // one problem with shared graphic files - there are also problems, 369 // a certain graphic file is referenced by two independent graphic nodes, 370 // brush item or drawing objects, the stream isn't no longer removed here. 371 // To do this stuff correct, a reference counting on shared streams 372 // inside one document have to be implemented. 373 // if( !pDoc->IsInDtor() && HasStreamName() ) 374 // DelStreamName(); 375 } 376 //#39289# Die Frames muessen hier bereits geloescht weil der DTor der 377 //Frms die Grafik noch fuer StopAnimation braucht. 378 if ( GetDepends() ) 379 DelFrms(); 380 } 381 382 /// allow reaction on change of content of GraphicObject 383 void SwGrfNode::onGraphicChanged() 384 { 385 // try to access SwFlyFrmFmt; since title/desc/name are set there, there is no 386 // use to continue if it is not yet set. If not yet set, call onGraphicChanged() 387 // when it is set. 388 SwFlyFrmFmt* pFlyFmt = dynamic_cast< SwFlyFrmFmt* >( GetFlyFmt() ); 389 390 if ( pFlyFmt != NULL ) 391 { 392 const bool bWasSwappedOut = ( GetGrfObj().IsSwappedOut() == sal_True ); 393 394 String aName; 395 String aTitle; 396 String aDesc; 397 const SvgDataPtr& rSvgDataPtr = GetGrf().getSvgData(); 398 399 if ( rSvgDataPtr.get() ) 400 { 401 const drawinglayer::primitive2d::Primitive2DSequence aSequence( rSvgDataPtr->getPrimitive2DSequence() ); 402 403 if ( aSequence.hasElements() ) 404 { 405 drawinglayer::geometry::ViewInformation2D aViewInformation2D; 406 drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor( aViewInformation2D ); 407 408 aProcessor.process( aSequence ); 409 410 const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult(); 411 412 if ( pResult ) 413 { 414 aName = pResult->getName(); 415 aTitle = pResult->getTitle(); 416 aDesc = pResult->getDesc(); 417 } 418 } 419 } 420 421 if ( aTitle.Len() > 0 ) 422 { 423 SetTitle( aTitle ); 424 } 425 else if ( aName.Len() > 0 ) 426 { 427 SetTitle( aName ); 428 } 429 430 if ( aDesc.Len() > 0 ) 431 { 432 SetDescription( aDesc ); 433 } 434 435 if ( bWasSwappedOut ) 436 { 437 SwapOut(); 438 } 439 } 440 } 441 442 void SwGrfNode::SetGraphic( 443 const Graphic& rGraphic, 444 const String& rLink ) 445 { 446 maGrfObj.SetGraphic( rGraphic, rLink ); 447 onGraphicChanged(); 448 } 449 450 const GraphicObject* SwGrfNode::GetReplacementGrfObj() const 451 { 452 if ( !mpReplacementGraphic ) 453 { 454 const SvgDataPtr& rSvgDataPtr = GetGrfObj().GetGraphic().getSvgData(); 455 456 if ( rSvgDataPtr.get() ) 457 { 458 const_cast< SwGrfNode* >( this )->mpReplacementGraphic = new GraphicObject( rSvgDataPtr->getReplacement() ); 459 } 460 } 461 462 return mpReplacementGraphic; 463 } 464 465 SwCntntNode *SwGrfNode::SplitCntntNode( 466 const SwPosition & ) 467 { 468 return this; 469 } 470 471 SwGrfNode * SwNodes::MakeGrfNode( 472 const SwNodeIndex & rWhere, 473 const String& rGrfName, 474 const String& rFltName, 475 const Graphic* pGraphic, 476 SwGrfFmtColl* pGrfColl, 477 SwAttrSet* pAutoAttr, 478 sal_Bool bDelayed ) 479 { 480 ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." ); 481 SwGrfNode *pNode; 482 // Delayed erzeugen nur aus dem SW/G-Reader 483 if ( bDelayed ) 484 pNode = new SwGrfNode( rWhere, rGrfName, 485 rFltName, pGrfColl, pAutoAttr ); 486 else 487 pNode = new SwGrfNode( rWhere, rGrfName, 488 rFltName, pGraphic, pGrfColl, pAutoAttr ); 489 return pNode; 490 } 491 492 SwGrfNode * SwNodes::MakeGrfNode( 493 const SwNodeIndex & rWhere, 494 const GraphicObject& rGrfObj, 495 SwGrfFmtColl* pGrfColl, 496 SwAttrSet* pAutoAttr ) 497 { 498 ASSERT( pGrfColl, "MakeGrfNode: Formatpointer ist 0." ); 499 return new SwGrfNode( rWhere, rGrfObj, pGrfColl, pAutoAttr ); 500 } 501 502 Size SwGrfNode::GetTwipSize() const 503 { 504 return nGrfSize; 505 } 506 507 sal_Bool SwGrfNode::ImportGraphic( 508 SvStream& rStrm ) 509 { 510 Graphic aGraphic; 511 const String aURL( maGrfObj.GetUserData() ); 512 513 if ( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, aURL, rStrm ) ) 514 { 515 delete mpReplacementGraphic; 516 mpReplacementGraphic = 0; 517 518 maGrfObj.SetGraphic( aGraphic ); 519 maGrfObj.SetUserData( aURL ); 520 onGraphicChanged(); 521 return sal_True; 522 } 523 524 return sal_False; 525 } 526 527 // Returnwert: 528 // -1 : ReRead erfolgreich 529 // 0 : nicht geladen 530 // 1 : Einlesen erfolgreich 531 532 short SwGrfNode::SwapIn( 533 sal_Bool bWaitForData ) 534 { 535 if ( bInSwapIn ) // nicht rekuriv!! 536 return !maGrfObj.IsSwappedOut(); 537 538 short nRet = 0; 539 bInSwapIn = sal_True; 540 SwBaseLink* pLink = (SwBaseLink*) (::sfx2::SvBaseLink*) refLink; 541 542 if ( pLink ) 543 { 544 if ( GRAPHIC_NONE == maGrfObj.GetType() || 545 GRAPHIC_DEFAULT == maGrfObj.GetType() ) 546 { 547 // noch nicht geladener Link 548 //TODO pLink->setInputStream(getInputStream()); 549 if ( pLink->SwapIn( bWaitForData ) ) 550 nRet = -1; 551 else if ( GRAPHIC_DEFAULT == maGrfObj.GetType() ) 552 { 553 // keine default Bitmap mehr, also neu Painten! 554 delete mpReplacementGraphic; 555 mpReplacementGraphic = 0; 556 557 maGrfObj.SetGraphic( Graphic() ); 558 onGraphicChanged(); 559 SwMsgPoolItem aMsgHint( RES_GRAPHIC_PIECE_ARRIVED ); 560 ModifyNotification( &aMsgHint, &aMsgHint ); 561 } 562 } 563 else if ( maGrfObj.IsSwappedOut() ) 564 { 565 // nachzuladender Link 566 //TODO pLink->setInputStream(getInputStream()); 567 nRet = pLink->SwapIn( bWaitForData ) ? 1 : 0; 568 } 569 else 570 nRet = 1; 571 } 572 else if ( maGrfObj.IsSwappedOut() ) 573 { 574 // Die Grafik ist im Storage oder im TempFile drin 575 if ( !HasEmbeddedStreamName() ) 576 nRet = (short) maGrfObj.SwapIn(); 577 else 578 { 579 580 try 581 { 582 String aStrmName, aPicStgName; 583 _GetStreamStorageNames( aStrmName, aPicStgName ); 584 uno::Reference< embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName ); 585 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName ); 586 if ( pStrm ) 587 { 588 if ( ImportGraphic( *pStrm ) ) 589 nRet = 1; 590 delete pStrm; 591 } 592 } 593 catch ( uno::Exception& ) 594 { 595 ASSERT( false, "<SwGrfNode::SwapIn(..)> - unhandled exception!" ); 596 } 597 } 598 599 if ( 1 == nRet ) 600 { 601 SwMsgPoolItem aMsg( RES_GRAPHIC_SWAPIN ); 602 ModifyNotification( &aMsg, &aMsg ); 603 } 604 } 605 else 606 nRet = 1; 607 DBG_ASSERTWARNING( nRet, "Grafik kann nicht eingeswapt werden" ); 608 609 if ( nRet ) 610 { 611 if ( !nGrfSize.Width() && !nGrfSize.Height() ) 612 SetTwipSize( ::GetGraphicSizeTwip( maGrfObj.GetGraphic(), 0 ) ); 613 } 614 bInSwapIn = sal_False; 615 return nRet; 616 } 617 618 short SwGrfNode::SwapOut() 619 { 620 if ( maGrfObj.GetType() != GRAPHIC_DEFAULT 621 && maGrfObj.GetType() != GRAPHIC_NONE 622 && !maGrfObj.IsSwappedOut() 623 && !bInSwapIn ) 624 { 625 if ( !refLink.Is() ) 626 { 627 // Das Swapping brauchen wir nur fuer Embedded Pictures 628 // Die Grafik wird in eine TempFile geschrieben, wenn 629 // sie frisch eingefuegt war, d.h. wenn es noch keinen 630 // Streamnamen im Storage gibt. 631 if ( !HasEmbeddedStreamName() ) 632 if ( !maGrfObj.SwapOut() ) 633 return 0; 634 } 635 // Geschriebene Grafiken oder Links werden jetzt weggeschmissen 636 return (short) maGrfObj.SwapOut( NULL ); 637 } 638 return 1; 639 } 640 641 sal_Bool SwGrfNode::GetFileFilterNms( 642 String* pFileNm, 643 String* pFilterNm ) const 644 { 645 sal_Bool bRet = sal_False; 646 if ( refLink.Is() && refLink->GetLinkManager() ) 647 { 648 sal_uInt16 nType = refLink->GetObjType(); 649 if ( OBJECT_CLIENT_GRF == nType ) 650 bRet = refLink->GetLinkManager()->GetDisplayNames( 651 refLink, 0, pFileNm, 0, pFilterNm ); 652 else if ( OBJECT_CLIENT_DDE == nType && pFileNm && pFilterNm ) 653 { 654 String sApp, sTopic, sItem; 655 if ( refLink->GetLinkManager()->GetDisplayNames( 656 refLink, &sApp, &sTopic, &sItem ) ) 657 { 658 ( *pFileNm = sApp ) += sfx2::cTokenSeperator; 659 ( *pFileNm += sTopic ) += sfx2::cTokenSeperator; 660 *pFileNm += sItem; 661 pFilterNm->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ) ); 662 bRet = sal_True; 663 } 664 } 665 } 666 return bRet; 667 } 668 669 // Eine Grafik Undo-faehig machen. Falls sie sich bereits in 670 // einem Storage befindet, muss sie geladen werden. 671 672 sal_Bool SwGrfNode::SavePersistentData() 673 { 674 if ( refLink.Is() ) 675 { 676 ASSERT( !bInSwapIn, "SavePersistentData: stehe noch im SwapIn" ); 677 GetDoc()->GetLinkManager().Remove( refLink ); 678 return sal_True; 679 } 680 681 // Erst mal reinswappen, falls sie im Storage ist 682 if ( HasEmbeddedStreamName() && !SwapIn() ) 683 return sal_False; 684 685 // #i44367# 686 // Do not delete graphic file in storage, because the graphic file could 687 // be referenced by other graphic nodes. 688 // Because it's hard to detect this case here and it would only fix 689 // one problem with shared graphic files - there are also problems, 690 // a certain graphic file is referenced by two independent graphic nodes, 691 // brush item or drawing objects, the stream isn't no longer removed here. 692 // To do this stuff correct, a reference counting on shared streams 693 // inside one document have to be implemented. 694 // Important note: see also fix for #i40014# 695 // if( HasStreamName() ) 696 // DelStreamName(); 697 698 // Und in TempFile rausswappen 699 return (sal_Bool) SwapOut(); 700 } 701 702 sal_Bool SwGrfNode::RestorePersistentData() 703 { 704 if ( refLink.Is() ) 705 { 706 IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration(); 707 refLink->SetVisible( pIDLA->IsVisibleLinks() ); 708 pIDLA->GetLinkManager().InsertDDELink( refLink ); 709 if ( getIDocumentLayoutAccess()->GetCurrentLayout() ) 710 refLink->Update(); 711 } 712 return sal_True; 713 } 714 715 void SwGrfNode::InsertLink( 716 const String& rGrfName, 717 const String& rFltName ) 718 { 719 refLink = new SwBaseLink( sfx2::LINKUPDATE_ONCALL, FORMAT_GDIMETAFILE, this ); 720 721 IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration(); 722 if ( GetNodes().IsDocNodes() ) 723 { 724 refLink->SetVisible( pIDLA->IsVisibleLinks() ); 725 if ( rFltName.EqualsAscii( "DDE" ) ) 726 { 727 sal_uInt16 nTmp = 0; 728 String sApp, sTopic, sItem; 729 sApp = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp ); 730 sTopic = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp ); 731 sItem = rGrfName.Copy( nTmp ); 732 pIDLA->GetLinkManager().InsertDDELink( refLink, 733 sApp, sTopic, sItem ); 734 } 735 else 736 { 737 sal_Bool bSync = rFltName.EqualsAscii( "SYNCHRON" ); 738 refLink->SetSynchron( bSync ); 739 refLink->SetContentType( SOT_FORMATSTR_ID_SVXB ); 740 741 pIDLA->GetLinkManager().InsertFileLink( *refLink, 742 OBJECT_CLIENT_GRF, rGrfName, 743 ( !bSync && rFltName.Len() ? &rFltName : 0 ) ); 744 } 745 } 746 maGrfObj.SetLink( rGrfName ); 747 } 748 749 void SwGrfNode::ReleaseLink() 750 { 751 if ( refLink.Is() ) 752 { 753 const String aFileName( maGrfObj.GetLink() ); 754 const Graphic aLocalGraphic( maGrfObj.GetGraphic() ); 755 const bool bHasOriginalData( aLocalGraphic.IsLink() ); 756 757 { 758 bInSwapIn = sal_True; 759 SwBaseLink* pLink = (SwBaseLink*) (::sfx2::SvBaseLink*) refLink; 760 //TODO pLink->setInputStream(getInputStream()); 761 pLink->SwapIn( sal_True, sal_True ); 762 bInSwapIn = sal_False; 763 } 764 765 getIDocumentLinksAdministration()->GetLinkManager().Remove( refLink ); 766 refLink.Clear(); 767 maGrfObj.SetLink(); 768 769 // #15508# added extra processing after getting rid of the link. Use whatever is 770 // known from the formally linked graphic to get to a state as close to a directly 771 // unlinked insterted graphic as possible. Goal is to have a valid GfxLink at the 772 // ImplGraphic (see there) that holds temporary data to the original data and type 773 // information about the original data. Only when this is given will 774 // SvXMLGraphicHelper::ImplInsertGraphicURL which is used at export use that type 775 // and use the original graphic at export for the ODF, without evtl. recoding 776 // of trhe bitmap graphic data to something without loss (e.g. PNG) but bigger 777 if ( bHasOriginalData ) 778 { 779 // #15508# if we have the original data at the Graphic, let it survive 780 // by using that Graphic again, this time at a GraphicObject without link. 781 // This happens e.g. when inserting a linked graphic and breaking the link 782 maGrfObj.SetGraphic( aLocalGraphic ); 783 } 784 else if ( aFileName.Len() ) 785 { 786 // #15508# we have no original data, but a file name. This happens e.g. 787 // when inserting a linked graphic and save, reload document. Try to access 788 // that data from the original file; if this works, use it. Else use the 789 // data we have (but without knowing the original format) 790 int nRes = GRFILTER_OK; 791 GraphicFilter* pFlt = GraphicFilter::GetGraphicFilter(); 792 Graphic aNew; 793 nRes = GraphicFilter::LoadGraphic( aFileName, String(), aNew, pFlt ); 794 795 if ( GRFILTER_OK == nRes ) 796 { 797 maGrfObj.SetGraphic( aNew ); 798 } 799 } 800 } 801 } 802 803 void SwGrfNode::SetTwipSize( 804 const Size& rSz ) 805 { 806 nGrfSize = rSz; 807 if ( IsScaleImageMap() && nGrfSize.Width() && nGrfSize.Height() ) 808 { 809 // Image-Map an Grafik-Groesse anpassen 810 ScaleImageMap(); 811 812 // Image-Map nicht noch einmal skalieren 813 SetScaleImageMap( sal_False ); 814 } 815 } 816 817 void SwGrfNode::ScaleImageMap() 818 { 819 if ( !nGrfSize.Width() || !nGrfSize.Height() ) 820 return; 821 822 // dann die Image-Map skalieren 823 SwFrmFmt* pFmt = GetFlyFmt(); 824 825 if ( !pFmt ) 826 return; 827 828 SwFmtURL aURL( pFmt->GetURL() ); 829 if ( !aURL.GetMap() ) 830 return; 831 832 sal_Bool bScale = sal_False; 833 Fraction aScaleX( 1, 1 ); 834 Fraction aScaleY( 1, 1 ); 835 836 const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize(); 837 const SvxBoxItem& rBox = pFmt->GetBox(); 838 839 if ( !rFrmSize.GetWidthPercent() ) 840 { 841 SwTwips nWidth = rFrmSize.GetWidth(); 842 843 nWidth -= rBox.CalcLineSpace( BOX_LINE_LEFT ) + 844 rBox.CalcLineSpace( BOX_LINE_RIGHT ); 845 846 ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" ); 847 848 if ( nGrfSize.Width() != nWidth ) 849 { 850 aScaleX = Fraction( nGrfSize.Width(), nWidth ); 851 bScale = sal_True; 852 } 853 } 854 if ( !rFrmSize.GetHeightPercent() ) 855 { 856 SwTwips nHeight = rFrmSize.GetHeight(); 857 858 nHeight -= rBox.CalcLineSpace( BOX_LINE_TOP ) + 859 rBox.CalcLineSpace( BOX_LINE_BOTTOM ); 860 861 ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" ); 862 863 if ( nGrfSize.Height() != nHeight ) 864 { 865 aScaleY = Fraction( nGrfSize.Height(), nHeight ); 866 bScale = sal_True; 867 } 868 } 869 870 if ( bScale ) 871 { 872 aURL.GetMap()->Scale( aScaleX, aScaleY ); 873 pFmt->SetFmtAttr( aURL ); 874 } 875 } 876 877 void SwGrfNode::DelStreamName() 878 { 879 if ( HasEmbeddedStreamName() ) 880 { 881 // Dann die Grafik im Storage loeschen 882 uno::Reference< embed::XStorage > xDocStg = GetDoc()->GetDocStorage(); 883 if ( xDocStg.is() ) 884 { 885 try 886 { 887 String aPicStgName, aStrmName; 888 _GetStreamStorageNames( aStrmName, aPicStgName ); 889 uno::Reference< embed::XStorage > refPics = xDocStg; 890 if ( aPicStgName.Len() ) 891 refPics = xDocStg->openStorageElement( aPicStgName, embed::ElementModes::READWRITE ); 892 refPics->removeElement( aStrmName ); 893 uno::Reference< embed::XTransactedObject > xTrans( refPics, uno::UNO_QUERY ); 894 if ( xTrans.is() ) 895 xTrans->commit(); 896 } 897 catch ( uno::Exception& ) 898 { 899 // --> OD 2005-04-25 #i48434# 900 ASSERT( false, "<SwGrfNode::DelStreamName()> - unhandled exception!" ); 901 // <-- 902 } 903 } 904 905 maGrfObj.SetUserData(); 906 } 907 } 908 909 /** helper method to get a substorage of the document storage for readonly access. 910 911 #i53025# 912 A substorage with the specified name will be opened readonly. If the provided 913 name is empty the root storage will be returned. 914 */ 915 uno::Reference< embed::XStorage > SwGrfNode::_GetDocSubstorageOrRoot( 916 const String& aStgName ) const 917 { 918 uno::Reference< embed::XStorage > refStor = 919 const_cast< SwGrfNode* >( this )->GetDoc()->GetDocStorage(); 920 ASSERT( refStor.is(), "Kein Storage am Doc" ); 921 922 if ( aStgName.Len() ) 923 { 924 if ( refStor.is() ) 925 return refStor->openStorageElement( aStgName, embed::ElementModes::READ ); 926 } 927 928 return refStor; 929 } 930 931 /** helper method to determine stream for the embedded graphic. 932 933 #i48434# 934 Important note: caller of this method has to handle the thrown exceptions 935 #i53025# 936 Storage, which should contain the stream of the embedded graphic, is 937 provided via parameter. Otherwise the returned stream will be closed 938 after the the method returns, because its parent stream is closed and deleted. 939 Proposed name of embedded graphic stream is also provided by parameter. 940 941 @author OD 942 */ 943 SvStream* SwGrfNode::_GetStreamForEmbedGrf( 944 const uno::Reference< embed::XStorage >& _refPics, 945 String& _aStrmName ) const 946 { 947 SvStream* pStrm( 0L ); 948 949 if ( _refPics.is() && _aStrmName.Len() ) 950 { 951 // If stream doesn't exist in the storage, try access the graphic file by 952 // re-generating its name. 953 // A save action can have changed the filename of the embedded graphic, 954 // because a changed unique ID of the graphic is calculated. 955 // #b6364738# 956 // recursive calls of <GetUniqueID()> have to be avoided. 957 // Thus, use local static boolean to assure this. 958 static bool bInRegenerateStrmName( false ); 959 if ( !bInRegenerateStrmName && 960 ( !_refPics->hasByName( _aStrmName ) || 961 !_refPics->isStreamElement( _aStrmName ) ) ) 962 { 963 bInRegenerateStrmName = true; 964 xub_StrLen nExtPos = _aStrmName.Search( '.' ); 965 String aExtStr = _aStrmName.Copy( nExtPos ); 966 Graphic aGraphic( GetGrfObj().GetGraphic() ); 967 if ( aGraphic.GetType() != GRAPHIC_NONE ) 968 { 969 _aStrmName = String( GetGrfObj().GetUniqueID(), RTL_TEXTENCODING_ASCII_US ); 970 _aStrmName += aExtStr; 971 } 972 bInRegenerateStrmName = false; 973 } 974 975 // assure that graphic file exist in the storage. 976 if ( _refPics->hasByName( _aStrmName ) && 977 _refPics->isStreamElement( _aStrmName ) ) 978 { 979 uno::Reference< io::XStream > refStrm = _refPics->openStreamElement( _aStrmName, embed::ElementModes::READ ); 980 pStrm = utl::UcbStreamHelper::CreateStream( refStrm ); 981 } 982 else 983 { 984 ASSERT( false, "<SwGrfNode::_GetStreamForEmbedGrf(..)> - embedded graphic file not found!" ); 985 } 986 } 987 988 return pStrm; 989 } 990 991 992 void SwGrfNode::_GetStreamStorageNames( 993 String& rStrmName, 994 String& rStorName ) const 995 { 996 rStorName.Erase(); 997 rStrmName.Erase(); 998 999 String aUserData( maGrfObj.GetUserData() ); 1000 if ( !aUserData.Len() ) 1001 return; 1002 1003 String aProt( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.Package:" ) ); 1004 if ( 0 == aUserData.CompareTo( aProt, aProt.Len() ) ) 1005 { 1006 // 6.0 (XML) Package 1007 xub_StrLen nPos = aUserData.Search( '/' ); 1008 if ( STRING_NOTFOUND == nPos ) 1009 { 1010 rStrmName = aUserData.Copy( aProt.Len() ); 1011 } 1012 else 1013 { 1014 xub_StrLen nPathStart = aProt.Len(); 1015 if ( 0 == aUserData.CompareToAscii( "./", 2 ) ) 1016 nPathStart += 2; 1017 rStorName = aUserData.Copy( nPathStart, nPos - nPathStart ); 1018 rStrmName = aUserData.Copy( nPos + 1 ); 1019 } 1020 } 1021 else 1022 { 1023 ASSERT( false, 1024 "<SwGrfNode::_GetStreamStorageNames(..)> - unknown graphic URL type. Code for handling 3.1 - 5.2 storages has been deleted by issue i53025." ); 1025 } 1026 ASSERT( STRING_NOTFOUND == rStrmName.Search( '/' ), 1027 "invalid graphic stream name" ); 1028 } 1029 1030 1031 SwCntntNode* SwGrfNode::MakeCopy( 1032 SwDoc* pDoc, 1033 const SwNodeIndex& rIdx ) const 1034 { 1035 // kopiere die Formate in das andere Dokument: 1036 SwGrfFmtColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() ); 1037 1038 Graphic aTmpGrf; 1039 SwBaseLink* pLink = (SwBaseLink*) (::sfx2::SvBaseLink*) refLink; 1040 if ( !pLink && HasEmbeddedStreamName() ) 1041 { 1042 try 1043 { 1044 String aStrmName, aPicStgName; 1045 _GetStreamStorageNames( aStrmName, aPicStgName ); 1046 uno::Reference< embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName ); 1047 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName ); 1048 if ( pStrm ) 1049 { 1050 const String aURL( maGrfObj.GetUserData() ); 1051 GraphicFilter::GetGraphicFilter()->ImportGraphic( aTmpGrf, aURL, *pStrm ); 1052 delete pStrm; 1053 } 1054 } 1055 catch ( uno::Exception& ) 1056 { 1057 ASSERT( false, "<SwGrfNode::MakeCopy(..)> - unhandled exception!" ); 1058 } 1059 } 1060 else 1061 { 1062 if ( maGrfObj.IsSwappedOut() ) 1063 const_cast< SwGrfNode* >( this )->SwapIn(); 1064 aTmpGrf = maGrfObj.GetGraphic(); 1065 } 1066 1067 const sfx2::LinkManager& rMgr = getIDocumentLinksAdministration()->GetLinkManager(); 1068 String sFile, sFilter; 1069 if ( IsLinkedFile() ) 1070 rMgr.GetDisplayNames( refLink, 0, &sFile, 0, &sFilter ); 1071 else if ( IsLinkedDDE() ) 1072 { 1073 String sTmp1, sTmp2; 1074 rMgr.GetDisplayNames( refLink, &sTmp1, &sTmp2, &sFilter ); 1075 sfx2::MakeLnkName( sFile, &sTmp1, sTmp2, sFilter ); 1076 sFilter.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ) ); 1077 } 1078 1079 SwGrfNode* pGrfNd = pDoc->GetNodes().MakeGrfNode( rIdx, sFile, sFilter, 1080 &aTmpGrf, pColl, 1081 (SwAttrSet*) GetpSwAttrSet() ); 1082 pGrfNd->SetTitle( GetTitle() ); 1083 pGrfNd->SetDescription( GetDescription() ); 1084 pGrfNd->SetContour( HasContour(), HasAutomaticContour() ); 1085 return pGrfNd; 1086 } 1087 1088 IMPL_LINK( SwGrfNode, SwapGraphic, GraphicObject*, pGrfObj ) 1089 { 1090 SvStream* pRet; 1091 1092 // #101174#: Keep graphic while in swap in. That's at least important 1093 // when breaking links, because in this situation a reschedule call and 1094 // a DataChanged call lead to a paint of the graphic. 1095 if ( pGrfObj->IsInSwapOut() && ( IsSelected() || bInSwapIn ) ) 1096 pRet = GRFMGR_AUTOSWAPSTREAM_NONE; 1097 else if ( refLink.Is() ) 1098 { 1099 if ( pGrfObj->IsInSwapIn() ) 1100 { 1101 // then make it by your self 1102 if ( !bInSwapIn ) 1103 { 1104 sal_Bool bIsModifyLocked = IsModifyLocked(); 1105 LockModify(); 1106 SwapIn( sal_False ); 1107 if ( !bIsModifyLocked ) 1108 UnlockModify(); 1109 } 1110 pRet = GRFMGR_AUTOSWAPSTREAM_NONE; 1111 } 1112 else 1113 pRet = GRFMGR_AUTOSWAPSTREAM_LINK; 1114 } 1115 else 1116 { 1117 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP; 1118 1119 if ( HasEmbeddedStreamName() ) 1120 { 1121 try 1122 { 1123 String aStrmName, aPicStgName; 1124 _GetStreamStorageNames( aStrmName, aPicStgName ); 1125 uno::Reference< embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName ); 1126 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName ); 1127 if ( pStrm ) 1128 { 1129 if ( pGrfObj->IsInSwapOut() ) 1130 { 1131 pRet = GRFMGR_AUTOSWAPSTREAM_LINK; 1132 } 1133 else 1134 { 1135 ImportGraphic( *pStrm ); 1136 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED; 1137 } 1138 delete pStrm; 1139 } 1140 } 1141 catch ( uno::Exception& ) 1142 { 1143 ASSERT( false, "<SwapGraphic> - unhandled exception!" ); 1144 } 1145 } 1146 } 1147 1148 return (long) pRet; 1149 } 1150 1151 // alle QuickDraw-Bitmaps eines speziellen Docs loeschen 1152 void DelAllGrfCacheEntries( 1153 SwDoc* pDoc ) 1154 { 1155 if ( pDoc ) 1156 { 1157 // alle Graphic-Links mit dem Namen aus dem Cache loeschen 1158 const sfx2::LinkManager& rLnkMgr = pDoc->GetLinkManager(); 1159 const ::sfx2::SvBaseLinks& rLnks = rLnkMgr.GetLinks(); 1160 SwGrfNode* pGrfNd; 1161 String sFileNm; 1162 for ( sal_uInt16 n = rLnks.Count(); n; ) 1163 { 1164 ::sfx2::SvBaseLink* pLnk = &( *rLnks[--n] ); 1165 if ( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType() 1166 && rLnkMgr.GetDisplayNames( pLnk, 0, &sFileNm ) 1167 && pLnk->ISA( SwBaseLink ) 1168 && 0 != ( pGrfNd = ( (SwBaseLink*) pLnk )->GetCntntNode()->GetGrfNode() ) ) 1169 { 1170 pGrfNd->ReleaseGraphicFromCache(); 1171 } 1172 } 1173 } 1174 } 1175 1176 // returns the with our graphic attributes filled Graphic-Attr-Structure 1177 GraphicAttr& SwGrfNode::GetGraphicAttr( 1178 GraphicAttr& rGA, 1179 const SwFrm* pFrm ) const 1180 { 1181 const SwAttrSet& rSet = GetSwAttrSet(); 1182 1183 rGA.SetDrawMode( (GraphicDrawMode) rSet.GetDrawModeGrf().GetValue() ); 1184 1185 const SwMirrorGrf & rMirror = rSet.GetMirrorGrf(); 1186 sal_uLong nMirror = BMP_MIRROR_NONE; 1187 if ( rMirror.IsGrfToggle() && pFrm && !pFrm->FindPageFrm()->OnRightPage() ) 1188 { 1189 switch (rMirror.GetValue()) 1190 { 1191 case RES_MIRROR_GRAPH_DONT: 1192 nMirror = BMP_MIRROR_HORZ; 1193 break; 1194 case RES_MIRROR_GRAPH_VERT: 1195 nMirror = BMP_MIRROR_NONE; 1196 break; 1197 case RES_MIRROR_GRAPH_HOR: 1198 nMirror = BMP_MIRROR_HORZ | BMP_MIRROR_VERT; 1199 break; 1200 default: 1201 nMirror = BMP_MIRROR_VERT; 1202 break; 1203 } 1204 } 1205 else 1206 switch (rMirror.GetValue()) 1207 { 1208 case RES_MIRROR_GRAPH_BOTH: 1209 nMirror = BMP_MIRROR_HORZ | BMP_MIRROR_VERT; 1210 break; 1211 case RES_MIRROR_GRAPH_VERT: 1212 nMirror = BMP_MIRROR_HORZ; 1213 break; 1214 case RES_MIRROR_GRAPH_HOR: 1215 nMirror = BMP_MIRROR_VERT; 1216 break; 1217 } 1218 1219 rGA.SetMirrorFlags( nMirror ); 1220 1221 const SwCropGrf& rCrop = rSet.GetCropGrf(); 1222 rGA.SetCrop( TWIP_TO_MM100( rCrop.GetLeft() ), 1223 TWIP_TO_MM100( rCrop.GetTop() ), 1224 TWIP_TO_MM100( rCrop.GetRight() ), 1225 TWIP_TO_MM100( rCrop.GetBottom() ) ); 1226 1227 const SwRotationGrf& rRotation = rSet.GetRotationGrf(); 1228 rGA.SetRotation( rRotation.GetValue() ); 1229 1230 rGA.SetLuminance( rSet.GetLuminanceGrf().GetValue() ); 1231 rGA.SetContrast( rSet.GetContrastGrf().GetValue() ); 1232 rGA.SetChannelR( rSet.GetChannelRGrf().GetValue() ); 1233 rGA.SetChannelG( rSet.GetChannelGGrf().GetValue() ); 1234 rGA.SetChannelB( rSet.GetChannelBGrf().GetValue() ); 1235 rGA.SetGamma( rSet.GetGammaGrf().GetValue() ); 1236 rGA.SetInvert( rSet.GetInvertGrf().GetValue() ); 1237 1238 const sal_uInt16 nTrans = rSet.GetTransparencyGrf().GetValue(); 1239 rGA.SetTransparency( (sal_uInt8) FRound( 1240 Min( nTrans, (sal_uInt16) 100 ) * 2.55 ) ); 1241 1242 return rGA; 1243 } 1244 1245 sal_Bool SwGrfNode::IsTransparent() const 1246 { 1247 sal_Bool bRet = maGrfObj.IsTransparent(); 1248 if ( !bRet ) // ask the attribut 1249 bRet = 0 != GetSwAttrSet().GetTransparencyGrf().GetValue(); 1250 1251 return bRet; 1252 } 1253 1254 sal_Bool SwGrfNode::IsSelected() const 1255 { 1256 sal_Bool bRet = sal_False; 1257 const SwEditShell* pESh = GetDoc()->GetEditShell(); 1258 if ( pESh ) 1259 { 1260 const SwNode* pN = this; 1261 const ViewShell* pV = pESh; 1262 do 1263 { 1264 if ( pV->ISA( SwEditShell ) && pN == &( (SwCrsrShell*) pV ) 1265 ->GetCrsr()->GetPoint()->nNode.GetNode() ) 1266 { 1267 bRet = sal_True; 1268 break; 1269 } 1270 } 1271 while (pESh != ( pV = (ViewShell*) pV->GetNext() )); 1272 } 1273 return bRet; 1274 } 1275 1276 boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > SwGrfNode::GetThreadConsumer() 1277 { 1278 return mpThreadConsumer; 1279 } 1280 1281 void SwGrfNode::TriggerAsyncRetrieveInputStream() 1282 { 1283 if ( !IsLinkedFile() ) 1284 { 1285 ASSERT( false, 1286 "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" ); 1287 return; 1288 } 1289 1290 if ( mpThreadConsumer.get() == 0 ) 1291 { 1292 mpThreadConsumer.reset( new SwAsyncRetrieveInputStreamThreadConsumer( *this ) ); 1293 1294 String sGrfNm; 1295 refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 ); 1296 1297 mpThreadConsumer->CreateThread( sGrfNm ); 1298 } 1299 } 1300 1301 bool SwGrfNode::IsLinkedInputStreamReady() const 1302 { 1303 return mbLinkedInputStreamReady; 1304 } 1305 1306 void SwGrfNode::ApplyInputStream( 1307 com::sun::star::uno::Reference< com::sun::star::io::XInputStream > xInputStream, 1308 const sal_Bool bIsStreamReadOnly ) 1309 { 1310 if ( IsLinkedFile() ) 1311 { 1312 if ( xInputStream.is() ) 1313 { 1314 mxInputStream = xInputStream; 1315 mbIsStreamReadOnly = bIsStreamReadOnly; 1316 mbLinkedInputStreamReady = true; 1317 SwMsgPoolItem aMsgHint( RES_LINKED_GRAPHIC_STREAM_ARRIVED ); 1318 ModifyNotification( &aMsgHint, &aMsgHint ); 1319 } 1320 } 1321 } 1322 1323 void SwGrfNode::UpdateLinkWithInputStream() 1324 { 1325 // do not work on link, if a <SwapIn> has been triggered. 1326 if ( !bInSwapIn && IsLinkedFile() ) 1327 { 1328 GetLink()->setStreamToLoadFrom( mxInputStream, mbIsStreamReadOnly ); 1329 GetLink()->Update(); 1330 SwMsgPoolItem aMsgHint( RES_GRAPHIC_ARRIVED ); 1331 ModifyNotification( &aMsgHint, &aMsgHint ); 1332 1333 mxInputStream.clear(); 1334 GetLink()->clearStreamToLoadFrom(); 1335 mbLinkedInputStreamReady = false; 1336 mpThreadConsumer.reset(); 1337 } 1338 } 1339 1340 1341 bool SwGrfNode::IsAsyncRetrieveInputStreamPossible() const 1342 { 1343 bool bRet = false; 1344 1345 if ( IsLinkedFile() ) 1346 { 1347 String sGrfNm; 1348 refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 ); 1349 String sProtocol( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.pkg:" ) ); 1350 if ( sGrfNm.CompareTo( sProtocol, sProtocol.Len() ) != 0 ) 1351 { 1352 bRet = true; 1353 } 1354 } 1355 1356 return bRet; 1357 } 1358