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