bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / svdraw / svdograf.cxx
blob2fa62cc96e3c78c466b7fd3d6aa3dab8dbfb6852
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <unotools/streamwrap.hxx>
22 #include <sfx2/lnkbase.hxx>
23 #include <math.h>
24 #include <tools/helpers.hxx>
25 #include <sot/formats.hxx>
26 #include <sot/storage.hxx>
27 #include <comphelper/storagehelper.hxx>
28 #include <unotools/ucbstreamhelper.hxx>
29 #include <unotools/localfilehelper.hxx>
30 #include <svl/style.hxx>
31 #include <vcl/graphicfilter.hxx>
32 #include <svl/urihelper.hxx>
33 #include <svtools/grfmgr.hxx>
34 #include <vcl/svapp.hxx>
36 #include <sfx2/linkmgr.hxx>
37 #include <sfx2/docfile.hxx>
38 #include <svx/svdetc.hxx>
39 #include "svdglob.hxx"
40 #include "svx/svdstr.hrc"
41 #include <svx/svdpool.hxx>
42 #include <svx/svdmodel.hxx>
43 #include <svx/svdpage.hxx>
44 #include <svx/svdmrkv.hxx>
45 #include <svx/svdpagv.hxx>
46 #include "svx/svdviter.hxx"
47 #include <svx/svdview.hxx>
48 #include <svx/svdograf.hxx>
49 #include <svx/svdogrp.hxx>
50 #include <svx/xbtmpit.hxx>
51 #include <svx/xflbmtit.hxx>
52 #include <svx/svdundo.hxx>
53 #include "svdfmtf.hxx"
54 #include <svx/sdgcpitm.hxx>
55 #include <editeng/eeitem.hxx>
56 #include <sdr/properties/graphicproperties.hxx>
57 #include <sdr/contact/viewcontactofgraphic.hxx>
58 #include <basegfx/matrix/b2dhommatrixtools.hxx>
59 #include <basegfx/polygon/b2dpolygon.hxx>
60 #include <basegfx/polygon/b2dpolygontools.hxx>
61 #include <osl/thread.hxx>
62 #include <drawinglayer/processor2d/objectinfoextractor2d.hxx>
63 #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
64 #include <boost/scoped_ptr.hpp>
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::io;
70 const Graphic ImpLoadLinkedGraphic( const OUString& aFileName, const OUString& aReferer, const OUString& aFilterName )
72 Graphic aGraphic;
74 SfxMedium xMed( aFileName, aReferer, STREAM_STD_READ );
75 xMed.Download();
77 SvStream* pInStrm = xMed.GetInStream();
78 if ( pInStrm )
80 pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
81 GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
83 const sal_uInt16 nFilter = !aFilterName.isEmpty() && rGF.GetImportFormatCount()
84 ? rGF.GetImportFormatNumber( aFilterName )
85 : GRFILTER_FORMAT_DONTKNOW;
87 css::uno::Sequence< css::beans::PropertyValue > aFilterData( 1 );
89 // TODO: Room for improvement:
90 // As this is a linked graphic the GfxLink is not needed if saving/loading our own format.
91 // But this link is required by some filters to access the native graphic (PDF export/MS export),
92 // there we should create a new service to provide this data if needed
93 aFilterData[ 0 ].Name = "CreateNativeLink";
94 aFilterData[ 0 ].Value = Any( sal_True );
96 // #i123042# for e.g SVG the path is needed, so hand it over here. I have no real idea
97 // what consequences this may have; maybe this is not handed over by purpose here. Not
98 // handing it over means that any GraphicFormat that internallv needs a path as base
99 // to interpret included links may fail.
100 // Alternatively the path may be set at the result after this call when it is known
101 // that it is a SVG graphic, but only because no one yet tried to interpret it.
102 rGF.ImportGraphic( aGraphic, aFileName, *pInStrm, nFilter, NULL, GraphicFilterImportFlags::NONE, &aFilterData );
104 return aGraphic;
107 class SdrGraphicUpdater;
108 class SdrGraphicLink : public sfx2::SvBaseLink
110 SdrGrafObj& rGrafObj;
111 SdrGraphicUpdater* pGraphicUpdater;
113 public:
114 SdrGraphicLink(SdrGrafObj& rObj);
115 virtual ~SdrGraphicLink();
117 virtual void Closed() SAL_OVERRIDE;
119 virtual ::sfx2::SvBaseLink::UpdateResult DataChanged(
120 const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue ) SAL_OVERRIDE;
121 void DataChanged( const Graphic& rGraphic );
123 bool Connect() { return 0 != GetRealObject(); }
124 void UpdateAsynchron();
125 void RemoveGraphicUpdater();
127 OUString getReferer() const { return rGrafObj.aReferer; }
130 class SdrGraphicUpdater : public ::osl::Thread
132 public:
133 SdrGraphicUpdater( const OUString& rFileName, const OUString& rFilterName, SdrGraphicLink& );
134 virtual ~SdrGraphicUpdater();
136 void SAL_CALL Terminate();
138 bool GraphicLinkChanged( const OUString& rFileName ){ return maFileName != rFileName; };
140 protected:
142 /** is called from the inherited create method and acts as the
143 main function of this thread.
145 virtual void SAL_CALL run() SAL_OVERRIDE;
147 /** Called after the thread is terminated via the terminate
148 method. Used to kill the thread by calling delete on this.
150 virtual void SAL_CALL onTerminated() SAL_OVERRIDE;
152 private:
154 const OUString maFileName;
155 const OUString maFilterName;
156 SdrGraphicLink& mrGraphicLink;
158 volatile bool mbIsTerminated;
161 SdrGraphicUpdater::SdrGraphicUpdater( const OUString& rFileName, const OUString& rFilterName, SdrGraphicLink& rGraphicLink )
162 : maFileName( rFileName )
163 , maFilterName( rFilterName )
164 , mrGraphicLink( rGraphicLink )
165 , mbIsTerminated( false )
167 create();
170 SdrGraphicUpdater::~SdrGraphicUpdater()
174 void SdrGraphicUpdater::Terminate()
176 mbIsTerminated = true;
179 void SAL_CALL SdrGraphicUpdater::onTerminated()
181 delete this;
184 void SAL_CALL SdrGraphicUpdater::run()
186 osl_setThreadName("SdrGraphicUpdater");
188 Graphic aGraphic( ImpLoadLinkedGraphic( maFileName, mrGraphicLink.getReferer(), maFilterName ) );
189 SolarMutexGuard aSolarGuard;
190 if ( !mbIsTerminated )
192 mrGraphicLink.DataChanged( aGraphic );
193 mrGraphicLink.RemoveGraphicUpdater();
197 SdrGraphicLink::SdrGraphicLink(SdrGrafObj& rObj)
198 : ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB )
199 , rGrafObj( rObj )
200 , pGraphicUpdater( NULL )
202 SetSynchron( false );
205 SdrGraphicLink::~SdrGraphicLink()
207 if ( pGraphicUpdater )
208 pGraphicUpdater->Terminate();
211 void SdrGraphicLink::DataChanged( const Graphic& rGraphic )
213 rGrafObj.ImpSetLinkedGraphic( rGraphic );
216 void SdrGraphicLink::RemoveGraphicUpdater()
218 pGraphicUpdater = NULL;
221 ::sfx2::SvBaseLink::UpdateResult SdrGraphicLink::DataChanged(
222 const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue )
224 SdrModel* pModel = rGrafObj.GetModel();
225 sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
227 if( pLinkManager && rValue.hasValue() )
229 sfx2::LinkManager::GetDisplayNames( this, 0, &rGrafObj.aFileName, 0, &rGrafObj.aFilterName );
231 Graphic aGraphic;
232 if( sfx2::LinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
234 rGrafObj.NbcSetGraphic( aGraphic );
235 rGrafObj.ActionChanged();
237 else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() )
239 // broadcasting, to update slide sorter
240 rGrafObj.BroadcastObjectChange();
243 return SUCCESS;
246 void SdrGraphicLink::Closed()
248 // close connection; set pLink of the object to NULL, as link instance is just about getting destructed.
249 rGrafObj.ForceSwapIn();
250 rGrafObj.pGraphicLink=NULL;
251 rGrafObj.ReleaseGraphicLink();
252 SvBaseLink::Closed();
255 void SdrGraphicLink::UpdateAsynchron()
257 if( GetObj() )
259 if ( pGraphicUpdater )
261 if ( pGraphicUpdater->GraphicLinkChanged( rGrafObj.GetFileName() ) )
263 pGraphicUpdater->Terminate();
264 pGraphicUpdater = new SdrGraphicUpdater( rGrafObj.GetFileName(), rGrafObj.GetFilterName(), *this );
267 else
268 pGraphicUpdater = new SdrGraphicUpdater( rGrafObj.GetFileName(), rGrafObj.GetFilterName(), *this );
272 sdr::properties::BaseProperties* SdrGrafObj::CreateObjectSpecificProperties()
274 return new sdr::properties::GraphicProperties(*this);
278 // DrawContact section
280 sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
282 return new sdr::contact::ViewContactOfGraphic(*this);
286 // check if SVG and if try to get ObjectInfoPrimitive2D and extract info
288 void SdrGrafObj::onGraphicChanged()
290 if (!pGraphic || pGraphic->IsSwappedOut()) // don't force swap-in for this
291 return;
293 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
295 if (!rSvgDataPtr.get())
296 return;
298 const drawinglayer::primitive2d::Primitive2DSequence aSequence(rSvgDataPtr->getPrimitive2DSequence());
300 if (!aSequence.hasElements())
301 return;
303 drawinglayer::geometry::ViewInformation2D aViewInformation2D;
304 drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor(aViewInformation2D);
306 aProcessor.process(aSequence);
308 const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult();
310 if (!pResult)
311 return;
313 OUString aName = pResult->getName();
314 OUString aTitle = pResult->getTitle();
315 OUString aDesc = pResult->getDesc();
317 if(!aName.isEmpty())
319 SetName(aName);
322 if(!aTitle.isEmpty())
324 SetTitle(aTitle);
327 if(!aDesc.isEmpty())
329 SetDescription(aDesc);
333 TYPEINIT1(SdrGrafObj,SdrRectObj);
335 SdrGrafObj::SdrGrafObj()
336 : SdrRectObj(),
337 pGraphicLink ( NULL ),
338 bMirrored ( false )
340 pGraphic = new GraphicObject;
341 mpReplacementGraphic = 0;
342 pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
343 onGraphicChanged();
345 // #i118485# Shear allowed and possible now
346 bNoShear = false;
348 mbGrafAnimationAllowed = true;
350 // #i25616#
351 mbLineIsOutsideGeometry = true;
352 mbInsidePaint = false;
353 mbIsPreview = false;
355 // #i25616#
356 mbSupportTextIndentingOnLineWidthChange = false;
359 SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
360 : SdrRectObj ( rRect ),
361 pGraphicLink ( NULL ),
362 bMirrored ( false )
364 pGraphic = new GraphicObject( rGrf );
365 mpReplacementGraphic = 0;
366 pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
367 onGraphicChanged();
369 // #i118485# Shear allowed and possible now
370 bNoShear = false;
372 mbGrafAnimationAllowed = true;
374 // #i25616#
375 mbLineIsOutsideGeometry = true;
376 mbInsidePaint = false;
377 mbIsPreview = false;
379 // #i25616#
380 mbSupportTextIndentingOnLineWidthChange = false;
383 SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
384 : SdrRectObj(),
385 pGraphicLink ( NULL ),
386 bMirrored ( false )
388 pGraphic = new GraphicObject( rGrf );
389 mpReplacementGraphic = 0;
390 pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
391 onGraphicChanged();
393 // #i118485# Shear allowed and possible now
394 bNoShear = false;
396 mbGrafAnimationAllowed = true;
398 // #i25616#
399 mbLineIsOutsideGeometry = true;
400 mbInsidePaint = false;
401 mbIsPreview = false;
403 // #i25616#
404 mbSupportTextIndentingOnLineWidthChange = false;
407 SdrGrafObj::~SdrGrafObj()
409 delete pGraphic;
410 delete mpReplacementGraphic;
411 ImpLinkAbmeldung();
414 void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
416 *pGraphic = rGrfObj;
417 delete mpReplacementGraphic;
418 mpReplacementGraphic = 0;
419 pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
420 pGraphic->SetUserData();
421 mbIsPreview = false;
422 SetChanged();
423 BroadcastObjectChange();
424 onGraphicChanged();
427 const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
429 if(bForceSwapIn)
431 ForceSwapIn();
434 return *pGraphic;
437 const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
439 if(!mpReplacementGraphic && pGraphic)
441 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
443 if(rSvgDataPtr.get())
445 const_cast< SdrGrafObj* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement());
449 return mpReplacementGraphic;
452 void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
454 pGraphic->SetGraphic( rGrf );
455 delete mpReplacementGraphic;
456 mpReplacementGraphic = 0;
457 pGraphic->SetUserData();
458 mbIsPreview = false;
459 onGraphicChanged();
462 void SdrGrafObj::SetGraphic( const Graphic& rGrf )
464 NbcSetGraphic(rGrf);
465 SetChanged();
466 BroadcastObjectChange();
469 const Graphic& SdrGrafObj::GetGraphic() const
471 ForceSwapIn();
472 return pGraphic->GetGraphic();
475 Graphic SdrGrafObj::GetTransformedGraphic( SdrGrafObjTransformsAttrs nTransformFlags ) const
477 // Refactored most of the code to GraphicObject, where
478 // everybody can use e.g. the cropping functionality
480 GraphicType eType = GetGraphicType();
481 MapMode aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() );
482 const Size aDestSize( GetLogicRect().GetSize() );
483 const bool bMirror = bool( nTransformFlags & SdrGrafObjTransformsAttrs::MIRROR );
484 const bool bRotate = bool( nTransformFlags & SdrGrafObjTransformsAttrs::ROTATE ) &&
485 ( aGeo.nRotationAngle && aGeo.nRotationAngle != 18000 ) && ( GRAPHIC_NONE != eType );
487 // Need cropping info earlier
488 const_cast<SdrGrafObj*>(this)->ImpSetAttrToGrafInfo();
489 GraphicAttr aActAttr;
491 if( SdrGrafObjTransformsAttrs::NONE != nTransformFlags &&
492 GRAPHIC_NONE != eType )
494 // Actually transform the graphic only in this case.
495 // Cropping always happens, though.
496 aActAttr = aGrafInfo;
498 if( bMirror )
500 sal_uInt16 nMirrorCase = ( aGeo.nRotationAngle == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
501 bool bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
502 bool bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
504 aActAttr.SetMirrorFlags( ( bHMirr ? BmpMirrorFlags::Horizontal : BmpMirrorFlags::NONE ) | ( bVMirr ? BmpMirrorFlags::Vertical : BmpMirrorFlags::NONE ) );
507 if( bRotate )
508 aActAttr.SetRotation( sal_uInt16(aGeo.nRotationAngle / 10) );
511 // Delegate to moved code in GraphicObject
512 return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
515 GraphicType SdrGrafObj::GetGraphicType() const
517 return pGraphic->GetType();
520 bool SdrGrafObj::IsAnimated() const
522 return pGraphic->IsAnimated();
525 bool SdrGrafObj::IsEPS() const
527 return pGraphic->IsEPS();
530 bool SdrGrafObj::IsSwappedOut() const
532 return mbIsPreview || pGraphic->IsSwappedOut();
535 const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
537 return pGraphic->GetPrefMapMode();
540 const Size& SdrGrafObj::GetGrafPrefSize() const
542 return pGraphic->GetPrefSize();
545 void SdrGrafObj::SetGrafStreamURL( const OUString& rGraphicStreamURL )
547 mbIsPreview = false;
548 if( rGraphicStreamURL.isEmpty() )
550 pGraphic->SetUserData();
552 else if( pModel->IsSwapGraphics() )
554 pGraphic->SetUserData( rGraphicStreamURL );
558 OUString SdrGrafObj::GetGrafStreamURL() const
560 return pGraphic->GetUserData();
563 void SdrGrafObj::ForceSwapIn() const
565 if( mbIsPreview && pGraphic->HasUserData() )
567 // removing preview graphic
568 const OUString aUserData( pGraphic->GetUserData() );
570 Graphic aEmpty;
571 pGraphic->SetGraphic( aEmpty );
572 pGraphic->SetUserData( aUserData );
574 const_cast< SdrGrafObj* >( this )->mbIsPreview = false;
576 if ( pGraphicLink && pGraphic->IsSwappedOut() )
577 ImpUpdateGraphicLink( false );
578 else
579 pGraphic->FireSwapInRequest();
581 if( pGraphic->IsSwappedOut() ||
582 ( pGraphic->GetType() == GRAPHIC_NONE ) ||
583 ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
585 Graphic aDefaultGraphic;
586 aDefaultGraphic.SetDefaultType();
587 pGraphic->SetGraphic( aDefaultGraphic );
591 void SdrGrafObj::ImpLinkAnmeldung()
593 sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
595 if( pLinkManager != NULL && pGraphicLink == NULL )
597 if (!aFileName.isEmpty())
599 pGraphicLink = new SdrGraphicLink( *this );
600 pLinkManager->InsertFileLink(
601 *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, (aFilterName.isEmpty() ? NULL : &aFilterName), NULL);
602 pGraphicLink->Connect();
607 void SdrGrafObj::ImpLinkAbmeldung()
609 sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
611 if( pLinkManager != NULL && pGraphicLink!=NULL)
613 // When using Remove, the *pGraphicLink is implicitly deleted
614 pLinkManager->Remove( pGraphicLink );
615 pGraphicLink=NULL;
619 void SdrGrafObj::SetGraphicLink(const OUString& rFileName, const OUString& rReferer, const OUString& rFilterName)
621 ImpLinkAbmeldung();
622 aFileName = rFileName;
623 aReferer = rReferer;
624 aFilterName = rFilterName;
625 ImpLinkAnmeldung();
626 pGraphic->SetUserData();
627 pGraphic->SetSwapState();
630 void SdrGrafObj::ReleaseGraphicLink()
632 ImpLinkAbmeldung();
633 aFileName.clear();
634 aReferer.clear();
635 aFilterName.clear();
638 bool SdrGrafObj::IsLinkedGraphic() const
640 return !aFileName.isEmpty();
645 void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
647 bool bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
649 rInfo.bResizeFreeAllowed = aGeo.nRotationAngle % 9000 == 0 ||
650 aGeo.nRotationAngle % 18000 == 0 ||
651 aGeo.nRotationAngle % 27000 == 0;
653 rInfo.bResizePropAllowed = true;
654 rInfo.bRotateFreeAllowed = bNoPresGrf;
655 rInfo.bRotate90Allowed = bNoPresGrf;
656 rInfo.bMirrorFreeAllowed = bNoPresGrf;
657 rInfo.bMirror45Allowed = bNoPresGrf;
658 rInfo.bMirror90Allowed = !bEmptyPresObj;
659 rInfo.bTransparenceAllowed = false;
660 rInfo.bGradientAllowed = false;
662 // #i118485# Shear allowed and possible now
663 rInfo.bShearAllowed = true;
665 rInfo.bEdgeRadiusAllowed=false;
666 rInfo.bCanConvToPath = !IsEPS();
667 rInfo.bCanConvToPathLineToArea = false;
668 rInfo.bCanConvToPolyLineToArea = false;
669 rInfo.bCanConvToPoly = !IsEPS();
670 rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
673 sal_uInt16 SdrGrafObj::GetObjIdentifier() const
675 return sal_uInt16( OBJ_GRAF );
678 /* The graphic of the GraphicLink will be loaded. If it is called with
679 bAsynchron = true then the graphic will be set later via DataChanged
681 bool SdrGrafObj::ImpUpdateGraphicLink( bool bAsynchron ) const
683 bool bRet = false;
684 if( pGraphicLink )
686 if ( bAsynchron )
687 pGraphicLink->UpdateAsynchron();
688 else
689 pGraphicLink->DataChanged( ImpLoadLinkedGraphic( aFileName, aReferer, aFilterName ) );
690 bRet = true;
692 return bRet;
695 void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
697 const bool bIsChanged = GetModel()->IsChanged();
698 NbcSetGraphic( rGraphic );
699 ActionChanged();
700 BroadcastObjectChange();
701 GetModel()->SetChanged( bIsChanged );
704 OUString SdrGrafObj::TakeObjNameSingul() const
706 if (!pGraphic)
707 return OUString();
709 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
711 OUStringBuffer sName;
713 if(rSvgDataPtr.get())
715 sName.append(ImpGetResStr(STR_ObjNameSingulGRAFSVG));
717 else
719 switch( pGraphic->GetType() )
721 case GRAPHIC_BITMAP:
723 const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || static_cast<const SdrGrafTransparenceItem&>( GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
724 ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
725 ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
727 sName.append(ImpGetResStr(nId));
729 break;
731 case GRAPHIC_GDIMETAFILE:
732 sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF));
733 break;
735 case GRAPHIC_NONE:
736 sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE));
737 break;
739 default:
740 sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF));
741 break;
745 const OUString aName(GetName());
747 if (!aName.isEmpty())
749 sName.append(" '");
750 sName.append(aName);
751 sName.append('\'' );
754 return sName.makeStringAndClear();
757 OUString SdrGrafObj::TakeObjNamePlural() const
759 if(!pGraphic)
760 return OUString();
762 const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
764 OUStringBuffer sName;
766 if(rSvgDataPtr.get())
768 sName.append(ImpGetResStr(STR_ObjNamePluralGRAFSVG));
770 else
772 switch( pGraphic->GetType() )
774 case GRAPHIC_BITMAP:
776 const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || static_cast<const SdrGrafTransparenceItem&>( GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
777 ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
778 ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
780 sName.append(ImpGetResStr(nId));
782 break;
784 case GRAPHIC_GDIMETAFILE:
785 sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF));
786 break;
788 case GRAPHIC_NONE:
789 sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE));
790 break;
792 default:
793 sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF));
794 break;
798 const OUString aName(GetName());
800 if (!aName.isEmpty())
802 sName.append(" '");
803 sName.append(aName);
804 sName.append('\'');
807 return sName.makeStringAndClear();
810 SdrObject* SdrGrafObj::getFullDragClone() const
812 // call parent
813 SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
815 // #i103116# the full drag clone leads to problems
816 // with linked graphics, so reset the link in this
817 // temporary interaction object and load graphic
818 if(pRetval && IsLinkedGraphic())
820 pRetval->ForceSwapIn();
821 pRetval->ReleaseGraphicLink();
824 return pRetval;
827 SdrGrafObj* SdrGrafObj::Clone() const
829 return CloneHelper< SdrGrafObj >();
832 SdrGrafObj& SdrGrafObj::operator=( const SdrGrafObj& rObj )
834 if( this == &rObj )
835 return *this;
836 SdrRectObj::operator=( rObj );
838 pGraphic->SetGraphic( rObj.GetGraphic(), &rObj.GetGraphicObject() );
839 aFileName = rObj.aFileName;
840 aFilterName = rObj.aFilterName;
841 bMirrored = rObj.bMirrored;
843 if( rObj.IsLinkedGraphic() )
845 SetGraphicLink( aFileName, rObj.aReferer, aFilterName );
848 ImpSetAttrToGrafInfo();
849 return *this;
852 basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const
854 if(mbInsidePaint)
856 basegfx::B2DPolyPolygon aRetval;
858 // take grown rectangle
859 const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2);
860 const Rectangle aGrownRect(
861 maRect.Left() - nHalfLineWidth,
862 maRect.Top() - nHalfLineWidth,
863 maRect.Right() + nHalfLineWidth,
864 maRect.Bottom() + nHalfLineWidth);
866 XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius()));
867 aRetval.append(aXPoly.getB2DPolygon());
869 return aRetval;
871 else
873 // call parent
874 return SdrRectObj::TakeXorPoly();
878 sal_uInt32 SdrGrafObj::GetHdlCount() const
880 return 8L;
883 SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
885 return SdrRectObj::GetHdl( nHdlNum + 1L );
888 void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
890 SdrRectObj::NbcResize( rRef, xFact, yFact );
892 bool bMirrX = xFact.GetNumerator() < 0;
893 bool bMirrY = yFact.GetNumerator() < 0;
895 if( bMirrX != bMirrY )
896 bMirrored = !bMirrored;
899 void SdrGrafObj::NbcRotate(const Point& rRef, long nAngle, double sn, double cs)
901 SdrRectObj::NbcRotate(rRef,nAngle,sn,cs);
904 void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
906 SdrRectObj::NbcMirror(rRef1,rRef2);
907 bMirrored = !bMirrored;
910 void SdrGrafObj::NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear)
912 // #i118485# Call Shear now, old version redirected to rotate
913 SdrRectObj::NbcShear(rRef, nAngle, tn, bVShear);
916 void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect)
918 SdrRectObj::NbcSetSnapRect(rRect);
921 void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect)
923 SdrRectObj::NbcSetLogicRect(rRect);
926 SdrObjGeoData* SdrGrafObj::NewGeoData() const
928 return new SdrGrafObjGeoData;
931 void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
933 SdrRectObj::SaveGeoData(rGeo);
934 SdrGrafObjGeoData& rGGeo=static_cast<SdrGrafObjGeoData&>(rGeo);
935 rGGeo.bMirrored=bMirrored;
938 void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo)
940 SdrRectObj::RestGeoData(rGeo);
941 const SdrGrafObjGeoData& rGGeo=static_cast<const SdrGrafObjGeoData&>(rGeo);
942 bMirrored=rGGeo.bMirrored;
945 void SdrGrafObj::SetPage( SdrPage* pNewPage )
947 bool bRemove = pNewPage == NULL && pPage != NULL;
948 bool bInsert = pNewPage != NULL && pPage == NULL;
950 if( bRemove )
952 // No SwapIn necessary here, because if something's not loaded, it can't be animated either.
953 if( pGraphic->IsAnimated())
954 pGraphic->StopAnimation();
956 if( pGraphicLink != NULL )
957 ImpLinkAbmeldung();
960 if(!pModel && !GetStyleSheet() && pNewPage && pNewPage->GetModel())
962 // #i119287# Set default StyleSheet for SdrGrafObj here, it is different from 'Default'. This
963 // needs to be done before the style 'Default' is set from the :SetModel() call which is triggered
964 // from the following :SetPage().
965 // TTTT: Needs to be moved in branch aw080 due to having a SdrModel from the beginning, is at this
966 // place for convenience currently (works in both versions, is not in the way)
967 SfxStyleSheet* pSheet = pNewPage->GetModel()->GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj();
969 if(pSheet)
971 SetStyleSheet(pSheet, false);
973 else
975 SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
976 SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
980 SdrRectObj::SetPage( pNewPage );
982 if (!aFileName.isEmpty() && bInsert)
983 ImpLinkAnmeldung();
986 void SdrGrafObj::SetModel( SdrModel* pNewModel )
988 bool bChg = pNewModel != pModel;
990 if( bChg )
992 if( pGraphic->HasUserData() )
994 ForceSwapIn();
997 if( pGraphicLink != NULL )
998 ImpLinkAbmeldung();
1001 // realize model
1002 SdrRectObj::SetModel(pNewModel);
1004 if (bChg && !aFileName.isEmpty())
1005 ImpLinkAnmeldung();
1008 void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/)
1010 SetGrafAnimationAllowed(true);
1013 bool SdrGrafObj::HasGDIMetaFile() const
1015 return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE );
1018 bool SdrGrafObj::isEmbeddedSvg() const
1020 return GRAPHIC_BITMAP == GetGraphicType() && GetGraphic().getSvgData().get();
1023 GDIMetaFile SdrGrafObj::getMetafileFromEmbeddedSvg() const
1025 GDIMetaFile aRetval;
1027 if(isEmbeddedSvg() && GetModel())
1029 ScopedVclPtrInstance< VirtualDevice > pOut;
1030 const Rectangle aBoundRect(GetCurrentBoundRect());
1031 const MapMode aMap(GetModel()->GetScaleUnit(), Point(), GetModel()->GetScaleFraction(), GetModel()->GetScaleFraction());
1033 pOut->EnableOutput(false);
1034 pOut->SetMapMode(aMap);
1035 aRetval.Record(pOut);
1036 SingleObjectPainter(*pOut.get());
1037 aRetval.Stop();
1038 aRetval.WindStart();
1039 aRetval.Move(-aBoundRect.Left(), -aBoundRect.Top());
1040 aRetval.SetPrefMapMode(aMap);
1041 aRetval.SetPrefSize(aBoundRect.GetSize());
1044 return aRetval;
1047 SdrObject* SdrGrafObj::DoConvertToPolyObj(bool bBezier, bool bAddText ) const
1049 SdrObject* pRetval = NULL;
1050 GraphicType aGraphicType(GetGraphicType());
1051 GDIMetaFile aMtf;
1053 if(isEmbeddedSvg())
1055 // Embedded Svg
1056 // There is currently no helper to create SdrObjects from primitives (even if I'm thinking
1057 // about writing one for some time). To get the roundtrip to SdrObjects it is necessary to
1058 // use the old converter path over the MetaFile mechanism. Create Metafile from Svg
1059 // primitives here pretty directly
1060 aMtf = getMetafileFromEmbeddedSvg();
1061 aGraphicType = GRAPHIC_GDIMETAFILE;
1063 else if(GRAPHIC_GDIMETAFILE == aGraphicType)
1065 aMtf = GetTransformedGraphic(SdrGrafObjTransformsAttrs::COLOR|SdrGrafObjTransformsAttrs::MIRROR).GetGDIMetaFile();
1068 switch(aGraphicType)
1070 case GRAPHIC_GDIMETAFILE:
1072 // Sort into group and return ONLY those objects that can be created from the MetaFile.
1073 ImpSdrGDIMetaFileImport aFilter(*GetModel(), GetLayer(), maRect);
1074 SdrObjGroup* pGrp = new SdrObjGroup();
1076 if(aFilter.DoImport(aMtf, *pGrp->GetSubList(), 0))
1079 // copy transformation
1080 GeoStat aGeoStat(GetGeoStat());
1082 if(aGeoStat.nShearAngle)
1084 aGeoStat.RecalcTan();
1085 pGrp->NbcShear(maRect.TopLeft(), aGeoStat.nShearAngle, aGeoStat.nTan, false);
1088 if(aGeoStat.nRotationAngle)
1090 aGeoStat.RecalcSinCos();
1091 pGrp->NbcRotate(maRect.TopLeft(), aGeoStat.nRotationAngle, aGeoStat.nSin, aGeoStat.nCos);
1095 pRetval = pGrp;
1096 pGrp->NbcSetLayer(GetLayer());
1097 pGrp->SetModel(GetModel());
1099 if(bAddText)
1101 pRetval = ImpConvertAddText(pRetval, bBezier);
1104 // convert all children
1105 if( pRetval )
1107 SdrObject* pHalfDone = pRetval;
1108 pRetval = pHalfDone->DoConvertToPolyObj(bBezier, bAddText);
1109 SdrObject::Free( pHalfDone ); // resulting object is newly created
1111 if( pRetval )
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();
1123 else
1125 delete pGrp;
1128 // #i118485# convert line and fill
1129 SdrObject* pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false);
1131 if(pLineFill)
1133 if(pRetval)
1135 pGrp = dynamic_cast< SdrObjGroup* >(pRetval);
1137 if(!pGrp)
1139 pGrp = new SdrObjGroup();
1141 pGrp->NbcSetLayer(GetLayer());
1142 pGrp->SetModel(GetModel());
1143 pGrp->GetSubList()->NbcInsertObject(pRetval);
1146 pGrp->GetSubList()->NbcInsertObject(pLineFill, 0);
1148 else
1150 pRetval = pLineFill;
1154 break;
1156 case GRAPHIC_BITMAP:
1158 // create basic object and add fill
1159 pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1161 // save bitmap as an attribute
1162 if(pRetval)
1164 // retrieve bitmap for the fill
1165 SfxItemSet aSet(GetObjectItemSet());
1167 aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
1168 const BitmapEx aBitmapEx(GetTransformedGraphic().GetBitmapEx());
1169 aSet.Put(XFillBitmapItem(OUString(), Graphic(aBitmapEx)));
1170 aSet.Put(XFillBmpTileItem(false));
1172 pRetval->SetMergedItemSet(aSet);
1174 break;
1176 case GRAPHIC_NONE:
1177 case GRAPHIC_DEFAULT:
1179 pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1180 break;
1184 return pRetval;
1187 void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1189 SetXPolyDirty();
1190 SdrRectObj::Notify( rBC, rHint );
1191 ImpSetAttrToGrafInfo();
1195 void SdrGrafObj::SetMirrored( bool _bMirrored )
1197 bMirrored = _bMirrored;
1200 void SdrGrafObj::ImpSetAttrToGrafInfo()
1202 const SfxItemSet& rSet = GetObjectItemSet();
1203 const sal_uInt16 nTrans = static_cast<const SdrGrafTransparenceItem&>( rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue();
1204 const SdrGrafCropItem& rCrop = static_cast<const SdrGrafCropItem&>( rSet.Get( SDRATTR_GRAFCROP ) );
1206 aGrafInfo.SetLuminance( static_cast<const SdrGrafLuminanceItem&>( rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() );
1207 aGrafInfo.SetContrast( static_cast<const SdrGrafContrastItem&>( rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() );
1208 aGrafInfo.SetChannelR( static_cast<const SdrGrafRedItem&>( rSet.Get( SDRATTR_GRAFRED ) ).GetValue() );
1209 aGrafInfo.SetChannelG( static_cast<const SdrGrafGreenItem&>( rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() );
1210 aGrafInfo.SetChannelB( static_cast<const SdrGrafBlueItem&>( rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() );
1211 aGrafInfo.SetGamma( static_cast<const SdrGrafGamma100Item&>( rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 );
1212 aGrafInfo.SetTransparency( (sal_uInt8) FRound( std::min( nTrans, (sal_uInt16) 100 ) * 2.55 ) );
1213 aGrafInfo.SetInvert( static_cast<const SdrGrafInvertItem&>( rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() );
1214 aGrafInfo.SetDrawMode( static_cast<const SdrGrafModeItem&>( rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() );
1215 aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
1217 SetXPolyDirty();
1218 SetRectsDirty();
1221 void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly )
1223 Size aSize;
1224 Size aMaxSize( rMaxRect.GetSize() );
1225 if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1226 aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM );
1227 else
1228 aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1229 pGraphic->GetPrefMapMode(),
1230 MapMode( MAP_100TH_MM ) );
1232 if( aSize.Height() != 0 && aSize.Width() != 0 )
1234 Point aPos( rMaxRect.TopLeft() );
1236 // if the graphic is too large, fit it to page
1237 if ( (!bShrinkOnly ||
1238 ( aSize.Height() > aMaxSize.Height() ) ||
1239 ( aSize.Width() > aMaxSize.Width() ) )&&
1240 aSize.Height() && aMaxSize.Height() )
1242 float fGrfWH = (float)aSize.Width() /
1243 (float)aSize.Height();
1244 float fWinWH = (float)aMaxSize.Width() /
1245 (float)aMaxSize.Height();
1247 // Scale graphic to page size
1248 if ( fGrfWH < fWinWH )
1250 aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
1251 aSize.Height()= aMaxSize.Height();
1253 else if ( fGrfWH > 0.F )
1255 aSize.Width() = aMaxSize.Width();
1256 aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
1259 aPos = rMaxRect.Center();
1262 if( bShrinkOnly )
1263 aPos = maRect.TopLeft();
1265 aPos.X() -= aSize.Width() / 2;
1266 aPos.Y() -= aSize.Height() / 2;
1267 SetLogicRect( Rectangle( aPos, aSize ) );
1271 IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
1273 SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1275 if( pO->IsInSwapOut() )
1277 if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
1279 // test if this object is visualized from someone
1280 // ## test only if there are VOCs other than the preview renderer
1281 if(!GetViewContact().HasViewObjectContacts(true))
1283 const SdrSwapGraphicsMode nSwapMode = pModel->GetSwapGraphicsMode();
1285 if( ( pGraphicLink ) &&
1286 ( nSwapMode & SdrSwapGraphicsMode::PURGE ) )
1288 pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1290 else if( nSwapMode & SdrSwapGraphicsMode::TEMP )
1292 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1293 pGraphic->SetUserData();
1296 // #i102380#
1297 sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
1299 if(pVC)
1301 pVC->flushGraphicObjects();
1306 else if( pO->IsInSwapIn() )
1308 // can be loaded from the original document stream later
1309 if( pModel != NULL )
1311 if( pGraphic->HasUserData() )
1313 ::comphelper::LifecycleProxy proxy;
1314 OUString aUserData = pGraphic->GetUserData();
1315 uno::Reference<io::XInputStream> const xStream(
1316 pModel->GetDocumentStream(aUserData, proxy));
1318 ::boost::scoped_ptr<SvStream> const pStream( (xStream.is())
1319 ? ::utl::UcbStreamHelper::CreateStream(xStream)
1320 : 0 );
1322 if( pStream != 0 )
1324 Graphic aGraphic;
1326 boost::scoped_ptr<com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > > pFilterData;
1328 if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
1330 pFilterData.reset(new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 ));
1332 const com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
1333 const bool bAllowPartialStreamRead = true;
1334 // create <GfxLink> instance also for previews in order to avoid that its corresponding
1335 // data is cleared in the graphic cache entry in case that the preview data equals the complete graphic data
1336 const bool bCreateNativeLink = true;
1337 (*pFilterData)[ 0 ].Name = "PreviewSizeHint";
1338 (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint;
1339 (*pFilterData)[ 1 ].Name = "AllowPartialStreamRead";
1340 (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead;
1341 (*pFilterData)[ 2 ].Name = "CreateNativeLink";
1342 (*pFilterData)[ 2 ].Value <<= bCreateNativeLink;
1344 mbIsPreview = true;
1347 if(!GraphicFilter::GetGraphicFilter().ImportGraphic(
1348 aGraphic, aUserData, *pStream,
1349 GRFILTER_FORMAT_DONTKNOW, NULL, GraphicFilterImportFlags::NONE, pFilterData.get()))
1351 const OUString aNewUserData( pGraphic->GetUserData() );
1352 pGraphic->SetGraphic( aGraphic );
1353 if( mbIsPreview )
1355 pGraphic->SetUserData(aNewUserData);
1357 else
1359 pGraphic->SetUserData();
1362 // Graphic successfully swapped in.
1363 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1365 pFilterData.reset();
1367 pStream->ResetError();
1370 else if( !ImpUpdateGraphicLink( false ) )
1372 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1374 else
1376 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1379 else
1380 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1383 return reinterpret_cast<sal_IntPtr>(pRet);
1386 void SdrGrafObj::SetGrafAnimationAllowed(bool bNew)
1388 if(mbGrafAnimationAllowed != bNew)
1390 mbGrafAnimationAllowed = bNew;
1391 ActionChanged();
1395 Reference< XInputStream > SdrGrafObj::getInputStream()
1397 Reference< XInputStream > xStream;
1399 if( pModel )
1401 if( pGraphic && GetGraphic().IsLink() )
1403 Graphic aGraphic( GetGraphic() );
1404 GfxLink aLink( aGraphic.GetLink() );
1405 sal_uInt32 nSize = aLink.GetDataSize();
1406 const void* pSourceData = (const void*)aLink.GetData();
1407 if( nSize && pSourceData )
1409 sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
1410 memcpy( pBuffer, pSourceData, nSize );
1412 SvMemoryStream* pStream = new SvMemoryStream( (void*)pBuffer, (sal_Size)nSize, StreamMode::READ );
1413 pStream->ObjectOwnsMemory( true );
1414 xStream.set( new utl::OInputStreamWrapper( pStream, true ) );
1418 if (!xStream.is() && !aFileName.isEmpty())
1420 SvFileStream* pStream = new SvFileStream( aFileName, StreamMode::READ );
1421 xStream.set( new utl::OInputStreamWrapper( pStream ) );
1425 return xStream;
1428 // moved crop handle creation here; this is the object type using them
1429 void SdrGrafObj::addCropHandles(SdrHdlList& rTarget) const
1431 basegfx::B2DHomMatrix aMatrix;
1432 basegfx::B2DPolyPolygon aPolyPolygon;
1434 // get object transformation
1435 TRGetBaseGeometry(aMatrix, aPolyPolygon);
1437 // part of object transformation correction, but used later, so defined outside next scope
1438 double fShearX(0.0), fRotate(0.0);
1440 { // TTTT correct shear, it comes currently mirrored from TRGetBaseGeometry, can be removed with aw080
1441 basegfx::B2DTuple aScale;
1442 basegfx::B2DTuple aTranslate;
1444 aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1446 if(!basegfx::fTools::equalZero(fShearX))
1448 // shearX is used, correct it
1449 fShearX = -fShearX;
1452 aMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1453 aScale,
1454 fShearX,
1455 fRotate,
1456 aTranslate);
1459 // get crop values
1460 const SdrGrafCropItem& rCrop = static_cast< const SdrGrafCropItem& >(GetMergedItem(SDRATTR_GRAFCROP));
1462 if(rCrop.GetLeft() || rCrop.GetTop() || rCrop.GetRight() ||rCrop.GetBottom())
1464 // decompose object transformation to have current translate and scale
1465 basegfx::B2DVector aScale, aTranslate;
1466 double fLclRotate, fLclShearX;
1468 aMatrix.decompose(aScale, aTranslate, fLclRotate, fLclShearX);
1470 if(!aScale.equalZero())
1472 // get crop scale
1473 const basegfx::B2DVector aCropScaleFactor(
1474 GetGraphicObject().calculateCropScaling(
1475 aScale.getX(),
1476 aScale.getY(),
1477 rCrop.GetLeft(),
1478 rCrop.GetTop(),
1479 rCrop.GetRight(),
1480 rCrop.GetBottom()));
1482 // apply crop scale
1483 const double fCropLeft(rCrop.GetLeft() * aCropScaleFactor.getX());
1484 const double fCropTop(rCrop.GetTop() * aCropScaleFactor.getY());
1485 const double fCropRight(rCrop.GetRight() * aCropScaleFactor.getX());
1486 const double fCropBottom(rCrop.GetBottom() * aCropScaleFactor.getY());
1487 basegfx::B2DHomMatrix aMatrixForCropViewHdl(aMatrix);
1489 if(IsMirrored())
1491 // create corrected new matrix, TTTT can be removed with aw080
1492 // the old mirror only can mirror horizontally; the vertical mirror
1493 // is faked by using the horizontal and 180 degree rotation. Since
1494 // the object can be rotated differently from 180 degree, this is
1495 // not safe to detect. Just correct horizontal mirror (which is
1496 // in IsMirrored()) and keep the rotation angle
1497 // caution: Do not modify aMatrix, it is used below to calculate
1498 // the exact handle positions
1499 basegfx::B2DHomMatrix aPreMultiply;
1501 // mirrored X, apply
1502 aPreMultiply.translate(-0.5, 0.0);
1503 aPreMultiply.scale(-1.0, 1.0);
1504 aPreMultiply.translate(0.5, 0.0);
1506 aMatrixForCropViewHdl = aMatrixForCropViewHdl * aPreMultiply;
1509 rTarget.AddHdl(
1510 new SdrCropViewHdl(
1511 aMatrixForCropViewHdl,
1512 GetGraphicObject().GetGraphic(),
1513 fCropLeft,
1514 fCropTop,
1515 fCropRight,
1516 fCropBottom));
1520 basegfx::B2DPoint aPos;
1522 aPos = aMatrix * basegfx::B2DPoint(0.0, 0.0);
1523 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPLFT, fShearX, fRotate));
1524 aPos = aMatrix * basegfx::B2DPoint(0.5, 0.0);
1525 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPPER, fShearX, fRotate));
1526 aPos = aMatrix * basegfx::B2DPoint(1.0, 0.0);
1527 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPRGT, fShearX, fRotate));
1528 aPos = aMatrix * basegfx::B2DPoint(0.0, 0.5);
1529 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LEFT , fShearX, fRotate));
1530 aPos = aMatrix * basegfx::B2DPoint(1.0, 0.5);
1531 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_RIGHT, fShearX, fRotate));
1532 aPos = aMatrix * basegfx::B2DPoint(0.0, 1.0);
1533 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWLFT, fShearX, fRotate));
1534 aPos = aMatrix * basegfx::B2DPoint(0.5, 1.0);
1535 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LOWER, fShearX, fRotate));
1536 aPos = aMatrix * basegfx::B2DPoint(1.0, 1.0);
1537 rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWRGT, fShearX, fRotate));
1540 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */