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