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