xref: /aoo41x/main/svx/source/svdraw/svdograf.cxx (revision f6e50924)
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 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
325 
326     // #i118485# Shear allowed and possible now
327     bNoShear = false;
328 
329 	// #111096#
330 	mbGrafAnimationAllowed = sal_True;
331 
332 	// #i25616#
333 	mbLineIsOutsideGeometry = sal_True;
334 	mbInsidePaint = sal_False;
335 	mbIsPreview = sal_False;
336 
337 	// #i25616#
338 	mbSupportTextIndentingOnLineWidthChange = sal_False;
339 }
340 
341 // -----------------------------------------------------------------------------
342 
343 SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
344 :	SdrRectObj		( rRect ),
345 	pGraphicLink	( NULL ),
346 	bMirrored		( sal_False )
347 {
348 	pGraphic = new GraphicObject( rGrf );
349 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
350 
351     // #i118485# Shear allowed and possible now
352     bNoShear = false;
353 
354 	// #111096#
355 	mbGrafAnimationAllowed = sal_True;
356 
357 	// #i25616#
358 	mbLineIsOutsideGeometry = sal_True;
359 	mbInsidePaint = sal_False;
360 	mbIsPreview	= sal_False;
361 
362 	// #i25616#
363 	mbSupportTextIndentingOnLineWidthChange = sal_False;
364 }
365 
366 // -----------------------------------------------------------------------------
367 
368 SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
369 :	SdrRectObj(),
370 	pGraphicLink	( NULL ),
371 	bMirrored		( sal_False )
372 {
373 	pGraphic = new GraphicObject( rGrf );
374 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
375 
376     // #i118485# Shear allowed and possible now
377     bNoShear = false;
378 
379 	// #111096#
380 	mbGrafAnimationAllowed = sal_True;
381 
382 	// #i25616#
383 	mbLineIsOutsideGeometry = sal_True;
384 	mbInsidePaint = sal_False;
385 	mbIsPreview	= sal_False;
386 
387 	// #i25616#
388 	mbSupportTextIndentingOnLineWidthChange = sal_False;
389 }
390 
391 // -----------------------------------------------------------------------------
392 
393 SdrGrafObj::~SdrGrafObj()
394 {
395 	delete pGraphic;
396 	ImpLinkAbmeldung();
397 }
398 
399 // -----------------------------------------------------------------------------
400 
401 void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
402 {
403 	*pGraphic = rGrfObj;
404 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
405 	pGraphic->SetUserData();
406 	mbIsPreview = sal_False;
407 	SetChanged();
408 	BroadcastObjectChange();
409 }
410 
411 // -----------------------------------------------------------------------------
412 
413 const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
414 {
415 	if(bForceSwapIn)
416 	{
417 		ForceSwapIn();
418 	}
419 
420 	return *pGraphic;
421 }
422 
423 // -----------------------------------------------------------------------------
424 
425 void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
426 {
427 	pGraphic->SetGraphic( rGrf );
428 	pGraphic->SetUserData();
429 	mbIsPreview = sal_False;
430 }
431 
432 void SdrGrafObj::SetGraphic( const Graphic& rGrf )
433 {
434     NbcSetGraphic(rGrf);
435 	SetChanged();
436 	BroadcastObjectChange();
437 }
438 
439 // -----------------------------------------------------------------------------
440 
441 const Graphic& SdrGrafObj::GetGraphic() const
442 {
443 	ForceSwapIn();
444 	return pGraphic->GetGraphic();
445 }
446 
447 // -----------------------------------------------------------------------------
448 
449 Graphic SdrGrafObj::GetTransformedGraphic( sal_uIntPtr nTransformFlags ) const
450 {
451     // #107947# Refactored most of the code to GraphicObject, where
452     // everybody can use e.g. the cropping functionality
453 
454 	GraphicType	    eType = GetGraphicType();
455     MapMode   		aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() );
456     const Size      aDestSize( GetLogicRect().GetSize() );
457     const sal_Bool      bMirror = ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR ) != 0;
458     const sal_Bool      bRotate = ( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) != 0 ) &&
459         ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType );
460 
461     // #104115# Need cropping info earlier
462     ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo();
463     GraphicAttr aActAttr;
464 
465 	if( SDRGRAFOBJ_TRANSFORMATTR_NONE != nTransformFlags &&
466         GRAPHIC_NONE != eType )
467 	{
468         // actually transform the graphic only in this case. On the
469         // other hand, cropping will always happen
470         aActAttr = aGrafInfo;
471 
472         if( bMirror )
473 		{
474 			sal_uInt16		nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
475 			FASTBOOL	bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
476 			FASTBOOL	bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
477 
478 			aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );
479 		}
480 
481 		if( bRotate )
482 			aActAttr.SetRotation( sal_uInt16(aGeo.nDrehWink / 10) );
483 	}
484 
485     // #107947# Delegate to moved code in GraphicObject
486     return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
487 }
488 
489 // -----------------------------------------------------------------------------
490 
491 GraphicType SdrGrafObj::GetGraphicType() const
492 {
493 	return pGraphic->GetType();
494 }
495 
496 sal_Bool SdrGrafObj::IsAnimated() const
497 {
498 	return pGraphic->IsAnimated();
499 }
500 
501 sal_Bool SdrGrafObj::IsEPS() const
502 {
503 	return pGraphic->IsEPS();
504 }
505 
506 sal_Bool SdrGrafObj::IsRenderGraphic() const
507 {
508 	return pGraphic->IsRenderGraphic();
509 }
510 
511 sal_Bool SdrGrafObj::HasRenderGraphic() const
512 {
513 	return pGraphic->HasRenderGraphic();
514 }
515 
516 sal_Bool SdrGrafObj::IsSwappedOut() const
517 {
518 	return mbIsPreview ? sal_True : pGraphic->IsSwappedOut();
519 }
520 
521 const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
522 {
523 	return pGraphic->GetPrefMapMode();
524 }
525 
526 const Size& SdrGrafObj::GetGrafPrefSize() const
527 {
528 	return pGraphic->GetPrefSize();
529 }
530 
531 // -----------------------------------------------------------------------------
532 
533 void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL )
534 {
535 	mbIsPreview = sal_False;
536 	if( !rGraphicStreamURL.Len() )
537 	{
538 		pGraphic->SetUserData();
539 	}
540 	else if( pModel->IsSwapGraphics() )
541 	{
542 		pGraphic->SetUserData( rGraphicStreamURL );
543 
544 		// set state of graphic object to 'swapped out'
545 		if( pGraphic->GetType() == GRAPHIC_NONE )
546 			pGraphic->SetSwapState();
547 	}
548 }
549 
550 // -----------------------------------------------------------------------------
551 
552 String SdrGrafObj::GetGrafStreamURL() const
553 {
554 	return pGraphic->GetUserData();
555 }
556 
557 // -----------------------------------------------------------------------------
558 
559 void SdrGrafObj::SetFileName(const String& rFileName)
560 {
561 	aFileName = rFileName;
562 	SetChanged();
563 }
564 
565 // -----------------------------------------------------------------------------
566 
567 void SdrGrafObj::SetFilterName(const String& rFilterName)
568 {
569 	aFilterName = rFilterName;
570 	SetChanged();
571 }
572 
573 // -----------------------------------------------------------------------------
574 
575 void SdrGrafObj::ForceSwapIn() const
576 {
577 	if( mbIsPreview )
578 	{
579 		// removing preview graphic
580 		const String aUserData( pGraphic->GetUserData() );
581 
582 		Graphic aEmpty;
583 		pGraphic->SetGraphic( aEmpty );
584 		pGraphic->SetUserData( aUserData );
585 		pGraphic->SetSwapState();
586 
587 		const_cast< SdrGrafObj* >( this )->mbIsPreview = sal_False;
588 	}
589 	if ( pGraphicLink && pGraphic->IsSwappedOut() )
590 		ImpUpdateGraphicLink( sal_False );
591 	else
592 		pGraphic->FireSwapInRequest();
593 
594 	if( pGraphic->IsSwappedOut() ||
595 	    ( pGraphic->GetType() == GRAPHIC_NONE ) ||
596 		( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
597 	{
598 		Graphic aDefaultGraphic;
599 		aDefaultGraphic.SetDefaultType();
600 		pGraphic->SetGraphic( aDefaultGraphic );
601 	}
602 }
603 
604 // -----------------------------------------------------------------------------
605 
606 void SdrGrafObj::ForceSwapOut() const
607 {
608 	pGraphic->FireSwapOutRequest();
609 }
610 
611 // -----------------------------------------------------------------------------
612 
613 void SdrGrafObj::ImpLinkAnmeldung()
614 {
615 	sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
616 
617 	if( pLinkManager != NULL && pGraphicLink == NULL )
618 	{
619 		if( aFileName.Len() )
620 		{
621 			pGraphicLink = new SdrGraphicLink( this );
622 			pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL );
623 			pGraphicLink->Connect();
624 		}
625 	}
626 }
627 
628 // -----------------------------------------------------------------------------
629 
630 void SdrGrafObj::ImpLinkAbmeldung()
631 {
632 	sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
633 
634 	if( pLinkManager != NULL && pGraphicLink!=NULL)
635 	{
636 		// Bei Remove wird *pGraphicLink implizit deleted
637 		pLinkManager->Remove( pGraphicLink );
638 		pGraphicLink=NULL;
639 	}
640 }
641 
642 // -----------------------------------------------------------------------------
643 
644 void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName )
645 {
646 	ImpLinkAbmeldung();
647 	aFileName = rFileName;
648 	aFilterName = rFilterName;
649 	ImpLinkAnmeldung();
650 	pGraphic->SetUserData();
651 
652     // #92205# A linked graphic is per definition swapped out (has to be loaded)
653     pGraphic->SetSwapState();
654 }
655 
656 // -----------------------------------------------------------------------------
657 
658 void SdrGrafObj::ReleaseGraphicLink()
659 {
660 	ImpLinkAbmeldung();
661 	aFileName = String();
662 	aFilterName = String();
663 }
664 
665 // -----------------------------------------------------------------------------
666 
667 void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
668 {
669 	FASTBOOL bAnim = pGraphic->IsAnimated();
670     FASTBOOL bRenderGraphic = pGraphic->HasRenderGraphic();
671 	FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
672 
673 	rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
674 							   aGeo.nDrehWink % 18000 == 0 ||
675 							   aGeo.nDrehWink % 27000 == 0;
676 
677 	rInfo.bResizePropAllowed = sal_True;
678 	rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim && !bRenderGraphic;
679 	rInfo.bRotate90Allowed = bNoPresGrf && !bAnim && !bRenderGraphic;
680 	rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim && !bRenderGraphic;
681 	rInfo.bMirror45Allowed = bNoPresGrf && !bAnim && !bRenderGraphic;
682 	rInfo.bMirror90Allowed = !bEmptyPresObj && !bRenderGraphic;
683 	rInfo.bTransparenceAllowed = sal_False;
684 	rInfo.bGradientAllowed = sal_False;
685 
686     // #i118485# Shear allowed and possible now
687 	rInfo.bShearAllowed = true;
688 
689     rInfo.bEdgeRadiusAllowed=sal_False;
690 	rInfo.bCanConvToPath = !IsEPS() && !bRenderGraphic;
691 	rInfo.bCanConvToPathLineToArea = sal_False;
692 	rInfo.bCanConvToPolyLineToArea = sal_False;
693 	rInfo.bCanConvToPoly = !IsEPS() && !bRenderGraphic;
694 	rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
695 }
696 
697 // -----------------------------------------------------------------------------
698 
699 sal_uInt16 SdrGrafObj::GetObjIdentifier() const
700 {
701 	return sal_uInt16( OBJ_GRAF );
702 }
703 
704 // -----------------------------------------------------------------------------
705 
706 /* The graphic of the GraphicLink will be loaded. If it is called with
707    bAsynchron = true then the graphic will be set later via DataChanged
708 */
709 sal_Bool SdrGrafObj::ImpUpdateGraphicLink( sal_Bool bAsynchron ) const
710 {
711     sal_Bool bRet = sal_False;
712     if( pGraphicLink )
713 	{
714 		if ( bAsynchron )
715 			pGraphicLink->UpdateAsynchron();
716 		else
717 			pGraphicLink->DataChanged( ImpLoadLinkedGraphic( aFileName, aFilterName ) );
718         bRet = sal_True;
719     }
720 	return bRet;
721 }
722 
723 // -----------------------------------------------------------------------------
724 
725 void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
726 {
727 	const sal_Bool bIsChanged = GetModel()->IsChanged();
728 	NbcSetGraphic( rGraphic );
729 	ActionChanged();
730 	BroadcastObjectChange();
731 	GetModel()->SetChanged( bIsChanged );
732 }
733 
734 // -----------------------------------------------------------------------------
735 
736 void SdrGrafObj::TakeObjNameSingul(XubString& rName) const
737 {
738 	switch( pGraphic->GetType() )
739 	{
740 		case GRAPHIC_BITMAP:
741         {
742             const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
743                                  ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
744                                  ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
745 
746             rName=ImpGetResStr( nId );
747         }
748         break;
749 
750 		case GRAPHIC_GDIMETAFILE:
751             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF );
752         break;
753 
754         case GRAPHIC_NONE:
755             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE );
756         break;
757 
758         default:
759             rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF );
760         break;
761 	}
762 
763 	const String aName(GetName());
764 
765 	if( aName.Len() )
766 	{
767 		rName.AppendAscii( " '" );
768 		rName += aName;
769 		rName += sal_Unicode( '\'' );
770 	}
771 }
772 
773 // -----------------------------------------------------------------------------
774 
775 void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const
776 {
777 	switch( pGraphic->GetType() )
778 	{
779 		case GRAPHIC_BITMAP:
780         {
781             const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
782                                  ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
783                                  ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
784 
785             rName=ImpGetResStr( nId );
786         }
787         break;
788 
789 		case GRAPHIC_GDIMETAFILE:
790             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF );
791         break;
792 
793         case GRAPHIC_NONE:
794             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE );
795         break;
796 
797         default:
798             rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF );
799         break;
800 	}
801 
802 	const String aName(GetName());
803 
804 	if( aName.Len() )
805 	{
806 		rName.AppendAscii( " '" );
807 		rName += aName;
808 		rName += sal_Unicode( '\'' );
809 	}
810 }
811 
812 // -----------------------------------------------------------------------------
813 
814 SdrObject* SdrGrafObj::getFullDragClone() const
815 {
816     // call parent
817     SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
818 
819     // #i103116# the full drag clone leads to problems
820     // with linked graphics, so reset the link in this
821     // temporary interaction object and load graphic
822     if(pRetval && IsLinkedGraphic())
823     {
824         pRetval->ForceSwapIn();
825         pRetval->ReleaseGraphicLink();
826     }
827 
828     return pRetval;
829 }
830 
831 void SdrGrafObj::operator=( const SdrObject& rObj )
832 {
833 	SdrRectObj::operator=( rObj );
834 
835 	const SdrGrafObj& rGraf = (SdrGrafObj&) rObj;
836 
837 	pGraphic->SetGraphic( rGraf.GetGraphic(), &rGraf.GetGraphicObject() );
838 	aCropRect = rGraf.aCropRect;
839 	aFileName = rGraf.aFileName;
840 	aFilterName = rGraf.aFilterName;
841 	bMirrored = rGraf.bMirrored;
842 
843 	if( rGraf.pGraphicLink != NULL)
844 	{
845 		SetGraphicLink( aFileName, aFilterName );
846 	}
847 
848 	ImpSetAttrToGrafInfo();
849 }
850 
851 // -----------------------------------------------------------------------------
852 // #i25616#
853 
854 basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const
855 {
856 	if(mbInsidePaint)
857 	{
858 		basegfx::B2DPolyPolygon aRetval;
859 
860 		// take grown rectangle
861 		const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2);
862 		const Rectangle aGrownRect(
863 			aRect.Left() - nHalfLineWidth,
864 			aRect.Top() - nHalfLineWidth,
865 			aRect.Right() + nHalfLineWidth,
866 			aRect.Bottom() + nHalfLineWidth);
867 
868 		XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius()));
869 		aRetval.append(aXPoly.getB2DPolygon());
870 
871 		return aRetval;
872 	}
873 	else
874 	{
875 		// call parent
876 		return SdrRectObj::TakeXorPoly();
877 	}
878 }
879 
880 // -----------------------------------------------------------------------------
881 
882 sal_uInt32 SdrGrafObj::GetHdlCount() const
883 {
884 	return 8L;
885 }
886 
887 // -----------------------------------------------------------------------------
888 
889 SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
890 {
891 	return SdrRectObj::GetHdl( nHdlNum + 1L );
892 }
893 
894 // -----------------------------------------------------------------------------
895 
896 void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
897 {
898 	SdrRectObj::NbcResize( rRef, xFact, yFact );
899 
900 	FASTBOOL bMirrX = xFact.GetNumerator() < 0;
901 	FASTBOOL bMirrY = yFact.GetNumerator() < 0;
902 
903 	if( bMirrX != bMirrY )
904 		bMirrored = !bMirrored;
905 }
906 
907 // -----------------------------------------------------------------------------
908 
909 void SdrGrafObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
910 {
911 	SdrRectObj::NbcRotate(rRef,nWink,sn,cs);
912 }
913 
914 // -----------------------------------------------------------------------------
915 
916 void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
917 {
918 	SdrRectObj::NbcMirror(rRef1,rRef2);
919 	bMirrored = !bMirrored;
920 }
921 
922 // -----------------------------------------------------------------------------
923 
924 void SdrGrafObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
925 {
926     // #i118485# Call Shear now, old version redirected to rotate
927 	SdrRectObj::NbcShear(rRef, nWink, tn, bVShear);
928 }
929 
930 // -----------------------------------------------------------------------------
931 
932 void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect)
933 {
934 	SdrRectObj::NbcSetSnapRect(rRect);
935 }
936 
937 // -----------------------------------------------------------------------------
938 
939 void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect)
940 {
941 	//int bChg=rRect.GetSize()!=aRect.GetSize();
942 	SdrRectObj::NbcSetLogicRect(rRect);
943 }
944 
945 // -----------------------------------------------------------------------------
946 
947 SdrObjGeoData* SdrGrafObj::NewGeoData() const
948 {
949 	return new SdrGrafObjGeoData;
950 }
951 
952 // -----------------------------------------------------------------------------
953 
954 void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
955 {
956 	SdrRectObj::SaveGeoData(rGeo);
957 	SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
958 	rGGeo.bMirrored=bMirrored;
959 }
960 
961 // -----------------------------------------------------------------------------
962 
963 void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo)
964 {
965 	//long		nDrehMerk = aGeo.nDrehWink;
966 	//long		nShearMerk = aGeo.nShearWink;
967 	//int	bMirrMerk = bMirrored;
968 	Size		aSizMerk( aRect.GetSize() );
969 
970 	SdrRectObj::RestGeoData(rGeo);
971 	SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
972 	bMirrored=rGGeo.bMirrored;
973 }
974 
975 // -----------------------------------------------------------------------------
976 
977 void SdrGrafObj::SetPage( SdrPage* pNewPage )
978 {
979 	FASTBOOL bRemove = pNewPage == NULL && pPage != NULL;
980 	FASTBOOL bInsert = pNewPage != NULL && pPage == NULL;
981 
982 	if( bRemove )
983 	{
984 		// hier kein SwapIn noetig, weil wenn nicht geladen, dann auch nicht animiert.
985 		if( pGraphic->IsAnimated())
986 			pGraphic->StopAnimation();
987 
988 		if( pGraphicLink != NULL )
989 			ImpLinkAbmeldung();
990 	}
991 
992 	SdrRectObj::SetPage( pNewPage );
993 
994 	if(aFileName.Len() && bInsert)
995 		ImpLinkAnmeldung();
996 }
997 
998 // -----------------------------------------------------------------------------
999 
1000 void SdrGrafObj::SetModel( SdrModel* pNewModel )
1001 {
1002 	FASTBOOL bChg = pNewModel != pModel;
1003 
1004 	if( bChg )
1005 	{
1006 		if( pGraphic->HasUserData() )
1007 		{
1008 			ForceSwapIn();
1009 			pGraphic->SetUserData();
1010 		}
1011 
1012 		if( pGraphicLink != NULL )
1013 			ImpLinkAbmeldung();
1014 	}
1015 
1016 	// Model umsetzen
1017 	SdrRectObj::SetModel(pNewModel);
1018 
1019 	if( bChg && aFileName.Len() )
1020 		ImpLinkAnmeldung();
1021 }
1022 
1023 // -----------------------------------------------------------------------------
1024 
1025 void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/)
1026 {
1027 	// #111096#
1028 	// use new graf animation
1029 	SetGrafAnimationAllowed(sal_True);
1030 }
1031 
1032 // -----------------------------------------------------------------------------
1033 
1034 void SdrGrafObj::StopAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1035 {
1036 	// #111096#
1037 	// use new graf animation
1038 	SetGrafAnimationAllowed(sal_False);
1039 }
1040 
1041 // -----------------------------------------------------------------------------
1042 
1043 FASTBOOL SdrGrafObj::HasGDIMetaFile() const
1044 {
1045 	return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE );
1046 }
1047 
1048 // -----------------------------------------------------------------------------
1049 
1050 const GDIMetaFile* SdrGrafObj::GetGDIMetaFile() const
1051 {
1052 	DBG_ERROR( "Invalid return value! Don't use it! (KA)" );
1053 	return &GetGraphic().GetGDIMetaFile();
1054 }
1055 
1056 // -----------------------------------------------------------------------------
1057 
1058 SdrObject* SdrGrafObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
1059 {
1060 	SdrObject* pRetval = NULL;
1061 
1062 	switch( GetGraphicType() )
1063 	{
1064 		case GRAPHIC_GDIMETAFILE:
1065 		{
1066 			// NUR die aus dem MetaFile erzeugbaren Objekte in eine Gruppe packen und zurueckliefern
1067 			ImpSdrGDIMetaFileImport aFilter(*GetModel());
1068 			aFilter.SetScaleRect(aRect);
1069 			aFilter.SetLayer(GetLayer());
1070 
1071 			SdrObjGroup* pGrp = new SdrObjGroup();
1072 			sal_uInt32 nInsAnz = aFilter.DoImport(GetTransformedGraphic(
1073                 SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile(),
1074                 *pGrp->GetSubList(), 0);
1075 
1076             if(nInsAnz)
1077 			{
1078                 {
1079                     // copy transformation
1080                 	GeoStat aGeoStat(GetGeoStat());
1081 
1082 	                if(aGeoStat.nShearWink)
1083                     {
1084                         aGeoStat.RecalcTan();
1085                         pGrp->NbcShear(aRect.TopLeft(), aGeoStat.nShearWink, aGeoStat.nTan, false);
1086                     }
1087 
1088 	                if(aGeoStat.nDrehWink)
1089                     {
1090 	                    aGeoStat.RecalcSinCos();
1091                         pGrp->NbcRotate(aRect.TopLeft(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1092                     }
1093                 }
1094 
1095                 pRetval = pGrp;
1096 				pGrp->NbcSetLayer(GetLayer());
1097 				pGrp->SetModel(GetModel());
1098 
1099                 if(bAddText)
1100                 {
1101 				    pRetval = ImpConvertAddText(pRetval, bBezier);
1102                 }
1103 
1104                 // convert all children
1105                 if( pRetval )
1106                 {
1107                     SdrObject* pHalfDone = pRetval;
1108                     pRetval = pHalfDone->DoConvertToPolyObj(bBezier, bAddText);
1109                     SdrObject::Free( pHalfDone ); // resulting object is newly created
1110 
1111                     if( pRetval )
1112                     {
1113                         // flatten subgroups. As we call
1114                         // DoConvertToPolyObj() on the resulting group
1115                         // objects, subgroups can exist (e.g. text is
1116                         // a group object for every line).
1117                         SdrObjList* pList = pRetval->GetSubList();
1118                         if( pList )
1119                             pList->FlattenGroups();
1120                     }
1121                 }
1122 			}
1123 			else
1124             {
1125 				delete pGrp;
1126             }
1127 
1128             // #i118485# convert line and fill
1129             SdrObject* pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false);
1130 
1131             if(pLineFill)
1132             {
1133                 if(pRetval)
1134                 {
1135                     pGrp = dynamic_cast< SdrObjGroup* >(pRetval);
1136 
1137                     if(!pGrp)
1138                     {
1139             			pGrp = new SdrObjGroup();
1140 
1141                         pGrp->NbcSetLayer(GetLayer());
1142 				        pGrp->SetModel(GetModel());
1143                         pGrp->GetSubList()->NbcInsertObject(pRetval);
1144                     }
1145 
1146                     pGrp->GetSubList()->NbcInsertObject(pLineFill, 0);
1147                 }
1148                 else
1149                 {
1150                     pRetval = pLineFill;
1151                 }
1152             }
1153 
1154 			break;
1155 		}
1156 		case GRAPHIC_BITMAP:
1157 		{
1158 			// Grundobjekt kreieren und Fuellung ergaenzen
1159 			pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1160 
1161 			// Bitmap als Attribut retten
1162 			if(pRetval)
1163 			{
1164 				// Bitmap als Fuellung holen
1165 				SfxItemSet aSet(GetObjectItemSet());
1166 
1167 				aSet.Put(XFillStyleItem(XFILL_BITMAP));
1168 				Bitmap aBitmap( GetTransformedGraphic().GetBitmap() );
1169 				XOBitmap aXBmp(aBitmap, XBITMAP_STRETCH);
1170 				aSet.Put(XFillBitmapItem(String(), aXBmp));
1171 				aSet.Put(XFillBmpTileItem(sal_False));
1172 
1173 				pRetval->SetMergedItemSet(aSet);
1174 			}
1175 			break;
1176 		}
1177 		case GRAPHIC_NONE:
1178 		case GRAPHIC_DEFAULT:
1179 		{
1180 			pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1181 			break;
1182 		}
1183 	}
1184 
1185 	return pRetval;
1186 }
1187 
1188 // -----------------------------------------------------------------------------
1189 
1190 void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1191 {
1192 	SetXPolyDirty();
1193 	SdrRectObj::Notify( rBC, rHint );
1194 	ImpSetAttrToGrafInfo();
1195 }
1196 
1197 void SdrGrafObj::ImpSetAttrToGrafInfo()
1198 {
1199 	const SfxItemSet& rSet = GetObjectItemSet();
1200 	const sal_uInt16 nTrans = ( (SdrGrafTransparenceItem&) rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue();
1201 	const SdrGrafCropItem&	rCrop = (const SdrGrafCropItem&) rSet.Get( SDRATTR_GRAFCROP );
1202 
1203 	aGrafInfo.SetLuminance( ( (SdrGrafLuminanceItem&) rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() );
1204 	aGrafInfo.SetContrast( ( (SdrGrafContrastItem&) rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() );
1205 	aGrafInfo.SetChannelR( ( (SdrGrafRedItem&) rSet.Get( SDRATTR_GRAFRED ) ).GetValue() );
1206 	aGrafInfo.SetChannelG( ( (SdrGrafGreenItem&) rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() );
1207 	aGrafInfo.SetChannelB( ( (SdrGrafBlueItem&) rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() );
1208 	aGrafInfo.SetGamma( ( (SdrGrafGamma100Item&) rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 );
1209 	aGrafInfo.SetTransparency( (sal_uInt8) FRound( Min( nTrans, (sal_uInt16) 100 )  * 2.55 ) );
1210 	aGrafInfo.SetInvert( ( (SdrGrafInvertItem&) rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() );
1211 	aGrafInfo.SetDrawMode( ( (SdrGrafModeItem&) rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() );
1212 	aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
1213 
1214 	SetXPolyDirty();
1215 	SetRectsDirty();
1216 }
1217 
1218 // -----------------------------------------------------------------------------
1219 
1220 void SdrGrafObj::ImpSetGrafInfoToAttr()
1221 {
1222 	SetObjectItem( SdrGrafLuminanceItem( aGrafInfo.GetLuminance() ) );
1223 	SetObjectItem( SdrGrafContrastItem( aGrafInfo.GetContrast() ) );
1224 	SetObjectItem( SdrGrafRedItem( aGrafInfo.GetChannelR() ) );
1225 	SetObjectItem( SdrGrafGreenItem( aGrafInfo.GetChannelG() ) );
1226 	SetObjectItem( SdrGrafBlueItem( aGrafInfo.GetChannelB() ) );
1227 	SetObjectItem( SdrGrafGamma100Item( FRound( aGrafInfo.GetGamma() * 100.0 ) ) );
1228 	SetObjectItem( SdrGrafTransparenceItem( (sal_uInt16) FRound( aGrafInfo.GetTransparency() / 2.55 ) ) );
1229 	SetObjectItem( SdrGrafInvertItem( aGrafInfo.IsInvert() ) );
1230 	SetObjectItem( SdrGrafModeItem( aGrafInfo.GetDrawMode() ) );
1231 	SetObjectItem( SdrGrafCropItem( aGrafInfo.GetLeftCrop(), aGrafInfo.GetTopCrop(), aGrafInfo.GetRightCrop(), aGrafInfo.GetBottomCrop() ) );
1232 }
1233 
1234 // -----------------------------------------------------------------------------
1235 
1236 void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly )
1237 {
1238 	Size aSize;
1239 	Size aMaxSize( rMaxRect.GetSize() );
1240 	if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1241 		aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM );
1242 	else
1243 		aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1244 										    pGraphic->GetPrefMapMode(),
1245 										    MapMode( MAP_100TH_MM ) );
1246 
1247 	if( aSize.Height() != 0 && aSize.Width() != 0 )
1248 	{
1249 		Point aPos( rMaxRect.TopLeft() );
1250 
1251 		// Falls Grafik zu gross, wird die Grafik
1252 		// in die Seite eingepasst
1253 		if ( (!bShrinkOnly                          ||
1254 	    	 ( aSize.Height() > aMaxSize.Height() ) ||
1255 		 	( aSize.Width()  > aMaxSize.Width()  ) )&&
1256 		 	aSize.Height() && aMaxSize.Height() )
1257 		{
1258 			float fGrfWH =	(float)aSize.Width() /
1259 							(float)aSize.Height();
1260 			float fWinWH =	(float)aMaxSize.Width() /
1261 							(float)aMaxSize.Height();
1262 
1263 			// Grafik an Pagesize anpassen (skaliert)
1264 			if ( fGrfWH < fWinWH )
1265 			{
1266 				aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
1267 				aSize.Height()= aMaxSize.Height();
1268 			}
1269 			else if ( fGrfWH > 0.F )
1270 			{
1271 				aSize.Width() = aMaxSize.Width();
1272 				aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
1273 			}
1274 
1275 			aPos = rMaxRect.Center();
1276 		}
1277 
1278 		if( bShrinkOnly )
1279 			aPos = aRect.TopLeft();
1280 
1281 		aPos.X() -= aSize.Width() / 2;
1282 		aPos.Y() -= aSize.Height() / 2;
1283 		SetLogicRect( Rectangle( aPos, aSize ) );
1284 	}
1285 }
1286 
1287 // -----------------------------------------------------------------------------
1288 
1289 IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
1290 {
1291 	SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1292 
1293 	if( pO->IsInSwapOut() )
1294 	{
1295 		if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
1296 		{
1297 			// test if this object is visualized from someone
1298             // ## test only if there are VOCs other than the preview renderer
1299 			if(!GetViewContact().HasViewObjectContacts(true))
1300 			{
1301 				const sal_uIntPtr	nSwapMode = pModel->GetSwapGraphicsMode();
1302 
1303 				if( ( pGraphic->HasUserData() || pGraphicLink ) &&
1304 					( nSwapMode & SDR_SWAPGRAPHICSMODE_PURGE ) )
1305 				{
1306 					pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1307 				}
1308 				else if( nSwapMode & SDR_SWAPGRAPHICSMODE_TEMP )
1309 				{
1310 					pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1311 					pGraphic->SetUserData();
1312 				}
1313 
1314 				// #i102380#
1315 				sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
1316 
1317 				if(pVC)
1318 				{
1319 					pVC->flushGraphicObjects();
1320 				}
1321 			}
1322 		}
1323 	}
1324 	else if( pO->IsInSwapIn() )
1325 	{
1326 		// kann aus dem original Doc-Stream nachgeladen werden...
1327 		if( pModel != NULL )
1328 		{
1329 			if( pGraphic->HasUserData() )
1330 			{
1331 				SdrDocumentStreamInfo aStreamInfo;
1332 
1333 				aStreamInfo.mbDeleteAfterUse = sal_False;
1334 				aStreamInfo.maUserData = pGraphic->GetUserData();
1335 
1336 				SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1337 
1338 				if( pStream != NULL )
1339 				{
1340 					Graphic aGraphic;
1341 
1342                     com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL;
1343 
1344 					if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
1345                     {
1346 //							Rectangle aSnapRect(GetSnapRect());
1347 //							const Rectangle aSnapRectPixel(pOutDev->LogicToPixel(aSnapRect));
1348 
1349                         pFilterData = new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 );
1350 
1351                         com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
1352                         sal_Bool bAllowPartialStreamRead = sal_True;
1353                         sal_Bool bCreateNativeLink = sal_False;
1354                         (*pFilterData)[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "PreviewSizeHint" ) );
1355                         (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint;
1356                         (*pFilterData)[ 1 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "AllowPartialStreamRead" ) );
1357                         (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead;
1358                         (*pFilterData)[ 2 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
1359                         (*pFilterData)[ 2 ].Value <<= bCreateNativeLink;
1360 
1361                         mbIsPreview = sal_True;
1362                     }
1363 
1364                     if( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pStream,
1365                                                         GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData ) )
1366                     {
1367                         const String aUserData( pGraphic->GetUserData() );
1368 
1369                         pGraphic->SetGraphic( aGraphic );
1370                         pGraphic->SetUserData( aUserData );
1371 
1372                         // #142146# Graphic successfully swapped in.
1373                         pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1374                     }
1375                     delete pFilterData;
1376 
1377                     pStream->ResetError();
1378 
1379                     if( aStreamInfo.mbDeleteAfterUse || aStreamInfo.mxStorageRef.is() )
1380                     {
1381                         if ( aStreamInfo.mxStorageRef.is() )
1382                         {
1383                             aStreamInfo.mxStorageRef->dispose();
1384                             aStreamInfo.mxStorageRef = 0;
1385                         }
1386 
1387                         delete pStream;
1388                     }
1389                 }
1390 			}
1391 			else if( !ImpUpdateGraphicLink( sal_False ) )
1392             {
1393 				pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1394             }
1395 			else
1396             {
1397                 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1398             }
1399 		}
1400 		else
1401 			pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1402 	}
1403 
1404 	return (long)(void*) pRet;
1405 }
1406 
1407 // -----------------------------------------------------------------------------
1408 
1409 // #111096#
1410 // Access to GrafAnimationAllowed flag
1411 sal_Bool SdrGrafObj::IsGrafAnimationAllowed() const
1412 {
1413 	return mbGrafAnimationAllowed;
1414 }
1415 
1416 void SdrGrafObj::SetGrafAnimationAllowed(sal_Bool bNew)
1417 {
1418 	if(mbGrafAnimationAllowed != bNew)
1419 	{
1420 		mbGrafAnimationAllowed = bNew;
1421 		ActionChanged();
1422 	}
1423 }
1424 
1425 // #i25616#
1426 sal_Bool SdrGrafObj::IsObjectTransparent() const
1427 {
1428 	if(((const SdrGrafTransparenceItem&)GetObjectItem(SDRATTR_GRAFTRANSPARENCE)).GetValue()
1429 		|| pGraphic->IsTransparent())
1430 	{
1431 		return sal_True;
1432 	}
1433 
1434 	return sal_False;
1435 }
1436 
1437 Reference< XInputStream > SdrGrafObj::getInputStream()
1438 {
1439 	Reference< XInputStream > xStream;
1440 
1441 	if( pModel )
1442 	{
1443 //		if( !pGraphic->HasUserData() )
1444 //			pGraphic->SwapOut();
1445 
1446 		// kann aus dem original Doc-Stream nachgeladen werden...
1447 		if( pGraphic->HasUserData() )
1448 		{
1449 			SdrDocumentStreamInfo aStreamInfo;
1450 
1451 			aStreamInfo.mbDeleteAfterUse = sal_False;
1452 			aStreamInfo.maUserData = pGraphic->GetUserData();
1453 
1454 			SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1455 
1456 			if( pStream )
1457 				xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1458 		}
1459 		else if( pGraphic && GetGraphic().IsLink() )
1460 		{
1461 			Graphic aGraphic( GetGraphic() );
1462 			GfxLink aLink( aGraphic.GetLink() );
1463 			sal_uInt32 nSize = aLink.GetDataSize();
1464 			const void* pSourceData = (const void*)aLink.GetData();
1465 			if( nSize && pSourceData )
1466 			{
1467 				sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
1468 				if( pBuffer )
1469 				{
1470 					memcpy( pBuffer, pSourceData, nSize );
1471 
1472 					SvMemoryStream* pStream = new SvMemoryStream( (void*)pBuffer, (sal_Size)nSize, STREAM_READ );
1473 					pStream->ObjectOwnsMemory( sal_True );
1474 					xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1475 				}
1476 			}
1477 		}
1478 
1479 		if( !xStream.is() && aFileName.Len() )
1480 		{
1481 			SvFileStream* pStream = new SvFileStream( aFileName, STREAM_READ );
1482 			if( pStream )
1483 				xStream.set( new utl::OInputStreamWrapper( pStream ) );
1484 		}
1485 	}
1486 
1487 	return xStream;
1488 }
1489 
1490 // eof
1491