xref: /trunk/main/svx/source/svdraw/svdograf.cxx (revision c945f2553a89a0730a645e382b4d7941bc6e551c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #define _ANIMATION
28 #include <unotools/streamwrap.hxx>
29 
30 #include <sfx2/lnkbase.hxx>
31 #include <math.h>
32 #include <vcl/salbtype.hxx>
33 #include <sot/formats.hxx>
34 #include <sot/storage.hxx>
35 #include <unotools/ucbstreamhelper.hxx>
36 #include <unotools/localfilehelper.hxx>
37 #include <svl/style.hxx>
38 #include <svtools/filter.hxx>
39 #include <svl/urihelper.hxx>
40 #include <svtools/grfmgr.hxx>
41 #include <vcl/svapp.hxx>
42 
43 #include <sfx2/linkmgr.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <svx/svdetc.hxx>
46 #include "svx/svdglob.hxx"
47 #include "svx/svdstr.hrc"
48 #include <svx/svdpool.hxx>
49 #include <svx/svdmodel.hxx>
50 #include <svx/svdpage.hxx>
51 #include <svx/svdmrkv.hxx>
52 #include <svx/svdpagv.hxx>
53 #include "svx/svdviter.hxx"
54 #include <svx/svdview.hxx>
55 #include "svtools/filter.hxx"
56 #include <svx/svdograf.hxx>
57 #include <svx/svdogrp.hxx>
58 #include <svx/xbtmpit.hxx>
59 #include <svx/xflbmtit.hxx>
60 #include <svx/svdundo.hxx>
61 #include "svdfmtf.hxx"
62 #include <svx/sdgcpitm.hxx>
63 #include <editeng/eeitem.hxx>
64 #include <svx/sdr/properties/graphicproperties.hxx>
65 #include <svx/sdr/contact/viewcontactofgraphic.hxx>
66 #include <basegfx/polygon/b2dpolygon.hxx>
67 #include <basegfx/polygon/b2dpolygontools.hxx>
68 #include <osl/thread.hxx>
69 #include <vos/mutex.hxx>
70 #include <drawinglayer/processor2d/objectinfoextractor2d.hxx>
71 #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
72 
73 using namespace ::com::sun::star::uno;
74 using namespace ::com::sun::star::io;
75 
76 // -----------
77 // - Defines -
78 // -----------
79 
80 #define GRAFSTREAMPOS_INVALID   0xffffffff
81 #define SWAPGRAPHIC_TIMEOUT     5000
82 
83 
84 // ------------------
85 // - SdrGraphicLink -
86 // ------------------
87 
88 
89 const Graphic ImpLoadLinkedGraphic( const String aFileName, const String aFilterName )
90 {
91     Graphic aGraphic;
92 
93     SfxMedium xMed( aFileName, STREAM_STD_READ, sal_True );
94     xMed.DownLoad();
95 
96     SvStream* pInStrm = xMed.GetInStream();
97     if ( pInStrm )
98     {
99         pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
100         GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
101 
102         const sal_uInt16 nFilter = aFilterName.Len() && pGF->GetImportFormatCount()
103                             ? pGF->GetImportFormatNumber( aFilterName )
104                             : GRFILTER_FORMAT_DONTKNOW;
105 
106         String aEmptyStr;
107         com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aFilterData( 1 );
108 
109         // Room for improvment:
110         // As this is a linked graphic the GfxLink is not needed if saving/loading our own format.
111         // But this link is required by some filters to access the native graphic (pdf export/ms export),
112         // there we should create a new service to provide this data if needed
113         aFilterData[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
114         aFilterData[ 0 ].Value = Any( sal_True );
115         pGF->ImportGraphic( aGraphic, aEmptyStr, *pInStrm, nFilter, NULL, 0, &aFilterData );
116     }
117     return aGraphic;
118 }
119 
120 class SdrGraphicUpdater;
121 class SdrGraphicLink : public sfx2::SvBaseLink
122 {
123     SdrGrafObj*         pGrafObj;
124     SdrGraphicUpdater*  pGraphicUpdater;
125 
126 public:
127                         SdrGraphicLink(SdrGrafObj* pObj);
128     virtual             ~SdrGraphicLink();
129 
130     virtual void        Closed();
131     virtual void        DataChanged( const String& rMimeType,
132                                 const ::com::sun::star::uno::Any & rValue );
133     void                DataChanged( const Graphic& rGraphic );
134 
135     sal_Bool                Connect() { return 0 != GetRealObject(); }
136     void                UpdateAsynchron();
137     void                RemoveGraphicUpdater();
138 };
139 
140 class SdrGraphicUpdater : public ::osl::Thread
141 {
142 public:
143     SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& );
144     virtual ~SdrGraphicUpdater( void );
145 
146     void SAL_CALL Terminate( void );
147 
148     sal_Bool GraphicLinkChanged( const String& rFileName ){ return maFileName != rFileName; };
149 
150 protected:
151 
152     /** is called from the inherited create method and acts as the
153         main function of this thread.
154     */
155     virtual void SAL_CALL run(void);
156 
157     /** Called after the thread is terminated via the terminate
158         method.  Used to kill the thread by calling delete on this.
159     */
160     virtual void SAL_CALL onTerminated(void);
161 
162 private:
163 
164     const String    maFileName;
165     const String    maFilterName;
166     SdrGraphicLink& mrGraphicLink;
167 
168     volatile bool mbIsTerminated;
169 };
170 
171 SdrGraphicUpdater::SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& rGraphicLink )
172 : maFileName( rFileName )
173 , maFilterName( rFilterName )
174 , mrGraphicLink( rGraphicLink )
175 , mbIsTerminated( sal_False )
176 {
177     create();
178 }
179 
180 SdrGraphicUpdater::~SdrGraphicUpdater( void )
181 {
182 }
183 
184 void SdrGraphicUpdater::Terminate()
185 {
186     mbIsTerminated = sal_True;
187 }
188 
189 void SAL_CALL SdrGraphicUpdater::onTerminated(void)
190 {
191     delete this;
192 }
193 
194 void SAL_CALL SdrGraphicUpdater::run(void)
195 {
196     Graphic aGraphic( ImpLoadLinkedGraphic( maFileName, maFilterName ) );
197     vos::OGuard aSolarGuard( Application::GetSolarMutex() );
198     if ( !mbIsTerminated )
199     {
200         mrGraphicLink.DataChanged( aGraphic );
201         mrGraphicLink.RemoveGraphicUpdater();
202     }
203 }
204 
205 // -----------------------------------------------------------------------------
206 
207 SdrGraphicLink::SdrGraphicLink(SdrGrafObj* pObj)
208 : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB )
209 , pGrafObj( pObj )
210 , pGraphicUpdater( NULL )
211 {
212     SetSynchron( sal_False );
213 }
214 
215 // -----------------------------------------------------------------------------
216 
217 SdrGraphicLink::~SdrGraphicLink()
218 {
219     if ( pGraphicUpdater )
220         pGraphicUpdater->Terminate();
221 }
222 
223 // -----------------------------------------------------------------------------
224 
225 void SdrGraphicLink::DataChanged( const Graphic& rGraphic )
226 {
227     pGrafObj->ImpSetLinkedGraphic( rGraphic );
228 }
229 
230 // -----------------------------------------------------------------------------
231 
232 void SdrGraphicLink::RemoveGraphicUpdater()
233 {
234     pGraphicUpdater = NULL;
235 }
236 
237 // -----------------------------------------------------------------------------
238 
239 void SdrGraphicLink::DataChanged( const String& rMimeType,
240                                 const ::com::sun::star::uno::Any & rValue )
241 {
242     SdrModel*       pModel      = pGrafObj ? pGrafObj->GetModel() : 0;
243     sfx2::LinkManager* pLinkManager= pModel  ? pModel->GetLinkManager() : 0;
244 
245     if( pLinkManager && rValue.hasValue() )
246     {
247         pLinkManager->GetDisplayNames( this, 0, &pGrafObj->aFileName, 0, &pGrafObj->aFilterName );
248 
249         Graphic aGraphic;
250         if( sfx2::LinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
251         {
252             pGrafObj->NbcSetGraphic( aGraphic );
253             pGrafObj->ActionChanged();
254         }
255         else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() )
256         {
257             // broadcasting, to update slidesorter
258             pGrafObj->BroadcastObjectChange();
259         }
260     }
261 }
262 
263 // -----------------------------------------------------------------------------
264 
265 void SdrGraphicLink::Closed()
266 {
267     // Die Verbindung wird aufgehoben; pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
268     pGrafObj->ForceSwapIn();
269     pGrafObj->pGraphicLink=NULL;
270     pGrafObj->ReleaseGraphicLink();
271     SvBaseLink::Closed();
272 }
273 
274 // -----------------------------------------------------------------------------
275 
276 void SdrGraphicLink::UpdateAsynchron()
277 {
278     if( GetObj() )
279     {
280         if ( pGraphicUpdater )
281         {
282             if ( pGraphicUpdater->GraphicLinkChanged( pGrafObj->GetFileName() ) )
283             {
284                 pGraphicUpdater->Terminate();
285                 pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this );
286             }
287         }
288         else
289             pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this );
290     }
291 }
292 
293 // --------------
294 // - SdrGrafObj -
295 // --------------
296 
297 //////////////////////////////////////////////////////////////////////////////
298 // BaseProperties section
299 
300 sdr::properties::BaseProperties* SdrGrafObj::CreateObjectSpecificProperties()
301 {
302     return new sdr::properties::GraphicProperties(*this);
303 }
304 
305 //////////////////////////////////////////////////////////////////////////////
306 // DrawContact section
307 
308 sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
309 {
310     return new sdr::contact::ViewContactOfGraphic(*this);
311 }
312 
313 //////////////////////////////////////////////////////////////////////////////
314 // check if SVG and if try to get ObjectInfoPrimitive2D and extract info
315 
316 void SdrGrafObj::onGraphicChanged()
317 {
318     String aName;
319     String aTitle;
320     String aDesc;
321 
322     if(pGraphic)
323     {
324         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
325 
326         if(rSvgDataPtr.get())
327         {
328             const drawinglayer::primitive2d::Primitive2DSequence aSequence(rSvgDataPtr->getPrimitive2DSequence());
329 
330             if(aSequence.hasElements())
331             {
332                 drawinglayer::geometry::ViewInformation2D aViewInformation2D;
333                 drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor(aViewInformation2D);
334 
335                 aProcessor.process(aSequence);
336 
337                 const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult();
338 
339                 if(pResult)
340                 {
341                     aName = pResult->getName();
342                     aTitle = pResult->getTitle();
343                     aDesc = pResult->getDesc();
344                 }
345             }
346         }
347     }
348 
349     if(aName.Len())
350     {
351         SetName(aName);
352     }
353 
354     if(aTitle.Len())
355     {
356         SetTitle(aTitle);
357     }
358 
359     if(aDesc.Len())
360     {
361         SetDescription(aDesc);
362     }
363 }
364 
365 //////////////////////////////////////////////////////////////////////////////
366 
367 TYPEINIT1(SdrGrafObj,SdrRectObj);
368 
369 // -----------------------------------------------------------------------------
370 
371 SdrGrafObj::SdrGrafObj()
372 :   SdrRectObj(),
373     pGraphicLink    ( NULL ),
374     bMirrored       ( sal_False )
375 {
376     pGraphic = new GraphicObject;
377     mpReplacementGraphic = 0;
378     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
379     onGraphicChanged();
380 
381     // #i118485# Shear allowed and possible now
382     bNoShear = false;
383 
384     // #111096#
385     mbGrafAnimationAllowed = sal_True;
386 
387     // #i25616#
388     mbLineIsOutsideGeometry = sal_True;
389     mbInsidePaint = sal_False;
390     mbIsPreview = sal_False;
391 
392     // #i25616#
393     mbSupportTextIndentingOnLineWidthChange = sal_False;
394 }
395 
396 // -----------------------------------------------------------------------------
397 
398 SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
399 :   SdrRectObj      ( rRect ),
400     pGraphicLink    ( NULL ),
401     bMirrored       ( sal_False )
402 {
403     pGraphic = new GraphicObject( rGrf );
404     mpReplacementGraphic = 0;
405     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
406     onGraphicChanged();
407 
408     // #i118485# Shear allowed and possible now
409     bNoShear = false;
410 
411     // #111096#
412     mbGrafAnimationAllowed = sal_True;
413 
414     // #i25616#
415     mbLineIsOutsideGeometry = sal_True;
416     mbInsidePaint = sal_False;
417     mbIsPreview = sal_False;
418 
419     // #i25616#
420     mbSupportTextIndentingOnLineWidthChange = sal_False;
421 }
422 
423 // -----------------------------------------------------------------------------
424 
425 SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
426 :   SdrRectObj(),
427     pGraphicLink    ( NULL ),
428     bMirrored       ( sal_False )
429 {
430     pGraphic = new GraphicObject( rGrf );
431     mpReplacementGraphic = 0;
432     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
433     onGraphicChanged();
434 
435     // #i118485# Shear allowed and possible now
436     bNoShear = false;
437 
438     // #111096#
439     mbGrafAnimationAllowed = sal_True;
440 
441     // #i25616#
442     mbLineIsOutsideGeometry = sal_True;
443     mbInsidePaint = sal_False;
444     mbIsPreview = sal_False;
445 
446     // #i25616#
447     mbSupportTextIndentingOnLineWidthChange = sal_False;
448 }
449 
450 // -----------------------------------------------------------------------------
451 
452 SdrGrafObj::~SdrGrafObj()
453 {
454     delete pGraphic;
455     delete mpReplacementGraphic;
456     ImpLinkAbmeldung();
457 }
458 
459 // -----------------------------------------------------------------------------
460 
461 void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
462 {
463     *pGraphic = rGrfObj;
464     delete mpReplacementGraphic;
465     mpReplacementGraphic = 0;
466     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
467     pGraphic->SetUserData();
468     mbIsPreview = sal_False;
469     SetChanged();
470     BroadcastObjectChange();
471     onGraphicChanged();
472 }
473 
474 // -----------------------------------------------------------------------------
475 
476 const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
477 {
478     if(bForceSwapIn)
479     {
480         ForceSwapIn();
481     }
482 
483     return *pGraphic;
484 }
485 
486 const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
487 {
488     if(!mpReplacementGraphic && pGraphic)
489     {
490         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
491 
492         if(rSvgDataPtr.get())
493         {
494             const_cast< SdrGrafObj* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement());
495         }
496     }
497 
498     return mpReplacementGraphic;
499 }
500 
501 // -----------------------------------------------------------------------------
502 
503 void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
504 {
505     pGraphic->SetGraphic( rGrf );
506     delete mpReplacementGraphic;
507     mpReplacementGraphic = 0;
508     pGraphic->SetUserData();
509     mbIsPreview = sal_False;
510     onGraphicChanged();
511 }
512 
513 void SdrGrafObj::SetGraphic( const Graphic& rGrf )
514 {
515     NbcSetGraphic(rGrf);
516     SetChanged();
517     BroadcastObjectChange();
518 }
519 
520 // -----------------------------------------------------------------------------
521 
522 const Graphic& SdrGrafObj::GetGraphic() const
523 {
524     ForceSwapIn();
525     return pGraphic->GetGraphic();
526 }
527 
528 // -----------------------------------------------------------------------------
529 
530 Graphic SdrGrafObj::GetTransformedGraphic( sal_uIntPtr nTransformFlags ) const
531 {
532     // #107947# Refactored most of the code to GraphicObject, where
533     // everybody can use e.g. the cropping functionality
534 
535     GraphicType     eType = GetGraphicType();
536     MapMode         aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() );
537     const Size      aDestSize( GetLogicRect().GetSize() );
538     const sal_Bool      bMirror = ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR ) != 0;
539     const sal_Bool      bRotate = ( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) != 0 ) &&
540         ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType );
541 
542     // #104115# Need cropping info earlier
543     ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo();
544     GraphicAttr aActAttr;
545 
546     if( SDRGRAFOBJ_TRANSFORMATTR_NONE != nTransformFlags &&
547         GRAPHIC_NONE != eType )
548     {
549         // actually transform the graphic only in this case. On the
550         // other hand, cropping will always happen
551         aActAttr = aGrafInfo;
552 
553         if( bMirror )
554         {
555             sal_uInt16      nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
556             FASTBOOL    bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
557             FASTBOOL    bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
558 
559             aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );
560         }
561 
562         if( bRotate )
563             aActAttr.SetRotation( sal_uInt16(aGeo.nDrehWink / 10) );
564     }
565 
566     // #107947# Delegate to moved code in GraphicObject
567     return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
568 }
569 
570 // -----------------------------------------------------------------------------
571 
572 GraphicType SdrGrafObj::GetGraphicType() const
573 {
574     return pGraphic->GetType();
575 }
576 
577 sal_Bool SdrGrafObj::IsAnimated() const
578 {
579     return pGraphic->IsAnimated();
580 }
581 
582 sal_Bool SdrGrafObj::IsEPS() const
583 {
584     return pGraphic->IsEPS();
585 }
586 
587 sal_Bool SdrGrafObj::IsSwappedOut() const
588 {
589     return mbIsPreview ? sal_True : pGraphic->IsSwappedOut();
590 }
591 
592 const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
593 {
594     return pGraphic->GetPrefMapMode();
595 }
596 
597 const Size& SdrGrafObj::GetGrafPrefSize() const
598 {
599     return pGraphic->GetPrefSize();
600 }
601 
602 // -----------------------------------------------------------------------------
603 
604 void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL )
605 {
606     mbIsPreview = sal_False;
607     if( !rGraphicStreamURL.Len() )
608     {
609         pGraphic->SetUserData();
610     }
611     else if( pModel->IsSwapGraphics() )
612     {
613         pGraphic->SetUserData( rGraphicStreamURL );
614 
615         // set state of graphic object to 'swapped out'
616         if( pGraphic->GetType() == GRAPHIC_NONE )
617             pGraphic->SetSwapState();
618     }
619 }
620 
621 // -----------------------------------------------------------------------------
622 
623 String SdrGrafObj::GetGrafStreamURL() const
624 {
625     return pGraphic->GetUserData();
626 }
627 
628 // -----------------------------------------------------------------------------
629 
630 void SdrGrafObj::SetFileName(const String& rFileName)
631 {
632     aFileName = rFileName;
633     SetChanged();
634 }
635 
636 // -----------------------------------------------------------------------------
637 
638 void SdrGrafObj::SetFilterName(const String& rFilterName)
639 {
640     aFilterName = rFilterName;
641     SetChanged();
642 }
643 
644 // -----------------------------------------------------------------------------
645 
646 void SdrGrafObj::ForceSwapIn() const
647 {
648     if( mbIsPreview )
649     {
650         // removing preview graphic
651         const String aUserData( pGraphic->GetUserData() );
652 
653         Graphic aEmpty;
654         pGraphic->SetGraphic( aEmpty );
655         pGraphic->SetUserData( aUserData );
656         pGraphic->SetSwapState();
657 
658         const_cast< SdrGrafObj* >( this )->mbIsPreview = sal_False;
659     }
660     if ( pGraphicLink && pGraphic->IsSwappedOut() )
661         ImpUpdateGraphicLink( sal_False );
662     else
663         pGraphic->FireSwapInRequest();
664 
665     if( pGraphic->IsSwappedOut() ||
666         ( pGraphic->GetType() == GRAPHIC_NONE ) ||
667         ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
668     {
669         Graphic aDefaultGraphic;
670         aDefaultGraphic.SetDefaultType();
671         pGraphic->SetGraphic( aDefaultGraphic );
672     }
673 }
674 
675 // -----------------------------------------------------------------------------
676 
677 void SdrGrafObj::ForceSwapOut() const
678 {
679     pGraphic->FireSwapOutRequest();
680 }
681 
682 // -----------------------------------------------------------------------------
683 
684 void SdrGrafObj::ImpLinkAnmeldung()
685 {
686     sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
687 
688     if( pLinkManager != NULL && pGraphicLink == NULL )
689     {
690         if( aFileName.Len() )
691         {
692             pGraphicLink = new SdrGraphicLink( this );
693             pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL );
694             pGraphicLink->Connect();
695         }
696     }
697 }
698 
699 // -----------------------------------------------------------------------------
700 
701 void SdrGrafObj::ImpLinkAbmeldung()
702 {
703     sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
704 
705     if( pLinkManager != NULL && pGraphicLink!=NULL)
706     {
707         // Bei Remove wird *pGraphicLink implizit deleted
708         pLinkManager->Remove( pGraphicLink );
709         pGraphicLink=NULL;
710     }
711 }
712 
713 // -----------------------------------------------------------------------------
714 
715 void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName )
716 {
717     ImpLinkAbmeldung();
718     aFileName = rFileName;
719     aFilterName = rFilterName;
720     ImpLinkAnmeldung();
721     pGraphic->SetUserData();
722 
723     // #92205# A linked graphic is per definition swapped out (has to be loaded)
724     pGraphic->SetSwapState();
725 }
726 
727 // -----------------------------------------------------------------------------
728 
729 void SdrGrafObj::ReleaseGraphicLink()
730 {
731     ImpLinkAbmeldung();
732     aFileName = String();
733     aFilterName = String();
734 }
735 
736 // -----------------------------------------------------------------------------
737 
738 void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
739 {
740     FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
741 
742     rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
743                                aGeo.nDrehWink % 18000 == 0 ||
744                                aGeo.nDrehWink % 27000 == 0;
745 
746     rInfo.bResizePropAllowed = sal_True;
747     rInfo.bRotateFreeAllowed = bNoPresGrf;
748     rInfo.bRotate90Allowed = bNoPresGrf;
749     rInfo.bMirrorFreeAllowed = bNoPresGrf;
750     rInfo.bMirror45Allowed = bNoPresGrf;
751     rInfo.bMirror90Allowed = !bEmptyPresObj;
752     rInfo.bTransparenceAllowed = sal_False;
753     rInfo.bGradientAllowed = sal_False;
754 
755     // #i118485# Shear allowed and possible now
756     rInfo.bShearAllowed = true;
757 
758     rInfo.bEdgeRadiusAllowed=sal_False;
759     rInfo.bCanConvToPath = !IsEPS();
760     rInfo.bCanConvToPathLineToArea = sal_False;
761     rInfo.bCanConvToPolyLineToArea = sal_False;
762     rInfo.bCanConvToPoly = !IsEPS();
763     rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
764 }
765 
766 // -----------------------------------------------------------------------------
767 
768 sal_uInt16 SdrGrafObj::GetObjIdentifier() const
769 {
770     return sal_uInt16( OBJ_GRAF );
771 }
772 
773 // -----------------------------------------------------------------------------
774 
775 /* The graphic of the GraphicLink will be loaded. If it is called with
776    bAsynchron = true then the graphic will be set later via DataChanged
777 */
778 sal_Bool SdrGrafObj::ImpUpdateGraphicLink( sal_Bool bAsynchron ) const
779 {
780     sal_Bool bRet = sal_False;
781     if( pGraphicLink )
782     {
783         if ( bAsynchron )
784             pGraphicLink->UpdateAsynchron();
785         else
786             pGraphicLink->DataChanged( ImpLoadLinkedGraphic( aFileName, aFilterName ) );
787         bRet = sal_True;
788     }
789     return bRet;
790 }
791 
792 // -----------------------------------------------------------------------------
793 
794 void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
795 {
796     const sal_Bool bIsChanged = GetModel()->IsChanged();
797     NbcSetGraphic( rGraphic );
798     ActionChanged();
799     BroadcastObjectChange();
800     GetModel()->SetChanged( bIsChanged );
801 }
802 
803 // -----------------------------------------------------------------------------
804 
805 void SdrGrafObj::TakeObjNameSingul(XubString& rName) const
806 {
807     if(pGraphic)
808     {
809         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
810 
811         if(rSvgDataPtr.get())
812         {
813             rName = ImpGetResStr(STR_ObjNameSingulGRAFSVG);
814         }
815         else
816         {
817             switch( pGraphic->GetType() )
818             {
819                 case GRAPHIC_BITMAP:
820                 {
821                     const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
822                                          ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
823                                          ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
824 
825                     rName=ImpGetResStr( nId );
826                 }
827                 break;
828 
829                 case GRAPHIC_GDIMETAFILE:
830                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF );
831                 break;
832 
833                 case GRAPHIC_NONE:
834                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE );
835                 break;
836 
837                 default:
838                     rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF );
839                 break;
840             }
841         }
842 
843         const String aName(GetName());
844 
845         if( aName.Len() )
846         {
847             rName.AppendAscii( " '" );
848             rName += aName;
849             rName += sal_Unicode( '\'' );
850         }
851     }
852 }
853 
854 // -----------------------------------------------------------------------------
855 
856 void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const
857 {
858     if(pGraphic)
859     {
860         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
861 
862         if(rSvgDataPtr.get())
863         {
864             rName = ImpGetResStr(STR_ObjNamePluralGRAFSVG);
865         }
866         else
867         {
868             switch( pGraphic->GetType() )
869             {
870                 case GRAPHIC_BITMAP:
871                 {
872                     const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
873                                          ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
874                                          ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
875 
876                     rName=ImpGetResStr( nId );
877                 }
878                 break;
879 
880                 case GRAPHIC_GDIMETAFILE:
881                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF );
882                 break;
883 
884                 case GRAPHIC_NONE:
885                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE );
886                 break;
887 
888                 default:
889                     rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF );
890                 break;
891             }
892         }
893 
894         const String aName(GetName());
895 
896         if( aName.Len() )
897         {
898             rName.AppendAscii( " '" );
899             rName += aName;
900             rName += sal_Unicode( '\'' );
901         }
902     }
903 }
904 
905 // -----------------------------------------------------------------------------
906 
907 SdrObject* SdrGrafObj::getFullDragClone() const
908 {
909     // call parent
910     SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
911 
912     // #i103116# the full drag clone leads to problems
913     // with linked graphics, so reset the link in this
914     // temporary interaction object and load graphic
915     if(pRetval && IsLinkedGraphic())
916     {
917         pRetval->ForceSwapIn();
918         pRetval->ReleaseGraphicLink();
919     }
920 
921     return pRetval;
922 }
923 
924 void SdrGrafObj::operator=( const SdrObject& rObj )
925 {
926     SdrRectObj::operator=( rObj );
927 
928     const SdrGrafObj& rGraf = (SdrGrafObj&) rObj;
929 
930     pGraphic->SetGraphic( rGraf.GetGraphic(), &rGraf.GetGraphicObject() );
931     aCropRect = rGraf.aCropRect;
932     aFileName = rGraf.aFileName;
933     aFilterName = rGraf.aFilterName;
934     bMirrored = rGraf.bMirrored;
935 
936     if( rGraf.pGraphicLink != NULL)
937     {
938         SetGraphicLink( aFileName, aFilterName );
939     }
940 
941     ImpSetAttrToGrafInfo();
942 }
943 
944 // -----------------------------------------------------------------------------
945 // #i25616#
946 
947 basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const
948 {
949     if(mbInsidePaint)
950     {
951         basegfx::B2DPolyPolygon aRetval;
952 
953         // take grown rectangle
954         const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2);
955         const Rectangle aGrownRect(
956             aRect.Left() - nHalfLineWidth,
957             aRect.Top() - nHalfLineWidth,
958             aRect.Right() + nHalfLineWidth,
959             aRect.Bottom() + nHalfLineWidth);
960 
961         XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius()));
962         aRetval.append(aXPoly.getB2DPolygon());
963 
964         return aRetval;
965     }
966     else
967     {
968         // call parent
969         return SdrRectObj::TakeXorPoly();
970     }
971 }
972 
973 // -----------------------------------------------------------------------------
974 
975 sal_uInt32 SdrGrafObj::GetHdlCount() const
976 {
977     return 8L;
978 }
979 
980 // -----------------------------------------------------------------------------
981 
982 SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
983 {
984     return SdrRectObj::GetHdl( nHdlNum + 1L );
985 }
986 
987 // -----------------------------------------------------------------------------
988 
989 void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
990 {
991     SdrRectObj::NbcResize( rRef, xFact, yFact );
992 
993     FASTBOOL bMirrX = xFact.GetNumerator() < 0;
994     FASTBOOL bMirrY = yFact.GetNumerator() < 0;
995 
996     if( bMirrX != bMirrY )
997         bMirrored = !bMirrored;
998 }
999 
1000 // -----------------------------------------------------------------------------
1001 
1002 void SdrGrafObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
1003 {
1004     SdrRectObj::NbcRotate(rRef,nWink,sn,cs);
1005 }
1006 
1007 // -----------------------------------------------------------------------------
1008 
1009 void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
1010 {
1011     SdrRectObj::NbcMirror(rRef1,rRef2);
1012     bMirrored = !bMirrored;
1013 }
1014 
1015 // -----------------------------------------------------------------------------
1016 
1017 void SdrGrafObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
1018 {
1019     // #i118485# Call Shear now, old version redirected to rotate
1020     SdrRectObj::NbcShear(rRef, nWink, tn, bVShear);
1021 }
1022 
1023 // -----------------------------------------------------------------------------
1024 
1025 void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect)
1026 {
1027     SdrRectObj::NbcSetSnapRect(rRect);
1028 }
1029 
1030 // -----------------------------------------------------------------------------
1031 
1032 void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect)
1033 {
1034     //int bChg=rRect.GetSize()!=aRect.GetSize();
1035     SdrRectObj::NbcSetLogicRect(rRect);
1036 }
1037 
1038 // -----------------------------------------------------------------------------
1039 
1040 SdrObjGeoData* SdrGrafObj::NewGeoData() const
1041 {
1042     return new SdrGrafObjGeoData;
1043 }
1044 
1045 // -----------------------------------------------------------------------------
1046 
1047 void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
1048 {
1049     SdrRectObj::SaveGeoData(rGeo);
1050     SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
1051     rGGeo.bMirrored=bMirrored;
1052 }
1053 
1054 // -----------------------------------------------------------------------------
1055 
1056 void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo)
1057 {
1058     //long      nDrehMerk = aGeo.nDrehWink;
1059     //long      nShearMerk = aGeo.nShearWink;
1060     //int   bMirrMerk = bMirrored;
1061     Size        aSizMerk( aRect.GetSize() );
1062 
1063     SdrRectObj::RestGeoData(rGeo);
1064     SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
1065     bMirrored=rGGeo.bMirrored;
1066 }
1067 
1068 // -----------------------------------------------------------------------------
1069 
1070 void SdrGrafObj::SetPage( SdrPage* pNewPage )
1071 {
1072     FASTBOOL bRemove = pNewPage == NULL && pPage != NULL;
1073     FASTBOOL bInsert = pNewPage != NULL && pPage == NULL;
1074 
1075     if( bRemove )
1076     {
1077         // hier kein SwapIn noetig, weil wenn nicht geladen, dann auch nicht animiert.
1078         if( pGraphic->IsAnimated())
1079             pGraphic->StopAnimation();
1080 
1081         if( pGraphicLink != NULL )
1082             ImpLinkAbmeldung();
1083     }
1084 
1085     if(!pModel && !GetStyleSheet() && pNewPage->GetModel())
1086     {
1087         // #119287# Set default StyleSheet for SdrGrafObj here, it is different from 'Default'. This
1088         // needs to be done before the style 'Default' is set from the :SetModel() call which is triggered
1089         // from the following :SetPage().
1090         // TTTT: Needs to be moved in branch aw080 due to having a SdrModel from the beginning, is at this
1091         // place for convenience currently (works in both versions, is not in the way)
1092         SfxStyleSheet* pSheet = pNewPage->GetModel()->GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj();
1093 
1094         if(pSheet)
1095         {
1096             SetStyleSheet(pSheet, false);
1097         }
1098         else
1099         {
1100             SetMergedItem(XFillStyleItem(XFILL_NONE));
1101             SetMergedItem(XLineStyleItem(XLINE_NONE));
1102         }
1103     }
1104 
1105     SdrRectObj::SetPage( pNewPage );
1106 
1107     if(aFileName.Len() && bInsert)
1108         ImpLinkAnmeldung();
1109 }
1110 
1111 // -----------------------------------------------------------------------------
1112 
1113 void SdrGrafObj::SetModel( SdrModel* pNewModel )
1114 {
1115     FASTBOOL bChg = pNewModel != pModel;
1116 
1117     if( bChg )
1118     {
1119         if( pGraphic->HasUserData() )
1120         {
1121             ForceSwapIn();
1122             pGraphic->SetUserData();
1123         }
1124 
1125         if( pGraphicLink != NULL )
1126             ImpLinkAbmeldung();
1127     }
1128 
1129     // Model umsetzen
1130     SdrRectObj::SetModel(pNewModel);
1131 
1132     if( bChg && aFileName.Len() )
1133         ImpLinkAnmeldung();
1134 }
1135 
1136 // -----------------------------------------------------------------------------
1137 
1138 void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/)
1139 {
1140     // #111096#
1141     // use new graf animation
1142     SetGrafAnimationAllowed(sal_True);
1143 }
1144 
1145 // -----------------------------------------------------------------------------
1146 
1147 void SdrGrafObj::StopAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1148 {
1149     // #111096#
1150     // use new graf animation
1151     SetGrafAnimationAllowed(sal_False);
1152 }
1153 
1154 // -----------------------------------------------------------------------------
1155 
1156 FASTBOOL SdrGrafObj::HasGDIMetaFile() const
1157 {
1158     return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE );
1159 }
1160 
1161 // -----------------------------------------------------------------------------
1162 
1163 const GDIMetaFile* SdrGrafObj::GetGDIMetaFile() const
1164 {
1165     DBG_ERROR( "Invalid return value! Don't use it! (KA)" );
1166     return &GetGraphic().GetGDIMetaFile();
1167 }
1168 
1169 // -----------------------------------------------------------------------------
1170 
1171 bool SdrGrafObj::isEmbeddedSvg() const
1172 {
1173     return GRAPHIC_BITMAP == GetGraphicType() && GetGraphic().getSvgData().get();
1174 }
1175 
1176 GDIMetaFile SdrGrafObj::getMetafileFromEmbeddedSvg() const
1177 {
1178     GDIMetaFile aRetval;
1179 
1180     if(isEmbeddedSvg() && GetModel())
1181     {
1182         VirtualDevice aOut;
1183         const Rectangle aBoundRect(GetCurrentBoundRect());
1184         const MapMode aMap(GetModel()->GetScaleUnit(), Point(), GetModel()->GetScaleFraction(), GetModel()->GetScaleFraction());
1185 
1186         aOut.EnableOutput(false);
1187         aOut.SetMapMode(aMap);
1188         aRetval.Record(&aOut);
1189         SingleObjectPainter(aOut);
1190         aRetval.Stop();
1191         aRetval.WindStart();
1192         aRetval.Move(-aBoundRect.Left(), -aBoundRect.Top());
1193         aRetval.SetPrefMapMode(aMap);
1194         aRetval.SetPrefSize(aBoundRect.GetSize());
1195     }
1196 
1197     return aRetval;
1198 }
1199 
1200 SdrObject* SdrGrafObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
1201 {
1202     SdrObject* pRetval = NULL;
1203     GraphicType aGraphicType(GetGraphicType());
1204     GDIMetaFile aMtf;
1205 
1206     if(isEmbeddedSvg())
1207     {
1208         // Embedded Svg
1209         // There is currently no helper to create SdrObjects from primitives (even if I'm thinking
1210         // about writing one for some time). To get the roundtrip to SdrObjects it is necessary to
1211         // use the old converter path over the MetaFile mechanism. Create Metafile from Svg
1212         // primitives here pretty directly
1213         aMtf = getMetafileFromEmbeddedSvg();
1214         aGraphicType = GRAPHIC_GDIMETAFILE;
1215     }
1216     else if(GRAPHIC_GDIMETAFILE == aGraphicType)
1217     {
1218         aMtf = GetTransformedGraphic(SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile();
1219     }
1220 
1221     switch(aGraphicType)
1222     {
1223         case GRAPHIC_GDIMETAFILE:
1224         {
1225             // NUR die aus dem MetaFile erzeugbaren Objekte in eine Gruppe packen und zurueckliefern
1226             ImpSdrGDIMetaFileImport aFilter(*GetModel(), GetLayer(), aRect);
1227             SdrObjGroup* pGrp = new SdrObjGroup();
1228             sal_uInt32 nInsAnz = aFilter.DoImport(aMtf, *pGrp->GetSubList(), 0);
1229 
1230             if(nInsAnz)
1231             {
1232                 {
1233                         // copy transformation
1234                     GeoStat aGeoStat(GetGeoStat());
1235 
1236                     if(aGeoStat.nShearWink)
1237                     {
1238                         aGeoStat.RecalcTan();
1239                         pGrp->NbcShear(aRect.TopLeft(), aGeoStat.nShearWink, aGeoStat.nTan, false);
1240                     }
1241 
1242                     if(aGeoStat.nDrehWink)
1243                     {
1244                         aGeoStat.RecalcSinCos();
1245                         pGrp->NbcRotate(aRect.TopLeft(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1246                     }
1247                 }
1248 
1249                 pRetval = pGrp;
1250                 pGrp->NbcSetLayer(GetLayer());
1251                 pGrp->SetModel(GetModel());
1252 
1253                 if(bAddText)
1254                 {
1255                     pRetval = ImpConvertAddText(pRetval, bBezier);
1256                 }
1257 
1258                 // convert all children
1259                 if( pRetval )
1260                 {
1261                     SdrObject* pHalfDone = pRetval;
1262                     pRetval = pHalfDone->DoConvertToPolyObj(bBezier, bAddText);
1263                     SdrObject::Free( pHalfDone ); // resulting object is newly created
1264 
1265                     if( pRetval )
1266                     {
1267                         // flatten subgroups. As we call
1268                         // DoConvertToPolyObj() on the resulting group
1269                         // objects, subgroups can exist (e.g. text is
1270                         // a group object for every line).
1271                         SdrObjList* pList = pRetval->GetSubList();
1272                         if( pList )
1273                             pList->FlattenGroups();
1274                     }
1275                 }
1276             }
1277             else
1278             {
1279                 delete pGrp;
1280             }
1281 
1282             // #i118485# convert line and fill
1283             SdrObject* pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false);
1284 
1285             if(pLineFill)
1286             {
1287                 if(pRetval)
1288                 {
1289                     pGrp = dynamic_cast< SdrObjGroup* >(pRetval);
1290 
1291                     if(!pGrp)
1292                     {
1293                         pGrp = new SdrObjGroup();
1294 
1295                         pGrp->NbcSetLayer(GetLayer());
1296                         pGrp->SetModel(GetModel());
1297                         pGrp->GetSubList()->NbcInsertObject(pRetval);
1298                     }
1299 
1300                     pGrp->GetSubList()->NbcInsertObject(pLineFill, 0);
1301                 }
1302                 else
1303                 {
1304                     pRetval = pLineFill;
1305                 }
1306             }
1307 
1308             break;
1309         }
1310         case GRAPHIC_BITMAP:
1311         {
1312             // Grundobjekt kreieren und Fuellung ergaenzen
1313             pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1314 
1315             // Bitmap als Attribut retten
1316             if(pRetval)
1317             {
1318                 // Bitmap als Fuellung holen
1319                 SfxItemSet aSet(GetObjectItemSet());
1320 
1321                 aSet.Put(XFillStyleItem(XFILL_BITMAP));
1322                 const BitmapEx aBitmapEx(GetTransformedGraphic().GetBitmapEx());
1323                 aSet.Put(XFillBitmapItem(String(), Graphic(aBitmapEx)));
1324                 aSet.Put(XFillBmpTileItem(false));
1325 
1326                 pRetval->SetMergedItemSet(aSet);
1327             }
1328             break;
1329         }
1330         case GRAPHIC_NONE:
1331         case GRAPHIC_DEFAULT:
1332         {
1333             pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1334             break;
1335         }
1336     }
1337 
1338     return pRetval;
1339 }
1340 
1341 // -----------------------------------------------------------------------------
1342 
1343 void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1344 {
1345     SetXPolyDirty();
1346     SdrRectObj::Notify( rBC, rHint );
1347     ImpSetAttrToGrafInfo();
1348 }
1349 
1350 void SdrGrafObj::ImpSetAttrToGrafInfo()
1351 {
1352     const SfxItemSet& rSet = GetObjectItemSet();
1353     const sal_uInt16 nTrans = ( (SdrGrafTransparenceItem&) rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue();
1354     const SdrGrafCropItem&  rCrop = (const SdrGrafCropItem&) rSet.Get( SDRATTR_GRAFCROP );
1355 
1356     aGrafInfo.SetLuminance( ( (SdrGrafLuminanceItem&) rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() );
1357     aGrafInfo.SetContrast( ( (SdrGrafContrastItem&) rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() );
1358     aGrafInfo.SetChannelR( ( (SdrGrafRedItem&) rSet.Get( SDRATTR_GRAFRED ) ).GetValue() );
1359     aGrafInfo.SetChannelG( ( (SdrGrafGreenItem&) rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() );
1360     aGrafInfo.SetChannelB( ( (SdrGrafBlueItem&) rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() );
1361     aGrafInfo.SetGamma( ( (SdrGrafGamma100Item&) rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 );
1362     aGrafInfo.SetTransparency( (sal_uInt8) FRound( Min( nTrans, (sal_uInt16) 100 )  * 2.55 ) );
1363     aGrafInfo.SetInvert( ( (SdrGrafInvertItem&) rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() );
1364     aGrafInfo.SetDrawMode( ( (SdrGrafModeItem&) rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() );
1365     aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
1366 
1367     SetXPolyDirty();
1368     SetRectsDirty();
1369 }
1370 
1371 // -----------------------------------------------------------------------------
1372 
1373 void SdrGrafObj::ImpSetGrafInfoToAttr()
1374 {
1375     SetObjectItem( SdrGrafLuminanceItem( aGrafInfo.GetLuminance() ) );
1376     SetObjectItem( SdrGrafContrastItem( aGrafInfo.GetContrast() ) );
1377     SetObjectItem( SdrGrafRedItem( aGrafInfo.GetChannelR() ) );
1378     SetObjectItem( SdrGrafGreenItem( aGrafInfo.GetChannelG() ) );
1379     SetObjectItem( SdrGrafBlueItem( aGrafInfo.GetChannelB() ) );
1380     SetObjectItem( SdrGrafGamma100Item( FRound( aGrafInfo.GetGamma() * 100.0 ) ) );
1381     SetObjectItem( SdrGrafTransparenceItem( (sal_uInt16) FRound( aGrafInfo.GetTransparency() / 2.55 ) ) );
1382     SetObjectItem( SdrGrafInvertItem( aGrafInfo.IsInvert() ) );
1383     SetObjectItem( SdrGrafModeItem( aGrafInfo.GetDrawMode() ) );
1384     SetObjectItem( SdrGrafCropItem( aGrafInfo.GetLeftCrop(), aGrafInfo.GetTopCrop(), aGrafInfo.GetRightCrop(), aGrafInfo.GetBottomCrop() ) );
1385 }
1386 
1387 // -----------------------------------------------------------------------------
1388 
1389 void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly )
1390 {
1391     Size aSize;
1392     Size aMaxSize( rMaxRect.GetSize() );
1393     if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1394         aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM );
1395     else
1396         aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1397                                             pGraphic->GetPrefMapMode(),
1398                                             MapMode( MAP_100TH_MM ) );
1399 
1400     if( aSize.Height() != 0 && aSize.Width() != 0 )
1401     {
1402         Point aPos( rMaxRect.TopLeft() );
1403 
1404         // Falls Grafik zu gross, wird die Grafik
1405         // in die Seite eingepasst
1406         if ( (!bShrinkOnly                          ||
1407              ( aSize.Height() > aMaxSize.Height() ) ||
1408             ( aSize.Width()  > aMaxSize.Width()  ) )&&
1409             aSize.Height() && aMaxSize.Height() )
1410         {
1411             float fGrfWH =  (float)aSize.Width() /
1412                             (float)aSize.Height();
1413             float fWinWH =  (float)aMaxSize.Width() /
1414                             (float)aMaxSize.Height();
1415 
1416             // Grafik an Pagesize anpassen (skaliert)
1417             if ( fGrfWH < fWinWH )
1418             {
1419                 aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
1420                 aSize.Height()= aMaxSize.Height();
1421             }
1422             else if ( fGrfWH > 0.F )
1423             {
1424                 aSize.Width() = aMaxSize.Width();
1425                 aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
1426             }
1427 
1428             aPos = rMaxRect.Center();
1429         }
1430 
1431         if( bShrinkOnly )
1432             aPos = aRect.TopLeft();
1433 
1434         aPos.X() -= aSize.Width() / 2;
1435         aPos.Y() -= aSize.Height() / 2;
1436         SetLogicRect( Rectangle( aPos, aSize ) );
1437     }
1438 }
1439 
1440 // -----------------------------------------------------------------------------
1441 
1442 IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
1443 {
1444     SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1445 
1446     if( pO->IsInSwapOut() )
1447     {
1448         if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
1449         {
1450             // test if this object is visualized from someone
1451             // ## test only if there are VOCs other than the preview renderer
1452             if(!GetViewContact().HasViewObjectContacts(true))
1453             {
1454                 const sal_uIntPtr   nSwapMode = pModel->GetSwapGraphicsMode();
1455 
1456                 if( ( pGraphic->HasUserData() || pGraphicLink ) &&
1457                     ( nSwapMode & SDR_SWAPGRAPHICSMODE_PURGE ) )
1458                 {
1459                     pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1460                 }
1461                 else if( nSwapMode & SDR_SWAPGRAPHICSMODE_TEMP )
1462                 {
1463                     pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1464                     pGraphic->SetUserData();
1465                 }
1466 
1467                 // #i102380#
1468                 sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
1469 
1470                 if(pVC)
1471                 {
1472                     pVC->flushGraphicObjects();
1473                 }
1474             }
1475         }
1476     }
1477     else if( pO->IsInSwapIn() )
1478     {
1479         // kann aus dem original Doc-Stream nachgeladen werden...
1480         if( pModel != NULL )
1481         {
1482             if( pGraphic->HasUserData() )
1483             {
1484                 SdrDocumentStreamInfo aStreamInfo;
1485 
1486                 aStreamInfo.mbDeleteAfterUse = sal_False;
1487                 aStreamInfo.maUserData = pGraphic->GetUserData();
1488 
1489                 SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1490 
1491                 if( pStream != NULL )
1492                 {
1493                     Graphic aGraphic;
1494 
1495                     com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL;
1496 
1497                     if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
1498                     {
1499                         pFilterData = new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 );
1500 
1501                         com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
1502                         sal_Bool bAllowPartialStreamRead = sal_True;
1503                         sal_Bool bCreateNativeLink = sal_False;
1504                         (*pFilterData)[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "PreviewSizeHint" ) );
1505                         (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint;
1506                         (*pFilterData)[ 1 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "AllowPartialStreamRead" ) );
1507                         (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead;
1508                         (*pFilterData)[ 2 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
1509                         (*pFilterData)[ 2 ].Value <<= bCreateNativeLink;
1510 
1511                         mbIsPreview = sal_True;
1512                     }
1513 
1514                     if(!GraphicFilter::GetGraphicFilter()->ImportGraphic(
1515                         aGraphic, aStreamInfo.maUserData, *pStream,
1516                         GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData))
1517                     {
1518                         const String aUserData( pGraphic->GetUserData() );
1519 
1520                         pGraphic->SetGraphic( aGraphic );
1521                         pGraphic->SetUserData( aUserData );
1522 
1523                         // #142146# Graphic successfully swapped in.
1524                         pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1525                     }
1526                     delete pFilterData;
1527 
1528                     pStream->ResetError();
1529 
1530                     if( aStreamInfo.mbDeleteAfterUse || aStreamInfo.mxStorageRef.is() )
1531                     {
1532                         if ( aStreamInfo.mxStorageRef.is() )
1533                         {
1534                             aStreamInfo.mxStorageRef->dispose();
1535                             aStreamInfo.mxStorageRef = 0;
1536                         }
1537 
1538                         delete pStream;
1539                     }
1540                 }
1541             }
1542             else if( !ImpUpdateGraphicLink( sal_False ) )
1543             {
1544                 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1545             }
1546             else
1547             {
1548                 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1549             }
1550         }
1551         else
1552             pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1553     }
1554 
1555     return (long)(void*) pRet;
1556 }
1557 
1558 // -----------------------------------------------------------------------------
1559 
1560 // #111096#
1561 // Access to GrafAnimationAllowed flag
1562 sal_Bool SdrGrafObj::IsGrafAnimationAllowed() const
1563 {
1564     return mbGrafAnimationAllowed;
1565 }
1566 
1567 void SdrGrafObj::SetGrafAnimationAllowed(sal_Bool bNew)
1568 {
1569     if(mbGrafAnimationAllowed != bNew)
1570     {
1571         mbGrafAnimationAllowed = bNew;
1572         ActionChanged();
1573     }
1574 }
1575 
1576 // #i25616#
1577 sal_Bool SdrGrafObj::IsObjectTransparent() const
1578 {
1579     if(((const SdrGrafTransparenceItem&)GetObjectItem(SDRATTR_GRAFTRANSPARENCE)).GetValue()
1580         || pGraphic->IsTransparent())
1581     {
1582         return sal_True;
1583     }
1584 
1585     return sal_False;
1586 }
1587 
1588 Reference< XInputStream > SdrGrafObj::getInputStream()
1589 {
1590     Reference< XInputStream > xStream;
1591 
1592     if( pModel )
1593     {
1594 //      if( !pGraphic->HasUserData() )
1595 //          pGraphic->SwapOut();
1596 
1597         // kann aus dem original Doc-Stream nachgeladen werden...
1598         if( pGraphic->HasUserData() )
1599         {
1600             SdrDocumentStreamInfo aStreamInfo;
1601 
1602             aStreamInfo.mbDeleteAfterUse = sal_False;
1603             aStreamInfo.maUserData = pGraphic->GetUserData();
1604 
1605             SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1606 
1607             if( pStream )
1608                 xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1609         }
1610         else if( pGraphic && GetGraphic().IsLink() )
1611         {
1612             Graphic aGraphic( GetGraphic() );
1613             GfxLink aLink( aGraphic.GetLink() );
1614             sal_uInt32 nSize = aLink.GetDataSize();
1615             const void* pSourceData = (const void*)aLink.GetData();
1616             if( nSize && pSourceData )
1617             {
1618                 sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
1619                 if( pBuffer )
1620                 {
1621                     memcpy( pBuffer, pSourceData, nSize );
1622 
1623                     SvMemoryStream* pStream = new SvMemoryStream( (void*)pBuffer, (sal_Size)nSize, STREAM_READ );
1624                     pStream->ObjectOwnsMemory( sal_True );
1625                     xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1626                 }
1627             }
1628         }
1629 
1630         if( !xStream.is() && aFileName.Len() )
1631         {
1632             SvFileStream* pStream = new SvFileStream( aFileName, STREAM_READ );
1633             if( pStream )
1634                 xStream.set( new utl::OInputStreamWrapper( pStream ) );
1635         }
1636     }
1637 
1638     return xStream;
1639 }
1640 
1641 // eof
1642