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