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