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