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