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