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