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