xref: /aoo41x/main/sw/source/core/graphic/ndgrf.cxx (revision 57326f99)
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( HasStreamName() )
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( HasStreamName() )
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( HasStreamName() )
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( !HasStreamName() )
553 			nRet = (short)maGrfObj.SwapIn();
554 		else
555 		{
556 
557             // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
558             try
559             {
560                 // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
561                 // method <_GetStreamForEmbedGrf(..)>
562 //                bool bGraphic(false);
563 //                SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
564                 String aStrmName, aPicStgName;
565                 _GetStreamStorageNames( aStrmName, aPicStgName );
566                 uno::Reference < embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
567                 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
568                 if ( pStrm )
569                 {
570                     if ( ImportGraphic( *pStrm ) )
571                         nRet = 1;
572                     delete pStrm;
573                 }
574                 // <--
575             }
576             catch ( uno::Exception& )
577             {
578                 // --> OD 2005-04-25 #i48434#
579                 ASSERT( false, "<SwGrfNode::SwapIn(..)> - unhandled exception!" );
580                 // <--
581             }
582             // <--
583 		}
584 
585 		if( 1 == nRet )
586 		{
587 			SwMsgPoolItem aMsg( RES_GRAPHIC_SWAPIN );
588             ModifyNotification( &aMsg, &aMsg );
589 		}
590 	}
591 	else
592 		nRet = 1;
593 	DBG_ASSERTWARNING( nRet, "Grafik kann nicht eingeswapt werden" );
594 
595 	if( nRet )
596 	{
597 		if( !nGrfSize.Width() && !nGrfSize.Height() )
598 			SetTwipSize( ::GetGraphicSizeTwip( maGrfObj.GetGraphic(), 0 ) );
599 	}
600 	bInSwapIn = sal_False;
601 	return nRet;
602 }
603 
604 
605 short SwGrfNode::SwapOut()
606 {
607 	if( maGrfObj.GetType() != GRAPHIC_DEFAULT &&
608 		maGrfObj.GetType() != GRAPHIC_NONE &&
609 		!maGrfObj.IsSwappedOut() && !bInSwapIn )
610 	{
611 		if( !refLink.Is() )
612 		{
613 			// Das Swapping brauchen wir nur fuer Embedded Pictures
614 			// Die Grafik wird in eine TempFile geschrieben, wenn
615 			// sie frisch eingefuegt war, d.h. wenn es noch keinen
616 			// Streamnamen im Storage gibt.
617 			if( !HasStreamName() )
618 				if( !maGrfObj.SwapOut() )
619 					return 0;
620 		}
621 		// Geschriebene Grafiken oder Links werden jetzt weggeschmissen
622 		return (short) maGrfObj.SwapOut( NULL );
623 	}
624 	return 1;
625 }
626 
627 
628 sal_Bool SwGrfNode::GetFileFilterNms( String* pFileNm, String* pFilterNm ) const
629 {
630 	sal_Bool bRet = sal_False;
631 	if( refLink.Is() && refLink->GetLinkManager() )
632 	{
633 		sal_uInt16 nType = refLink->GetObjType();
634 		if( OBJECT_CLIENT_GRF == nType )
635 			bRet = refLink->GetLinkManager()->GetDisplayNames(
636 					refLink, 0, pFileNm, 0, pFilterNm );
637 		else if( OBJECT_CLIENT_DDE == nType && pFileNm && pFilterNm )
638 		{
639 			String sApp, sTopic, sItem;
640 			if( refLink->GetLinkManager()->GetDisplayNames(
641 					refLink, &sApp, &sTopic, &sItem ) )
642 			{
643                 ( *pFileNm = sApp ) += sfx2::cTokenSeperator;
644                 ( *pFileNm += sTopic ) += sfx2::cTokenSeperator;
645 				*pFileNm += sItem;
646 				pFilterNm->AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
647 				bRet = sal_True;
648 			}
649 		}
650 	}
651 	return bRet;
652 }
653 
654 
655 // Eine Grafik Undo-faehig machen. Falls sie sich bereits in
656 // einem Storage befindet, muss sie geladen werden.
657 
658 sal_Bool SwGrfNode::SavePersistentData()
659 {
660 	if( refLink.Is() )
661 	{
662 		ASSERT( !bInSwapIn, "SavePersistentData: stehe noch im SwapIn" );
663 		GetDoc()->GetLinkManager().Remove( refLink );
664 		return sal_True;
665 	}
666 
667 	// Erst mal reinswappen, falls sie im Storage ist
668 	if( HasStreamName() && !SwapIn() )
669 		return sal_False;
670 
671     // --> OD 2005-04-19 #i44367#
672     // Do not delete graphic file in storage, because the graphic file could
673     // be referenced by other graphic nodes.
674     // Because it's hard to detect this case here and it would only fix
675     // one problem with shared graphic files - there are also problems,
676     // a certain graphic file is referenced by two independent graphic nodes,
677     // brush item or drawing objects, the stream isn't no longer removed here.
678     // To do this stuff correct, a reference counting on shared streams
679     // inside one document have to be implemented.
680     // Important note: see also fix for #i40014#
681 //    if( HasStreamName() )
682 //        DelStreamName();
683     // <--
684 
685 	// Und in TempFile rausswappen
686 	return (sal_Bool) SwapOut();
687 }
688 
689 
690 sal_Bool SwGrfNode::RestorePersistentData()
691 {
692 	if( refLink.Is() )
693 	{
694         IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration();
695         refLink->SetVisible( pIDLA->IsVisibleLinks() );
696         pIDLA->GetLinkManager().InsertDDELink( refLink );
697         if( getIDocumentLayoutAccess()->GetCurrentLayout() )	//swmod 080218
698 			refLink->Update();
699 	}
700 	return sal_True;
701 }
702 
703 
704 void SwGrfNode::InsertLink( const String& rGrfName, const String& rFltName )
705 {
706     refLink = new SwBaseLink( sfx2::LINKUPDATE_ONCALL, FORMAT_GDIMETAFILE, this );
707 
708     IDocumentLinksAdministration* pIDLA = getIDocumentLinksAdministration();
709 	if( GetNodes().IsDocNodes() )
710 	{
711         refLink->SetVisible( pIDLA->IsVisibleLinks() );
712 		if( rFltName.EqualsAscii( "DDE" ))
713 		{
714 			sal_uInt16 nTmp = 0;
715 			String sApp, sTopic, sItem;
716             sApp = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp );
717             sTopic = rGrfName.GetToken( 0, sfx2::cTokenSeperator, nTmp );
718 			sItem = rGrfName.Copy( nTmp );
719             pIDLA->GetLinkManager().InsertDDELink( refLink,
720 											sApp, sTopic, sItem );
721 		}
722 		else
723 		{
724 			sal_Bool bSync = rFltName.EqualsAscii( "SYNCHRON" );
725 			refLink->SetSynchron( bSync );
726             refLink->SetContentType( SOT_FORMATSTR_ID_SVXB );
727 
728             pIDLA->GetLinkManager().InsertFileLink( *refLink,
729 											OBJECT_CLIENT_GRF, rGrfName,
730 								(!bSync && rFltName.Len() ? &rFltName : 0) );
731 		}
732 	}
733 	maGrfObj.SetLink( rGrfName );
734 }
735 
736 
737 void SwGrfNode::ReleaseLink()
738 {
739     if( refLink.Is() )
740     {
741         // #15508# remember some stuff from the linked graphic
742         const String aFileName(maGrfObj.GetLink());
743         const Graphic aLocalGraphic(maGrfObj.GetGraphic());
744         const bool bHasOriginalData(aLocalGraphic.IsLink());
745 
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 
754         getIDocumentLinksAdministration()->GetLinkManager().Remove( refLink );
755         refLink.Clear();
756         maGrfObj.SetLink();
757 
758         // #15508# added extra processing after getting rid of the link. Use whatever is
759         // known from the formally linked graphic to get to a state as close to a directly
760         // unlinked insterted graphic as possible. Goal is to have a valid GfxLink at the
761         // ImplGraphic (see there) that holds temporary data to the original data and type
762         // information about the original data. Only when this is given will
763         // SvXMLGraphicHelper::ImplInsertGraphicURL which is used at export use that type
764         // and use the original graphic at export for the ODF, without evtl. recoding
765         // of trhe bitmap graphic data to something without loss (e.g. PNG) but bigger
766         if(bHasOriginalData)
767         {
768             // #15508# if we have the original data at the Graphic, let it survive
769             // by using that Graphic again, this time at a GraphicObject without link.
770             // This happens e.g. when inserting a linked graphic and breaking the link
771             maGrfObj.SetGraphic(aLocalGraphic);
772         }
773         else if(aFileName.Len())
774         {
775             // #15508# we have no original data, but a file name. This happens e.g.
776             // when inserting a linked graphic and save, reload document. Try to access
777             // that data from the original file; if this works, use it. Else use the
778             // data we have (but without knowing the original format)
779             int nRes = GRFILTER_OK;
780             GraphicFilter* pFlt = GraphicFilter::GetGraphicFilter();
781             Graphic aNew;
782             nRes = GraphicFilter::LoadGraphic( aFileName, String(), aNew, pFlt);
783 
784             if(GRFILTER_OK == nRes)
785             {
786                 maGrfObj.SetGraphic(aNew);
787             }
788         }
789     }
790 }
791 
792 
793 void SwGrfNode::SetTwipSize( const Size& rSz )
794 {
795 	nGrfSize = rSz;
796 	if( IsScaleImageMap() && nGrfSize.Width() && nGrfSize.Height() )
797 	{
798 		// Image-Map an Grafik-Groesse anpassen
799 		ScaleImageMap();
800 
801 		// Image-Map nicht noch einmal skalieren
802 		SetScaleImageMap( sal_False );
803 	}
804 }
805 
806 void SwGrfNode::ScaleImageMap()
807 {
808 	if( !nGrfSize.Width() || !nGrfSize.Height() )
809 		return;
810 
811 	// dann die Image-Map skalieren
812 	SwFrmFmt* pFmt = GetFlyFmt();
813 
814 	if( !pFmt )
815 		return;
816 
817 	SwFmtURL aURL( pFmt->GetURL() );
818 	if ( !aURL.GetMap() )
819 		return;
820 
821 	sal_Bool bScale = sal_False;
822 	Fraction aScaleX( 1, 1 );
823 	Fraction aScaleY( 1, 1 );
824 
825 	const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
826 	const SvxBoxItem& rBox = pFmt->GetBox();
827 
828 	if( !rFrmSize.GetWidthPercent() )
829 	{
830 		SwTwips nWidth = rFrmSize.GetWidth();
831 
832 		nWidth -= rBox.CalcLineSpace(BOX_LINE_LEFT) +
833 				  rBox.CalcLineSpace(BOX_LINE_RIGHT);
834 
835 		ASSERT( nWidth>0, "Gibt es 0 twip breite Grafiken!?" );
836 
837 		if( nGrfSize.Width() != nWidth )
838 		{
839 			aScaleX = Fraction( nGrfSize.Width(), nWidth );
840 			bScale = sal_True;
841 		}
842 	}
843 	if( !rFrmSize.GetHeightPercent() )
844 	{
845 		SwTwips nHeight = rFrmSize.GetHeight();
846 
847 		nHeight -= rBox.CalcLineSpace(BOX_LINE_TOP) +
848 				   rBox.CalcLineSpace(BOX_LINE_BOTTOM);
849 
850 		ASSERT( nHeight>0, "Gibt es 0 twip hohe Grafiken!?" );
851 
852 		if( nGrfSize.Height() != nHeight )
853 		{
854 			aScaleY = Fraction( nGrfSize.Height(), nHeight );
855 			bScale = sal_True;
856 		}
857 	}
858 
859 	if( bScale )
860 	{
861 		aURL.GetMap()->Scale( aScaleX, aScaleY );
862         pFmt->SetFmtAttr( aURL );
863 	}
864 }
865 
866 
867 void SwGrfNode::DelStreamName()
868 {
869 	if( HasStreamName() )
870 	{
871 		// Dann die Grafik im Storage loeschen
872         uno::Reference < embed::XStorage > xDocStg = GetDoc()->GetDocStorage();
873         if( xDocStg.is() )
874 		{
875             try
876             {
877                 String aPicStgName, aStrmName;
878                 _GetStreamStorageNames( aStrmName, aPicStgName );
879                 uno::Reference < embed::XStorage > refPics = xDocStg;
880                 if ( aPicStgName.Len() )
881                     refPics = xDocStg->openStorageElement( aPicStgName, embed::ElementModes::READWRITE );
882                 refPics->removeElement( aStrmName );
883                 uno::Reference < embed::XTransactedObject > xTrans( refPics, uno::UNO_QUERY );
884                 if ( xTrans.is() )
885                     xTrans->commit();
886             }
887             catch ( uno::Exception& )
888             {
889                 // --> OD 2005-04-25 #i48434#
890                 ASSERT( false, "<SwGrfNode::DelStreamName()> - unhandled exception!" );
891                 // <--
892             }
893 		}
894 
895 		maGrfObj.SetUserData();
896 	}
897 }
898 
899 /** helper method to get a substorage of the document storage for readonly access.
900 
901     OD, MAV 2005-08-17 #i53025#
902     A substorage with the specified name will be opened readonly. If the provided
903     name is empty the root storage will be returned.
904 */
905 uno::Reference< embed::XStorage > SwGrfNode::_GetDocSubstorageOrRoot( const String& aStgName ) const
906 {
907     uno::Reference < embed::XStorage > refStor =
908         const_cast<SwGrfNode*>(this)->GetDoc()->GetDocStorage();
909     ASSERT( refStor.is(), "Kein Storage am Doc" );
910 
911     if ( aStgName.Len() )
912     {
913         if( refStor.is() )
914             return refStor->openStorageElement( aStgName, embed::ElementModes::READ );
915     }
916 
917     return refStor;
918 }
919 
920 /** helper method to determine stream for the embedded graphic.
921 
922     OD 2005-05-04 #i48434#
923     Important note: caller of this method has to handle the thrown exceptions
924     OD, MAV 2005-08-17 #i53025#
925     Storage, which should contain the stream of the embedded graphic, is
926     provided via parameter. Otherwise the returned stream will be closed
927     after the the method returns, because its parent stream is closed and deleted.
928     Proposed name of embedded graphic stream is also provided by parameter.
929 
930     @author OD
931 */
932 SvStream* SwGrfNode::_GetStreamForEmbedGrf(
933             const uno::Reference< embed::XStorage >& _refPics,
934             String& _aStrmName ) const
935 {
936     SvStream* pStrm( 0L );
937 
938     if( _refPics.is() && _aStrmName.Len() )
939     {
940         // If stream doesn't exist in the storage, try access the graphic file by
941         // re-generating its name.
942         // A save action can have changed the filename of the embedded graphic,
943         // because a changed unique ID of the graphic is calculated.
944         // --> OD 2006-01-30 #b6364738#
945         // recursive calls of <GetUniqueID()> have to be avoided.
946         // Thus, use local static boolean to assure this.
947         static bool bInRegenerateStrmName( false );
948         if ( !bInRegenerateStrmName &&
949              ( !_refPics->hasByName( _aStrmName ) ||
950                !_refPics->isStreamElement( _aStrmName ) ) )
951         {
952             bInRegenerateStrmName = true;
953             xub_StrLen nExtPos = _aStrmName.Search( '.' );
954             String aExtStr = _aStrmName.Copy( nExtPos );
955 			Graphic aGraphic( GetGrfObj().GetGraphic() );
956 			if ( aGraphic.GetType() != GRAPHIC_NONE )
957 			{
958 				_aStrmName = String( GetGrfObj().GetUniqueID(), RTL_TEXTENCODING_ASCII_US );
959 				_aStrmName += aExtStr;
960 			}
961             bInRegenerateStrmName = false;
962         }
963         // <--
964 
965         // assure that graphic file exist in the storage.
966         if ( _refPics->hasByName( _aStrmName ) &&
967              _refPics->isStreamElement( _aStrmName ) )
968         {
969             uno::Reference < io::XStream > refStrm = _refPics->openStreamElement( _aStrmName, embed::ElementModes::READ );
970             pStrm = utl::UcbStreamHelper::CreateStream( refStrm );
971         }
972         else
973         {
974             ASSERT( false, "<SwGrfNode::_GetStreamForEmbedGrf(..)> - embedded graphic file not found!" );
975         }
976     }
977 
978     return pStrm;
979 }
980 
981 
982 // --> OD 2005-08-17 #i53025# - stream couldn't be in a 3.1 - 5.2 storage any more.
983 // Thus, removing corresponding code.
984 void SwGrfNode::_GetStreamStorageNames( String& rStrmName,
985                                         String& rStorName ) const
986 {
987 	rStorName.Erase();
988 	rStrmName.Erase();
989 
990 	String aUserData( maGrfObj.GetUserData() );
991 	if( !aUserData.Len() )
992         return;
993 
994 	String aProt( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.Package:" ) );
995 	if( 0 == aUserData.CompareTo( aProt, aProt.Len() ) )
996 	{
997 		// 6.0 (XML) Package
998 		xub_StrLen nPos = aUserData.Search( '/' );
999 		if( STRING_NOTFOUND == nPos )
1000 		{
1001 			rStrmName = aUserData.Copy( aProt.Len() );
1002 		}
1003 		else
1004 		{
1005 			xub_StrLen nPathStart = aProt.Len();
1006 			if( 0 == aUserData.CompareToAscii( "./", 2 ) )
1007 				nPathStart += 2;
1008 			rStorName = aUserData.Copy( nPathStart, nPos-nPathStart );
1009 			rStrmName = aUserData.Copy( nPos+1 );
1010 		}
1011 	}
1012     else
1013     {
1014         ASSERT( false,
1015                 "<SwGrfNode::_GetStreamStorageNames(..)> - unknown graphic URL type. Code for handling 3.1 - 5.2 storages has been deleted by issue i53025." );
1016     }
1017 	ASSERT( STRING_NOTFOUND == rStrmName.Search( '/' ),
1018 			"invalid graphic stream name" );
1019 }
1020 // <--
1021 
1022 SwCntntNode* SwGrfNode::MakeCopy( SwDoc* pDoc, const SwNodeIndex& rIdx ) const
1023 {
1024 	// kopiere die Formate in das andere Dokument:
1025 	SwGrfFmtColl* pColl = pDoc->CopyGrfColl( *GetGrfColl() );
1026 
1027 	Graphic aTmpGrf;
1028     SwBaseLink* pLink = (SwBaseLink*)(::sfx2::SvBaseLink*) refLink;
1029 	if( !pLink && HasStreamName() )
1030 	{
1031         // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
1032         try
1033         {
1034             // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
1035             // method <_GetStreamForEmbedGrf(..)>
1036 //            bool bGraphic(false);
1037 //            SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
1038             String aStrmName, aPicStgName;
1039             _GetStreamStorageNames( aStrmName, aPicStgName );
1040             uno::Reference < embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
1041             SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
1042             if ( pStrm )
1043             {
1044                 const String aURL(maGrfObj.GetUserData());
1045                 GraphicFilter::GetGraphicFilter()->ImportGraphic(aTmpGrf, aURL, *pStrm);
1046                 delete pStrm;
1047             }
1048             // <--
1049         }
1050         catch ( uno::Exception& )
1051         {
1052             // --> OD 2005-04-25 #i48434#
1053             ASSERT( false, "<SwGrfNode::MakeCopy(..)> - unhandled exception!" );
1054             // <--
1055         }
1056         // <--
1057 	}
1058 	else
1059 	{
1060 		if( maGrfObj.IsSwappedOut() )
1061             const_cast<SwGrfNode*>(this)->SwapIn();
1062 		aTmpGrf = maGrfObj.GetGraphic();
1063 	}
1064 
1065     const sfx2::LinkManager& rMgr = getIDocumentLinksAdministration()->GetLinkManager();
1066 	String sFile, sFilter;
1067 	if( IsLinkedFile() )
1068 		rMgr.GetDisplayNames( refLink, 0, &sFile, 0, &sFilter );
1069 	else if( IsLinkedDDE() )
1070 	{
1071 		String sTmp1, sTmp2;
1072 		rMgr.GetDisplayNames( refLink, &sTmp1, &sTmp2, &sFilter );
1073         sfx2::MakeLnkName( sFile, &sTmp1, sTmp2, sFilter );
1074 		sFilter.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE" ));
1075 	}
1076 
1077 	SwGrfNode* pGrfNd = pDoc->GetNodes().MakeGrfNode( rIdx, sFile, sFilter,
1078 													&aTmpGrf, pColl,
1079 											(SwAttrSet*)GetpSwAttrSet() );
1080     pGrfNd->SetTitle( GetTitle() );
1081     pGrfNd->SetDescription( GetDescription() );
1082     pGrfNd->SetContour( HasContour(), HasAutomaticContour() );
1083 	return pGrfNd;
1084 }
1085 
1086 IMPL_LINK( SwGrfNode, SwapGraphic, GraphicObject*, pGrfObj )
1087 {
1088 	SvStream* pRet;
1089 
1090 	// #101174#: Keep graphic while in swap in. That's at least important
1091 	// when breaking links, because in this situation a reschedule call and
1092 	// a DataChanged call lead to a paint of the graphic.
1093 	if( pGrfObj->IsInSwapOut() && (IsSelected() || bInSwapIn) )
1094 		pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1095 	else if( refLink.Is() )
1096 	{
1097 		if( pGrfObj->IsInSwapIn() )
1098 		{
1099 			// then make it by your self
1100 			if( !bInSwapIn )
1101 			{
1102 				sal_Bool bIsModifyLocked = IsModifyLocked();
1103 				LockModify();
1104 				SwapIn( sal_False );
1105 				if( !bIsModifyLocked )
1106 					UnlockModify();
1107 			}
1108 			pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1109 		}
1110 		else
1111 			pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1112 	}
1113 	else
1114 	{
1115 		pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1116 
1117 		if( HasStreamName() )
1118 		{
1119             // --> OD 2005-05-04 #i48434# - usage of new method <_GetStreamForEmbedGrf(..)>
1120             try
1121             {
1122                 // --> OD, MAV 2005-08-17 #i53025# - needed correction of new
1123                 // method <_GetStreamForEmbedGrf(..)>
1124 //                bool bGraphic(false);
1125 //                SvStream* pStrm = _GetStreamForEmbedGrf( bGraphic );
1126                 String aStrmName, aPicStgName;
1127                 _GetStreamStorageNames( aStrmName, aPicStgName );
1128                 uno::Reference < embed::XStorage > refPics = _GetDocSubstorageOrRoot( aPicStgName );
1129                 SvStream* pStrm = _GetStreamForEmbedGrf( refPics, aStrmName );
1130                 if ( pStrm )
1131                 {
1132                     if( pGrfObj->IsInSwapOut() )
1133                     {
1134                         pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1135                     }
1136                     else
1137                     {
1138                         ImportGraphic( *pStrm );
1139                         pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1140                     }
1141                     delete pStrm;
1142                 }
1143                 // <--
1144             }
1145             catch ( uno::Exception& )
1146             {
1147                 // --> OD 2005-04-25 #i48434#
1148                 ASSERT( false, "<SwapGraphic> - unhandled exception!" );
1149                 // <--
1150             }
1151             // <--
1152 		}
1153 	}
1154 
1155 	return (long)pRet;
1156 }
1157 
1158 
1159 // alle QuickDraw-Bitmaps eines speziellen Docs loeschen
1160 void DelAllGrfCacheEntries( SwDoc* pDoc )
1161 {
1162 	if( pDoc )
1163 	{
1164 		// alle Graphic-Links mit dem Namen aus dem Cache loeschen
1165 		const sfx2::LinkManager& rLnkMgr = pDoc->GetLinkManager();
1166         const ::sfx2::SvBaseLinks& rLnks = rLnkMgr.GetLinks();
1167 		SwGrfNode* pGrfNd;
1168 		String sFileNm;
1169 		for( sal_uInt16 n = rLnks.Count(); n; )
1170 		{
1171             ::sfx2::SvBaseLink* pLnk = &(*rLnks[ --n ]);
1172 			if( pLnk && OBJECT_CLIENT_GRF == pLnk->GetObjType() &&
1173 				rLnkMgr.GetDisplayNames( pLnk, 0, &sFileNm ) &&
1174 				pLnk->ISA( SwBaseLink ) && 0 != ( pGrfNd =
1175 				((SwBaseLink*)pLnk)->GetCntntNode()->GetGrfNode()) )
1176 			{
1177 				pGrfNd->ReleaseGraphicFromCache();
1178 			}
1179 		}
1180 	}
1181 }
1182 
1183 // returns the with our graphic attributes filled Graphic-Attr-Structure
1184 GraphicAttr& SwGrfNode::GetGraphicAttr( GraphicAttr& rGA,
1185 										const SwFrm* pFrm ) const
1186 {
1187 	const SwAttrSet& rSet = GetSwAttrSet();
1188 
1189 	rGA.SetDrawMode( (GraphicDrawMode)rSet.GetDrawModeGrf().GetValue() );
1190 
1191 	const SwMirrorGrf & rMirror = rSet.GetMirrorGrf();
1192 	sal_uLong nMirror = BMP_MIRROR_NONE;
1193 	if( rMirror.IsGrfToggle() && pFrm && !pFrm->FindPageFrm()->OnRightPage() )
1194 	{
1195 		switch( rMirror.GetValue() )
1196 		{
1197         case RES_MIRROR_GRAPH_DONT:     nMirror = BMP_MIRROR_HORZ; break;
1198         case RES_MIRROR_GRAPH_VERT:     nMirror = BMP_MIRROR_NONE; break;
1199         case RES_MIRROR_GRAPH_HOR:  nMirror = BMP_MIRROR_HORZ|BMP_MIRROR_VERT;
1200 									break;
1201 		default: 					nMirror = BMP_MIRROR_VERT; break;
1202 		}
1203 	}
1204 	else
1205 		switch( rMirror.GetValue() )
1206 		{
1207         case RES_MIRROR_GRAPH_BOTH:     nMirror = BMP_MIRROR_HORZ|BMP_MIRROR_VERT;
1208 									break;
1209         case RES_MIRROR_GRAPH_VERT: nMirror = BMP_MIRROR_HORZ; break;
1210         case RES_MIRROR_GRAPH_HOR:  nMirror = BMP_MIRROR_VERT; break;
1211 		}
1212 
1213 	rGA.SetMirrorFlags( nMirror );
1214 
1215 	const SwCropGrf& rCrop = rSet.GetCropGrf();
1216 	rGA.SetCrop( TWIP_TO_MM100( rCrop.GetLeft() ),
1217 				 TWIP_TO_MM100( rCrop.GetTop() ),
1218 				 TWIP_TO_MM100( rCrop.GetRight() ),
1219 				 TWIP_TO_MM100( rCrop.GetBottom() ));
1220 
1221 	const SwRotationGrf& rRotation = rSet.GetRotationGrf();
1222 	rGA.SetRotation( rRotation.GetValue() );
1223 
1224 	rGA.SetLuminance( rSet.GetLuminanceGrf().GetValue() );
1225 	rGA.SetContrast( rSet.GetContrastGrf().GetValue() );
1226 	rGA.SetChannelR( rSet.GetChannelRGrf().GetValue() );
1227 	rGA.SetChannelG( rSet.GetChannelGGrf().GetValue() );
1228 	rGA.SetChannelB( rSet.GetChannelBGrf().GetValue() );
1229 	rGA.SetGamma( rSet.GetGammaGrf().GetValue() );
1230 	rGA.SetInvert( rSet.GetInvertGrf().GetValue() );
1231 
1232 	const sal_uInt16 nTrans = rSet.GetTransparencyGrf().GetValue();
1233 	rGA.SetTransparency( (sal_uInt8) FRound(
1234 								Min( nTrans, (sal_uInt16) 100 )  * 2.55 ) );
1235 
1236 	return rGA;
1237 }
1238 
1239 sal_Bool SwGrfNode::IsTransparent() const
1240 {
1241 	sal_Bool bRet = maGrfObj.IsTransparent();
1242 	if( !bRet )	// ask the attribut
1243 		bRet = 0 != GetSwAttrSet().GetTransparencyGrf().GetValue();
1244 
1245 	return bRet;
1246 }
1247 
1248 
1249 sal_Bool SwGrfNode::IsSelected() const
1250 {
1251 	sal_Bool bRet = sal_False;
1252 	const SwEditShell* pESh = GetDoc()->GetEditShell();
1253 	if( pESh )
1254 	{
1255 		const SwNode* pN = this;
1256 		const ViewShell* pV = pESh;
1257 		do {
1258 			if( pV->ISA( SwEditShell ) && pN == &((SwCrsrShell*)pV)
1259 								->GetCrsr()->GetPoint()->nNode.GetNode() )
1260 			{
1261 				bRet = sal_True;
1262 				break;
1263 			}
1264 		}
1265 		while( pESh != ( pV = (ViewShell*)pV->GetNext() ));
1266 	}
1267 	return bRet;
1268 }
1269 
1270 // --> OD 2006-12-22 #i73788#
1271 boost::weak_ptr< SwAsyncRetrieveInputStreamThreadConsumer > SwGrfNode::GetThreadConsumer()
1272 {
1273     return mpThreadConsumer;
1274 }
1275 
1276 void SwGrfNode::TriggerAsyncRetrieveInputStream()
1277 {
1278     if ( !IsLinkedFile() )
1279     {
1280         ASSERT( false,
1281                 "<SwGrfNode::TriggerAsyncLoad()> - Method is misused. Method call is only valid for graphic nodes, which refer a linked graphic file" );
1282         return;
1283     }
1284 
1285     if ( mpThreadConsumer.get() == 0 )
1286     {
1287         mpThreadConsumer.reset( new SwAsyncRetrieveInputStreamThreadConsumer( *this ) );
1288 
1289         String sGrfNm;
1290         refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 );
1291 
1292         mpThreadConsumer->CreateThread( sGrfNm );
1293     }
1294 }
1295 
1296 bool SwGrfNode::IsLinkedInputStreamReady() const
1297 {
1298     return mbLinkedInputStreamReady;
1299 }
1300 
1301 void SwGrfNode::ApplyInputStream(
1302     com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xInputStream,
1303     const sal_Bool bIsStreamReadOnly )
1304 {
1305     if ( IsLinkedFile() )
1306     {
1307         if ( xInputStream.is() )
1308         {
1309             mxInputStream = xInputStream;
1310             mbIsStreamReadOnly = bIsStreamReadOnly;
1311             mbLinkedInputStreamReady = true;
1312             SwMsgPoolItem aMsgHint( RES_LINKED_GRAPHIC_STREAM_ARRIVED );
1313             ModifyNotification( &aMsgHint, &aMsgHint );
1314         }
1315     }
1316 }
1317 
1318 void SwGrfNode::UpdateLinkWithInputStream()
1319 {
1320     // --> OD #i85105#
1321     // do not work on link, if a <SwapIn> has been triggered.
1322     if ( !bInSwapIn && IsLinkedFile() )
1323     // <--
1324     {
1325         GetLink()->setStreamToLoadFrom( mxInputStream, mbIsStreamReadOnly );
1326         GetLink()->Update();
1327         SwMsgPoolItem aMsgHint( RES_GRAPHIC_ARRIVED );
1328         ModifyNotification( &aMsgHint, &aMsgHint );
1329 
1330         // --> OD 2008-06-18 #i88291#
1331         mxInputStream.clear();
1332         GetLink()->clearStreamToLoadFrom();
1333         // <--
1334         mbLinkedInputStreamReady = false;
1335         mpThreadConsumer.reset();
1336     }
1337 }
1338 // <--
1339 
1340 // --> OD 2008-07-21 #i90395#
1341 bool SwGrfNode::IsAsyncRetrieveInputStreamPossible() const
1342 {
1343     bool bRet = false;
1344 
1345     if ( IsLinkedFile() )
1346     {
1347         String sGrfNm;
1348         refLink->GetLinkManager()->GetDisplayNames( refLink, 0, &sGrfNm, 0, 0 );
1349         String sProtocol( RTL_CONSTASCII_STRINGPARAM( "vnd.sun.star.pkg:" ) );
1350         if ( sGrfNm.CompareTo( sProtocol, sProtocol.Len() ) != 0 )
1351         {
1352             bRet = true;
1353         }
1354     }
1355 
1356     return bRet;
1357 }
1358 // <--
1359