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