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