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