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