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