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