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