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