Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <unotools/streamwrap.hxx>
21 :
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>
35 :
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>
65 :
66 : using namespace ::com::sun::star;
67 : using namespace ::com::sun::star::uno;
68 : using namespace ::com::sun::star::io;
69 :
70 13 : const Graphic ImpLoadLinkedGraphic( const OUString& aFileName, const OUString& aReferer, const OUString& aFilterName )
71 : {
72 13 : Graphic aGraphic;
73 :
74 26 : SfxMedium xMed( aFileName, aReferer, STREAM_STD_READ );
75 13 : xMed.Download();
76 :
77 13 : SvStream* pInStrm = xMed.GetInStream();
78 13 : if ( pInStrm )
79 : {
80 13 : pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
81 13 : GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
82 :
83 26 : const sal_uInt16 nFilter = !aFilterName.isEmpty() && rGF.GetImportFormatCount()
84 : ? rGF.GetImportFormatNumber( aFilterName )
85 26 : : GRFILTER_FORMAT_DONTKNOW;
86 :
87 13 : css::uno::Sequence< css::beans::PropertyValue > aFilterData( 1 );
88 :
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 13 : aFilterData[ 0 ].Name = "CreateNativeLink";
94 13 : aFilterData[ 0 ].Value = Any( sal_True );
95 :
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 13 : rGF.ImportGraphic( aGraphic, aFileName, *pInStrm, nFilter, NULL, GraphicFilterImportFlags::NONE, &aFilterData );
103 : }
104 26 : return aGraphic;
105 : }
106 :
107 : class SdrGraphicUpdater;
108 : class SdrGraphicLink : public sfx2::SvBaseLink
109 : {
110 : SdrGrafObj& rGrafObj;
111 : SdrGraphicUpdater* pGraphicUpdater;
112 :
113 : public:
114 : explicit SdrGraphicLink(SdrGrafObj& rObj);
115 : virtual ~SdrGraphicLink();
116 :
117 : virtual void Closed() SAL_OVERRIDE;
118 :
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 );
122 :
123 15 : bool Connect() { return 0 != GetRealObject(); }
124 : void UpdateAsynchron();
125 : void RemoveGraphicUpdater();
126 :
127 0 : OUString getReferer() const { return rGrafObj.aReferer; }
128 : };
129 :
130 : class SdrGraphicUpdater : public ::osl::Thread
131 : {
132 : public:
133 : SdrGraphicUpdater( const OUString& rFileName, const OUString& rFilterName, SdrGraphicLink& );
134 : virtual ~SdrGraphicUpdater();
135 :
136 : void SAL_CALL Terminate();
137 :
138 0 : bool GraphicLinkChanged( const OUString& rFileName ){ return maFileName != rFileName; };
139 :
140 : protected:
141 :
142 : /** is called from the inherited create method and acts as the
143 : main function of this thread.
144 : */
145 : virtual void SAL_CALL run() SAL_OVERRIDE;
146 :
147 : /** Called after the thread is terminated via the terminate
148 : method. Used to kill the thread by calling delete on this.
149 : */
150 : virtual void SAL_CALL onTerminated() SAL_OVERRIDE;
151 :
152 : private:
153 :
154 : const OUString maFileName;
155 : const OUString maFilterName;
156 : SdrGraphicLink& mrGraphicLink;
157 :
158 : volatile bool mbIsTerminated;
159 : };
160 :
161 0 : SdrGraphicUpdater::SdrGraphicUpdater( const OUString& rFileName, const OUString& rFilterName, SdrGraphicLink& rGraphicLink )
162 : : maFileName( rFileName )
163 : , maFilterName( rFilterName )
164 : , mrGraphicLink( rGraphicLink )
165 0 : , mbIsTerminated( false )
166 : {
167 0 : create();
168 0 : }
169 :
170 0 : SdrGraphicUpdater::~SdrGraphicUpdater()
171 : {
172 0 : }
173 :
174 0 : void SdrGraphicUpdater::Terminate()
175 : {
176 0 : mbIsTerminated = true;
177 0 : }
178 :
179 0 : void SAL_CALL SdrGraphicUpdater::onTerminated()
180 : {
181 0 : delete this;
182 0 : }
183 :
184 0 : void SAL_CALL SdrGraphicUpdater::run()
185 : {
186 0 : osl_setThreadName("SdrGraphicUpdater");
187 :
188 0 : Graphic aGraphic( ImpLoadLinkedGraphic( maFileName, mrGraphicLink.getReferer(), maFilterName ) );
189 0 : SolarMutexGuard aSolarGuard;
190 0 : if ( !mbIsTerminated )
191 : {
192 0 : mrGraphicLink.DataChanged( aGraphic );
193 0 : mrGraphicLink.RemoveGraphicUpdater();
194 0 : }
195 0 : }
196 :
197 15 : SdrGraphicLink::SdrGraphicLink(SdrGrafObj& rObj)
198 : : ::sfx2::SvBaseLink( ::SfxLinkUpdateMode::ONCALL, SotClipboardFormatId::SVXB )
199 : , rGrafObj( rObj )
200 15 : , pGraphicUpdater( NULL )
201 : {
202 15 : SetSynchron( false );
203 15 : }
204 :
205 42 : SdrGraphicLink::~SdrGraphicLink()
206 : {
207 14 : if ( pGraphicUpdater )
208 0 : pGraphicUpdater->Terminate();
209 28 : }
210 :
211 13 : void SdrGraphicLink::DataChanged( const Graphic& rGraphic )
212 : {
213 13 : rGrafObj.ImpSetLinkedGraphic( rGraphic );
214 13 : }
215 :
216 0 : void SdrGraphicLink::RemoveGraphicUpdater()
217 : {
218 0 : pGraphicUpdater = NULL;
219 0 : }
220 :
221 3 : ::sfx2::SvBaseLink::UpdateResult SdrGraphicLink::DataChanged(
222 : const OUString& rMimeType, const ::com::sun::star::uno::Any & rValue )
223 : {
224 3 : SdrModel* pModel = rGrafObj.GetModel();
225 3 : sfx2::LinkManager* pLinkManager= pModel ? pModel->GetLinkManager() : 0;
226 :
227 3 : if( pLinkManager && rValue.hasValue() )
228 : {
229 3 : sfx2::LinkManager::GetDisplayNames( this, 0, &rGrafObj.aFileName, 0, &rGrafObj.aFilterName );
230 :
231 3 : Graphic aGraphic;
232 3 : if( sfx2::LinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
233 : {
234 0 : rGrafObj.NbcSetGraphic( aGraphic );
235 0 : rGrafObj.ActionChanged();
236 : }
237 3 : else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() )
238 : {
239 : // broadcasting, to update slide sorter
240 3 : rGrafObj.BroadcastObjectChange();
241 3 : }
242 : }
243 3 : return SUCCESS;
244 : }
245 :
246 0 : void SdrGraphicLink::Closed()
247 : {
248 : // close connection; set pLink of the object to NULL, as link instance is just about getting destructed.
249 0 : rGrafObj.ForceSwapIn();
250 0 : rGrafObj.pGraphicLink=NULL;
251 0 : rGrafObj.ReleaseGraphicLink();
252 0 : SvBaseLink::Closed();
253 0 : }
254 :
255 0 : void SdrGraphicLink::UpdateAsynchron()
256 : {
257 0 : if( GetObj() )
258 : {
259 0 : if ( pGraphicUpdater )
260 : {
261 0 : if ( pGraphicUpdater->GraphicLinkChanged( rGrafObj.GetFileName() ) )
262 : {
263 0 : pGraphicUpdater->Terminate();
264 0 : pGraphicUpdater = new SdrGraphicUpdater( rGrafObj.GetFileName(), rGrafObj.GetFilterName(), *this );
265 : }
266 : }
267 : else
268 0 : pGraphicUpdater = new SdrGraphicUpdater( rGrafObj.GetFileName(), rGrafObj.GetFilterName(), *this );
269 : }
270 0 : }
271 :
272 780 : sdr::properties::BaseProperties* SdrGrafObj::CreateObjectSpecificProperties()
273 : {
274 780 : return new sdr::properties::GraphicProperties(*this);
275 : }
276 :
277 :
278 : // DrawContact section
279 :
280 825 : sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
281 : {
282 825 : return new sdr::contact::ViewContactOfGraphic(*this);
283 : }
284 :
285 :
286 : // check if SVG and if try to get ObjectInfoPrimitive2D and extract info
287 :
288 1777 : void SdrGrafObj::onGraphicChanged()
289 : {
290 1777 : if (!pGraphic || pGraphic->IsSwappedOut()) // don't force swap-in for this
291 1777 : return;
292 :
293 1777 : const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
294 :
295 1777 : if (!rSvgDataPtr.get())
296 1777 : return;
297 :
298 0 : const drawinglayer::primitive2d::Primitive2DSequence aSequence(rSvgDataPtr->getPrimitive2DSequence());
299 :
300 0 : if (!aSequence.hasElements())
301 0 : return;
302 :
303 0 : drawinglayer::geometry::ViewInformation2D aViewInformation2D;
304 0 : drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor(aViewInformation2D);
305 :
306 0 : aProcessor.process(aSequence);
307 :
308 0 : const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult();
309 :
310 0 : if (!pResult)
311 0 : return;
312 :
313 0 : OUString aName = pResult->getName();
314 0 : OUString aTitle = pResult->getTitle();
315 0 : OUString aDesc = pResult->getDesc();
316 :
317 0 : if(!aName.isEmpty())
318 : {
319 0 : SetName(aName);
320 : }
321 :
322 0 : if(!aTitle.isEmpty())
323 : {
324 0 : SetTitle(aTitle);
325 : }
326 :
327 0 : if(!aDesc.isEmpty())
328 : {
329 0 : SetDescription(aDesc);
330 0 : }
331 : }
332 :
333 124766 : TYPEINIT1(SdrGrafObj,SdrRectObj);
334 :
335 762 : SdrGrafObj::SdrGrafObj()
336 : : SdrRectObj(),
337 : pGraphicLink ( NULL ),
338 762 : bMirrored ( false )
339 : {
340 762 : pGraphic = new GraphicObject;
341 762 : mpReplacementGraphic = 0;
342 762 : pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
343 762 : onGraphicChanged();
344 :
345 : // #i118485# Shear allowed and possible now
346 762 : bNoShear = false;
347 :
348 762 : mbGrafAnimationAllowed = true;
349 :
350 : // #i25616#
351 762 : mbLineIsOutsideGeometry = true;
352 762 : mbInsidePaint = false;
353 762 : mbIsPreview = false;
354 :
355 : // #i25616#
356 762 : mbSupportTextIndentingOnLineWidthChange = false;
357 762 : }
358 :
359 63 : SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
360 : : SdrRectObj ( rRect ),
361 : pGraphicLink ( NULL ),
362 63 : bMirrored ( false )
363 : {
364 63 : pGraphic = new GraphicObject( rGrf );
365 63 : mpReplacementGraphic = 0;
366 63 : pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
367 63 : onGraphicChanged();
368 :
369 : // #i118485# Shear allowed and possible now
370 63 : bNoShear = false;
371 :
372 63 : mbGrafAnimationAllowed = true;
373 :
374 : // #i25616#
375 63 : mbLineIsOutsideGeometry = true;
376 63 : mbInsidePaint = false;
377 63 : mbIsPreview = false;
378 :
379 : // #i25616#
380 63 : mbSupportTextIndentingOnLineWidthChange = false;
381 63 : }
382 :
383 0 : SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
384 : : SdrRectObj(),
385 : pGraphicLink ( NULL ),
386 0 : bMirrored ( false )
387 : {
388 0 : pGraphic = new GraphicObject( rGrf );
389 0 : mpReplacementGraphic = 0;
390 0 : pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
391 0 : onGraphicChanged();
392 :
393 : // #i118485# Shear allowed and possible now
394 0 : bNoShear = false;
395 :
396 0 : mbGrafAnimationAllowed = true;
397 :
398 : // #i25616#
399 0 : mbLineIsOutsideGeometry = true;
400 0 : mbInsidePaint = false;
401 0 : mbIsPreview = false;
402 :
403 : // #i25616#
404 0 : mbSupportTextIndentingOnLineWidthChange = false;
405 0 : }
406 :
407 2469 : SdrGrafObj::~SdrGrafObj()
408 : {
409 823 : delete pGraphic;
410 823 : delete mpReplacementGraphic;
411 823 : ImpLinkAbmeldung();
412 1646 : }
413 :
414 512 : void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
415 : {
416 512 : *pGraphic = rGrfObj;
417 512 : delete mpReplacementGraphic;
418 512 : mpReplacementGraphic = 0;
419 512 : pGraphic->SetSwapStreamHdl( LINK(this, SdrGrafObj, ImpSwapHdl) );
420 512 : pGraphic->SetUserData();
421 512 : mbIsPreview = false;
422 512 : SetChanged();
423 512 : BroadcastObjectChange();
424 512 : onGraphicChanged();
425 512 : }
426 :
427 3181 : const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
428 : {
429 3181 : if(bForceSwapIn)
430 : {
431 572 : ForceSwapIn();
432 : }
433 :
434 3181 : return *pGraphic;
435 : }
436 :
437 13 : const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
438 : {
439 13 : if(!mpReplacementGraphic && pGraphic)
440 : {
441 13 : const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
442 :
443 13 : if(rSvgDataPtr.get())
444 : {
445 0 : const_cast< SdrGrafObj* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement());
446 : }
447 : }
448 :
449 13 : return mpReplacementGraphic;
450 : }
451 :
452 440 : void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
453 : {
454 440 : pGraphic->SetGraphic( rGrf );
455 440 : delete mpReplacementGraphic;
456 440 : mpReplacementGraphic = 0;
457 440 : pGraphic->SetUserData();
458 440 : mbIsPreview = false;
459 440 : onGraphicChanged();
460 440 : }
461 :
462 427 : void SdrGrafObj::SetGraphic( const Graphic& rGrf )
463 : {
464 427 : NbcSetGraphic(rGrf);
465 427 : SetChanged();
466 427 : BroadcastObjectChange();
467 427 : }
468 :
469 117 : const Graphic& SdrGrafObj::GetGraphic() const
470 : {
471 117 : ForceSwapIn();
472 117 : return pGraphic->GetGraphic();
473 : }
474 :
475 0 : Graphic SdrGrafObj::GetTransformedGraphic( SdrGrafObjTransformsAttrs nTransformFlags ) const
476 : {
477 : // Refactored most of the code to GraphicObject, where
478 : // everybody can use e.g. the cropping functionality
479 :
480 0 : GraphicType eType = GetGraphicType();
481 0 : MapMode aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() );
482 0 : const Size aDestSize( GetLogicRect().GetSize() );
483 0 : const bool bMirror = bool( nTransformFlags & SdrGrafObjTransformsAttrs::MIRROR );
484 0 : const bool bRotate = bool( nTransformFlags & SdrGrafObjTransformsAttrs::ROTATE ) &&
485 0 : ( aGeo.nRotationAngle && aGeo.nRotationAngle != 18000 ) && ( GRAPHIC_NONE != eType );
486 :
487 : // Need cropping info earlier
488 0 : const_cast<SdrGrafObj*>(this)->ImpSetAttrToGrafInfo();
489 0 : GraphicAttr aActAttr;
490 :
491 0 : if( SdrGrafObjTransformsAttrs::NONE != nTransformFlags &&
492 : GRAPHIC_NONE != eType )
493 : {
494 : // Actually transform the graphic only in this case.
495 : // Cropping always happens, though.
496 0 : aActAttr = aGrafInfo;
497 :
498 0 : if( bMirror )
499 : {
500 0 : sal_uInt16 nMirrorCase = ( aGeo.nRotationAngle == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
501 0 : bool bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
502 0 : bool bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
503 :
504 0 : aActAttr.SetMirrorFlags( ( bHMirr ? BmpMirrorFlags::Horizontal : BmpMirrorFlags::NONE ) | ( bVMirr ? BmpMirrorFlags::Vertical : BmpMirrorFlags::NONE ) );
505 : }
506 :
507 0 : if( bRotate )
508 0 : aActAttr.SetRotation( sal_uInt16(aGeo.nRotationAngle / 10) );
509 : }
510 :
511 : // Delegate to moved code in GraphicObject
512 0 : return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
513 : }
514 :
515 1 : GraphicType SdrGrafObj::GetGraphicType() const
516 : {
517 1 : return pGraphic->GetType();
518 : }
519 :
520 0 : bool SdrGrafObj::IsAnimated() const
521 : {
522 0 : return pGraphic->IsAnimated();
523 : }
524 :
525 0 : bool SdrGrafObj::IsEPS() const
526 : {
527 0 : return pGraphic->IsEPS();
528 : }
529 :
530 400 : bool SdrGrafObj::IsSwappedOut() const
531 : {
532 400 : return mbIsPreview || pGraphic->IsSwappedOut();
533 : }
534 :
535 0 : const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
536 : {
537 0 : return pGraphic->GetPrefMapMode();
538 : }
539 :
540 0 : const Size& SdrGrafObj::GetGrafPrefSize() const
541 : {
542 0 : return pGraphic->GetPrefSize();
543 : }
544 :
545 98 : void SdrGrafObj::SetGrafStreamURL( const OUString& rGraphicStreamURL )
546 : {
547 98 : mbIsPreview = false;
548 98 : if( rGraphicStreamURL.isEmpty() )
549 : {
550 26 : pGraphic->SetUserData();
551 : }
552 72 : else if( pModel->IsSwapGraphics() )
553 : {
554 72 : pGraphic->SetUserData( rGraphicStreamURL );
555 : }
556 98 : }
557 :
558 15 : OUString SdrGrafObj::GetGrafStreamURL() const
559 : {
560 15 : return pGraphic->GetUserData();
561 : }
562 :
563 691 : void SdrGrafObj::ForceSwapIn() const
564 : {
565 691 : if( mbIsPreview && pGraphic->HasUserData() )
566 : {
567 : // removing preview graphic
568 0 : const OUString aUserData( pGraphic->GetUserData() );
569 :
570 0 : Graphic aEmpty;
571 0 : pGraphic->SetGraphic( aEmpty );
572 0 : pGraphic->SetUserData( aUserData );
573 :
574 0 : const_cast< SdrGrafObj* >( this )->mbIsPreview = false;
575 : }
576 691 : if ( pGraphicLink && pGraphic->IsSwappedOut() )
577 9 : ImpUpdateGraphicLink( false );
578 : else
579 682 : pGraphic->FireSwapInRequest();
580 :
581 2073 : if( pGraphic->IsSwappedOut() ||
582 1365 : ( pGraphic->GetType() == GRAPHIC_NONE ) ||
583 674 : ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
584 : {
585 17 : Graphic aDefaultGraphic;
586 17 : aDefaultGraphic.SetDefaultType();
587 17 : pGraphic->SetGraphic( aDefaultGraphic );
588 : }
589 691 : }
590 :
591 17 : void SdrGrafObj::ImpLinkAnmeldung()
592 : {
593 17 : sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
594 :
595 17 : if( pLinkManager != NULL && pGraphicLink == NULL )
596 : {
597 15 : if (!aFileName.isEmpty())
598 : {
599 15 : pGraphicLink = new SdrGraphicLink( *this );
600 : pLinkManager->InsertFileLink(
601 15 : *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, (aFilterName.isEmpty() ? NULL : &aFilterName), NULL);
602 15 : pGraphicLink->Connect();
603 : }
604 : }
605 17 : }
606 :
607 1353 : void SdrGrafObj::ImpLinkAbmeldung()
608 : {
609 1353 : sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
610 :
611 1353 : if( pLinkManager != NULL && pGraphicLink!=NULL)
612 : {
613 : // When using Remove, the *pGraphicLink is implicitly deleted
614 14 : pLinkManager->Remove( pGraphicLink );
615 14 : pGraphicLink=NULL;
616 : }
617 1353 : }
618 :
619 15 : void SdrGrafObj::SetGraphicLink(const OUString& rFileName, const OUString& rReferer, const OUString& rFilterName)
620 : {
621 15 : ImpLinkAbmeldung();
622 15 : aFileName = rFileName;
623 15 : aReferer = rReferer;
624 15 : aFilterName = rFilterName;
625 15 : ImpLinkAnmeldung();
626 15 : pGraphic->SetUserData();
627 15 : pGraphic->SetSwapState();
628 15 : }
629 :
630 512 : void SdrGrafObj::ReleaseGraphicLink()
631 : {
632 512 : ImpLinkAbmeldung();
633 512 : aFileName.clear();
634 512 : aReferer.clear();
635 512 : aFilterName.clear();
636 512 : }
637 :
638 664 : bool SdrGrafObj::IsLinkedGraphic() const
639 : {
640 664 : return !aFileName.isEmpty();
641 : }
642 :
643 :
644 :
645 0 : void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
646 : {
647 0 : bool bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
648 :
649 0 : rInfo.bResizeFreeAllowed = aGeo.nRotationAngle % 9000 == 0 ||
650 0 : aGeo.nRotationAngle % 18000 == 0 ||
651 0 : aGeo.nRotationAngle % 27000 == 0;
652 :
653 0 : rInfo.bResizePropAllowed = true;
654 0 : rInfo.bRotateFreeAllowed = bNoPresGrf;
655 0 : rInfo.bRotate90Allowed = bNoPresGrf;
656 0 : rInfo.bMirrorFreeAllowed = bNoPresGrf;
657 0 : rInfo.bMirror45Allowed = bNoPresGrf;
658 0 : rInfo.bMirror90Allowed = !bEmptyPresObj;
659 0 : rInfo.bTransparenceAllowed = false;
660 0 : rInfo.bGradientAllowed = false;
661 :
662 : // #i118485# Shear allowed and possible now
663 0 : rInfo.bShearAllowed = true;
664 :
665 0 : rInfo.bEdgeRadiusAllowed=false;
666 0 : rInfo.bCanConvToPath = !IsEPS();
667 0 : rInfo.bCanConvToPathLineToArea = false;
668 0 : rInfo.bCanConvToPolyLineToArea = false;
669 0 : rInfo.bCanConvToPoly = !IsEPS();
670 0 : rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
671 0 : }
672 :
673 9515 : sal_uInt16 SdrGrafObj::GetObjIdentifier() const
674 : {
675 9515 : return sal_uInt16( OBJ_GRAF );
676 : }
677 :
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
680 : */
681 13 : bool SdrGrafObj::ImpUpdateGraphicLink( bool bAsynchron ) const
682 : {
683 13 : bool bRet = false;
684 13 : if( pGraphicLink )
685 : {
686 13 : if ( bAsynchron )
687 0 : pGraphicLink->UpdateAsynchron();
688 : else
689 13 : pGraphicLink->DataChanged( ImpLoadLinkedGraphic( aFileName, aReferer, aFilterName ) );
690 13 : bRet = true;
691 : }
692 13 : return bRet;
693 : }
694 :
695 13 : void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
696 : {
697 13 : const bool bIsChanged = GetModel()->IsChanged();
698 13 : NbcSetGraphic( rGraphic );
699 13 : ActionChanged();
700 13 : BroadcastObjectChange();
701 13 : GetModel()->SetChanged( bIsChanged );
702 13 : }
703 :
704 6 : OUString SdrGrafObj::TakeObjNameSingul() const
705 : {
706 6 : if (!pGraphic)
707 0 : return OUString();
708 :
709 6 : const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
710 :
711 6 : OUStringBuffer sName;
712 :
713 6 : if(rSvgDataPtr.get())
714 : {
715 0 : sName.append(ImpGetResStr(STR_ObjNameSingulGRAFSVG));
716 : }
717 : else
718 : {
719 6 : switch( pGraphic->GetType() )
720 : {
721 : case GRAPHIC_BITMAP:
722 : {
723 0 : const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || static_cast<const SdrGrafTransparenceItem&>( GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
724 0 : ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
725 0 : ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
726 :
727 0 : sName.append(ImpGetResStr(nId));
728 : }
729 0 : break;
730 :
731 : case GRAPHIC_GDIMETAFILE:
732 0 : sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF));
733 0 : break;
734 :
735 : case GRAPHIC_NONE:
736 6 : sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE));
737 6 : break;
738 :
739 : default:
740 0 : sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF));
741 0 : break;
742 : }
743 : }
744 :
745 6 : const OUString aName(GetName());
746 :
747 6 : if (!aName.isEmpty())
748 : {
749 0 : sName.append(" '");
750 0 : sName.append(aName);
751 0 : sName.append('\'' );
752 : }
753 :
754 6 : return sName.makeStringAndClear();
755 : }
756 :
757 0 : OUString SdrGrafObj::TakeObjNamePlural() const
758 : {
759 0 : if(!pGraphic)
760 0 : return OUString();
761 :
762 0 : const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
763 :
764 0 : OUStringBuffer sName;
765 :
766 0 : if(rSvgDataPtr.get())
767 : {
768 0 : sName.append(ImpGetResStr(STR_ObjNamePluralGRAFSVG));
769 : }
770 : else
771 : {
772 0 : switch( pGraphic->GetType() )
773 : {
774 : case GRAPHIC_BITMAP:
775 : {
776 0 : const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || static_cast<const SdrGrafTransparenceItem&>( GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
777 0 : ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
778 0 : ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
779 :
780 0 : sName.append(ImpGetResStr(nId));
781 : }
782 0 : break;
783 :
784 : case GRAPHIC_GDIMETAFILE:
785 0 : sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF));
786 0 : break;
787 :
788 : case GRAPHIC_NONE:
789 0 : sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE));
790 0 : break;
791 :
792 : default:
793 0 : sName.append(ImpGetResStr(IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF));
794 0 : break;
795 : }
796 : }
797 :
798 0 : const OUString aName(GetName());
799 :
800 0 : if (!aName.isEmpty())
801 : {
802 0 : sName.append(" '");
803 0 : sName.append(aName);
804 0 : sName.append('\'');
805 : }
806 :
807 0 : return sName.makeStringAndClear();
808 : }
809 :
810 0 : SdrObject* SdrGrafObj::getFullDragClone() const
811 : {
812 : // call parent
813 0 : SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
814 :
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 0 : if(pRetval && IsLinkedGraphic())
819 : {
820 0 : pRetval->ForceSwapIn();
821 0 : pRetval->ReleaseGraphicLink();
822 : }
823 :
824 0 : return pRetval;
825 : }
826 :
827 45 : SdrGrafObj* SdrGrafObj::Clone() const
828 : {
829 45 : return CloneHelper< SdrGrafObj >();
830 : }
831 :
832 45 : SdrGrafObj& SdrGrafObj::operator=( const SdrGrafObj& rObj )
833 : {
834 45 : if( this == &rObj )
835 0 : return *this;
836 45 : SdrRectObj::operator=( rObj );
837 :
838 45 : pGraphic->SetGraphic( rObj.GetGraphic(), &rObj.GetGraphicObject() );
839 45 : aFileName = rObj.aFileName;
840 45 : aFilterName = rObj.aFilterName;
841 45 : bMirrored = rObj.bMirrored;
842 :
843 45 : if( rObj.IsLinkedGraphic() )
844 : {
845 0 : SetGraphicLink( aFileName, rObj.aReferer, aFilterName );
846 : }
847 :
848 45 : ImpSetAttrToGrafInfo();
849 45 : return *this;
850 : }
851 :
852 3 : basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const
853 : {
854 3 : if(mbInsidePaint)
855 : {
856 0 : basegfx::B2DPolyPolygon aRetval;
857 :
858 : // take grown rectangle
859 0 : const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2);
860 : const Rectangle aGrownRect(
861 0 : maRect.Left() - nHalfLineWidth,
862 0 : maRect.Top() - nHalfLineWidth,
863 0 : maRect.Right() + nHalfLineWidth,
864 0 : maRect.Bottom() + nHalfLineWidth);
865 :
866 0 : XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius()));
867 0 : aRetval.append(aXPoly.getB2DPolygon());
868 :
869 0 : return aRetval;
870 : }
871 : else
872 : {
873 : // call parent
874 3 : return SdrRectObj::TakeXorPoly();
875 : }
876 : }
877 :
878 0 : sal_uInt32 SdrGrafObj::GetHdlCount() const
879 : {
880 0 : return 8L;
881 : }
882 :
883 0 : SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
884 : {
885 0 : return SdrRectObj::GetHdl( nHdlNum + 1L );
886 : }
887 :
888 35 : void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
889 : {
890 35 : SdrRectObj::NbcResize( rRef, xFact, yFact );
891 :
892 35 : bool bMirrX = xFact.GetNumerator() < 0;
893 35 : bool bMirrY = yFact.GetNumerator() < 0;
894 :
895 35 : if( bMirrX != bMirrY )
896 0 : bMirrored = !bMirrored;
897 35 : }
898 :
899 31 : void SdrGrafObj::NbcRotate(const Point& rRef, long nAngle, double sn, double cs)
900 : {
901 31 : SdrRectObj::NbcRotate(rRef,nAngle,sn,cs);
902 31 : }
903 :
904 0 : void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
905 : {
906 0 : SdrRectObj::NbcMirror(rRef1,rRef2);
907 0 : bMirrored = !bMirrored;
908 0 : }
909 :
910 0 : void SdrGrafObj::NbcShear(const Point& rRef, long nAngle, double tn, bool bVShear)
911 : {
912 : // #i118485# Call Shear now, old version redirected to rotate
913 0 : SdrRectObj::NbcShear(rRef, nAngle, tn, bVShear);
914 0 : }
915 :
916 1045 : void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect)
917 : {
918 1045 : SdrRectObj::NbcSetSnapRect(rRect);
919 1045 : }
920 :
921 1124 : void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect)
922 : {
923 1124 : SdrRectObj::NbcSetLogicRect(rRect);
924 1124 : }
925 :
926 1 : SdrObjGeoData* SdrGrafObj::NewGeoData() const
927 : {
928 1 : return new SdrGrafObjGeoData;
929 : }
930 :
931 1 : void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
932 : {
933 1 : SdrRectObj::SaveGeoData(rGeo);
934 1 : SdrGrafObjGeoData& rGGeo=static_cast<SdrGrafObjGeoData&>(rGeo);
935 1 : rGGeo.bMirrored=bMirrored;
936 1 : }
937 :
938 0 : void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo)
939 : {
940 0 : SdrRectObj::RestGeoData(rGeo);
941 0 : const SdrGrafObjGeoData& rGGeo=static_cast<const SdrGrafObjGeoData&>(rGeo);
942 0 : bMirrored=rGGeo.bMirrored;
943 0 : }
944 :
945 1969 : void SdrGrafObj::SetPage( SdrPage* pNewPage )
946 : {
947 1969 : bool bRemove = pNewPage == NULL && pPage != NULL;
948 1969 : bool bInsert = pNewPage != NULL && pPage == NULL;
949 :
950 1969 : if( bRemove )
951 : {
952 : // No SwapIn necessary here, because if something's not loaded, it can't be animated either.
953 586 : if( pGraphic->IsAnimated())
954 0 : pGraphic->StopAnimation();
955 :
956 586 : if( pGraphicLink != NULL )
957 3 : ImpLinkAbmeldung();
958 : }
959 :
960 1969 : if(!pModel && !GetStyleSheet() && pNewPage && pNewPage->GetModel())
961 : {
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 688 : SfxStyleSheet* pSheet = pNewPage->GetModel()->GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj();
968 :
969 688 : if(pSheet)
970 : {
971 101 : SetStyleSheet(pSheet, false);
972 : }
973 : else
974 : {
975 587 : SetMergedItem(XFillStyleItem(drawing::FillStyle_NONE));
976 587 : SetMergedItem(XLineStyleItem(drawing::LineStyle_NONE));
977 : }
978 : }
979 :
980 1969 : SdrRectObj::SetPage( pNewPage );
981 :
982 1969 : if (!aFileName.isEmpty() && bInsert)
983 2 : ImpLinkAnmeldung();
984 1969 : }
985 :
986 1474 : void SdrGrafObj::SetModel( SdrModel* pNewModel )
987 : {
988 1474 : bool bChg = pNewModel != pModel;
989 :
990 1474 : if( bChg )
991 : {
992 780 : if( pGraphic->HasUserData() )
993 : {
994 0 : ForceSwapIn();
995 : }
996 :
997 780 : if( pGraphicLink != NULL )
998 0 : ImpLinkAbmeldung();
999 : }
1000 :
1001 : // realize model
1002 1474 : SdrRectObj::SetModel(pNewModel);
1003 :
1004 1474 : if (bChg && !aFileName.isEmpty())
1005 0 : ImpLinkAnmeldung();
1006 1474 : }
1007 :
1008 0 : void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/)
1009 : {
1010 0 : SetGrafAnimationAllowed(true);
1011 0 : }
1012 :
1013 0 : bool SdrGrafObj::HasGDIMetaFile() const
1014 : {
1015 0 : return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE );
1016 : }
1017 :
1018 0 : bool SdrGrafObj::isEmbeddedSvg() const
1019 : {
1020 0 : return GRAPHIC_BITMAP == GetGraphicType() && GetGraphic().getSvgData().get();
1021 : }
1022 :
1023 0 : GDIMetaFile SdrGrafObj::getMetafileFromEmbeddedSvg() const
1024 : {
1025 0 : GDIMetaFile aRetval;
1026 :
1027 0 : if(isEmbeddedSvg() && GetModel())
1028 : {
1029 0 : ScopedVclPtrInstance< VirtualDevice > pOut;
1030 0 : const Rectangle aBoundRect(GetCurrentBoundRect());
1031 0 : const MapMode aMap(GetModel()->GetScaleUnit(), Point(), GetModel()->GetScaleFraction(), GetModel()->GetScaleFraction());
1032 :
1033 0 : pOut->EnableOutput(false);
1034 0 : pOut->SetMapMode(aMap);
1035 0 : aRetval.Record(pOut);
1036 0 : SingleObjectPainter(*pOut.get());
1037 0 : aRetval.Stop();
1038 0 : aRetval.WindStart();
1039 0 : aRetval.Move(-aBoundRect.Left(), -aBoundRect.Top());
1040 0 : aRetval.SetPrefMapMode(aMap);
1041 0 : aRetval.SetPrefSize(aBoundRect.GetSize());
1042 : }
1043 :
1044 0 : return aRetval;
1045 : }
1046 :
1047 0 : SdrObject* SdrGrafObj::DoConvertToPolyObj(bool bBezier, bool bAddText ) const
1048 : {
1049 0 : SdrObject* pRetval = NULL;
1050 0 : GraphicType aGraphicType(GetGraphicType());
1051 0 : GDIMetaFile aMtf;
1052 :
1053 0 : if(isEmbeddedSvg())
1054 : {
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 0 : aMtf = getMetafileFromEmbeddedSvg();
1061 0 : aGraphicType = GRAPHIC_GDIMETAFILE;
1062 : }
1063 0 : else if(GRAPHIC_GDIMETAFILE == aGraphicType)
1064 : {
1065 0 : aMtf = GetTransformedGraphic(SdrGrafObjTransformsAttrs::COLOR|SdrGrafObjTransformsAttrs::MIRROR).GetGDIMetaFile();
1066 : }
1067 :
1068 0 : switch(aGraphicType)
1069 : {
1070 : case GRAPHIC_GDIMETAFILE:
1071 : {
1072 : // Sort into group and return ONLY those objects that can be created from the MetaFile.
1073 0 : ImpSdrGDIMetaFileImport aFilter(*GetModel(), GetLayer(), maRect);
1074 0 : SdrObjGroup* pGrp = new SdrObjGroup();
1075 :
1076 0 : if(aFilter.DoImport(aMtf, *pGrp->GetSubList(), 0))
1077 : {
1078 : {
1079 : // copy transformation
1080 0 : GeoStat aGeoStat(GetGeoStat());
1081 :
1082 0 : if(aGeoStat.nShearAngle)
1083 : {
1084 0 : aGeoStat.RecalcTan();
1085 0 : pGrp->NbcShear(maRect.TopLeft(), aGeoStat.nShearAngle, aGeoStat.nTan, false);
1086 : }
1087 :
1088 0 : if(aGeoStat.nRotationAngle)
1089 : {
1090 0 : aGeoStat.RecalcSinCos();
1091 0 : pGrp->NbcRotate(maRect.TopLeft(), aGeoStat.nRotationAngle, aGeoStat.nSin, aGeoStat.nCos);
1092 : }
1093 : }
1094 :
1095 0 : pRetval = pGrp;
1096 0 : pGrp->NbcSetLayer(GetLayer());
1097 0 : pGrp->SetModel(GetModel());
1098 :
1099 0 : if(bAddText)
1100 : {
1101 0 : pRetval = ImpConvertAddText(pRetval, bBezier);
1102 : }
1103 :
1104 : // convert all children
1105 0 : if( pRetval )
1106 : {
1107 0 : SdrObject* pHalfDone = pRetval;
1108 0 : pRetval = pHalfDone->DoConvertToPolyObj(bBezier, bAddText);
1109 0 : SdrObject::Free( pHalfDone ); // resulting object is newly created
1110 :
1111 0 : 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 0 : SdrObjList* pList = pRetval->GetSubList();
1118 0 : if( pList )
1119 0 : pList->FlattenGroups();
1120 : }
1121 : }
1122 : }
1123 : else
1124 : {
1125 0 : delete pGrp;
1126 : }
1127 :
1128 : // #i118485# convert line and fill
1129 0 : SdrObject* pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false);
1130 :
1131 0 : if(pLineFill)
1132 : {
1133 0 : if(pRetval)
1134 : {
1135 0 : pGrp = dynamic_cast< SdrObjGroup* >(pRetval);
1136 :
1137 0 : if(!pGrp)
1138 : {
1139 0 : pGrp = new SdrObjGroup();
1140 :
1141 0 : pGrp->NbcSetLayer(GetLayer());
1142 0 : pGrp->SetModel(GetModel());
1143 0 : pGrp->GetSubList()->NbcInsertObject(pRetval);
1144 : }
1145 :
1146 0 : pGrp->GetSubList()->NbcInsertObject(pLineFill, 0);
1147 : }
1148 : else
1149 : {
1150 0 : pRetval = pLineFill;
1151 : }
1152 : }
1153 :
1154 0 : break;
1155 : }
1156 : case GRAPHIC_BITMAP:
1157 : {
1158 : // create basic object and add fill
1159 0 : pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1160 :
1161 : // save bitmap as an attribute
1162 0 : if(pRetval)
1163 : {
1164 : // retrieve bitmap for the fill
1165 0 : SfxItemSet aSet(GetObjectItemSet());
1166 :
1167 0 : aSet.Put(XFillStyleItem(drawing::FillStyle_BITMAP));
1168 0 : const BitmapEx aBitmapEx(GetTransformedGraphic().GetBitmapEx());
1169 0 : aSet.Put(XFillBitmapItem(OUString(), Graphic(aBitmapEx)));
1170 0 : aSet.Put(XFillBmpTileItem(false));
1171 :
1172 0 : pRetval->SetMergedItemSet(aSet);
1173 : }
1174 0 : break;
1175 : }
1176 : case GRAPHIC_NONE:
1177 : case GRAPHIC_DEFAULT:
1178 : {
1179 0 : pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1180 0 : break;
1181 : }
1182 : }
1183 :
1184 0 : return pRetval;
1185 : }
1186 :
1187 72 : void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1188 : {
1189 72 : SetXPolyDirty();
1190 72 : SdrRectObj::Notify( rBC, rHint );
1191 72 : ImpSetAttrToGrafInfo();
1192 72 : }
1193 :
1194 :
1195 89 : void SdrGrafObj::SetMirrored( bool _bMirrored )
1196 : {
1197 89 : bMirrored = _bMirrored;
1198 89 : }
1199 :
1200 3410 : void SdrGrafObj::ImpSetAttrToGrafInfo()
1201 : {
1202 3410 : const SfxItemSet& rSet = GetObjectItemSet();
1203 3410 : const sal_uInt16 nTrans = static_cast<const SdrGrafTransparenceItem&>( rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue();
1204 3410 : const SdrGrafCropItem& rCrop = static_cast<const SdrGrafCropItem&>( rSet.Get( SDRATTR_GRAFCROP ) );
1205 :
1206 3410 : aGrafInfo.SetLuminance( static_cast<const SdrGrafLuminanceItem&>( rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() );
1207 3410 : aGrafInfo.SetContrast( static_cast<const SdrGrafContrastItem&>( rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() );
1208 3410 : aGrafInfo.SetChannelR( static_cast<const SdrGrafRedItem&>( rSet.Get( SDRATTR_GRAFRED ) ).GetValue() );
1209 3410 : aGrafInfo.SetChannelG( static_cast<const SdrGrafGreenItem&>( rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() );
1210 3410 : aGrafInfo.SetChannelB( static_cast<const SdrGrafBlueItem&>( rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() );
1211 3410 : aGrafInfo.SetGamma( static_cast<const SdrGrafGamma100Item&>( rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 );
1212 3410 : aGrafInfo.SetTransparency( (sal_uInt8) FRound( std::min( nTrans, (sal_uInt16) 100 ) * 2.55 ) );
1213 3410 : aGrafInfo.SetInvert( static_cast<const SdrGrafInvertItem&>( rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() );
1214 3410 : aGrafInfo.SetDrawMode( static_cast<const SdrGrafModeItem&>( rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() );
1215 3410 : aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
1216 :
1217 3410 : SetXPolyDirty();
1218 3410 : SetRectsDirty();
1219 3410 : }
1220 :
1221 52 : void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly )
1222 : {
1223 52 : Size aSize;
1224 52 : Size aMaxSize( rMaxRect.GetSize() );
1225 52 : if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1226 52 : aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM );
1227 : else
1228 0 : aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1229 0 : pGraphic->GetPrefMapMode(),
1230 0 : MapMode( MAP_100TH_MM ) );
1231 :
1232 52 : if( aSize.Height() != 0 && aSize.Width() != 0 )
1233 : {
1234 52 : Point aPos( rMaxRect.TopLeft() );
1235 :
1236 : // if the graphic is too large, fit it to page
1237 104 : if ( (!bShrinkOnly ||
1238 0 : ( aSize.Height() > aMaxSize.Height() ) ||
1239 52 : ( aSize.Width() > aMaxSize.Width() ) )&&
1240 156 : aSize.Height() && aMaxSize.Height() )
1241 : {
1242 104 : float fGrfWH = (float)aSize.Width() /
1243 104 : (float)aSize.Height();
1244 104 : float fWinWH = (float)aMaxSize.Width() /
1245 104 : (float)aMaxSize.Height();
1246 :
1247 : // Scale graphic to page size
1248 52 : if ( fGrfWH < fWinWH )
1249 : {
1250 50 : aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
1251 50 : aSize.Height()= aMaxSize.Height();
1252 : }
1253 2 : else if ( fGrfWH > 0.F )
1254 : {
1255 2 : aSize.Width() = aMaxSize.Width();
1256 2 : aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
1257 : }
1258 :
1259 52 : aPos = rMaxRect.Center();
1260 : }
1261 :
1262 52 : if( bShrinkOnly )
1263 0 : aPos = maRect.TopLeft();
1264 :
1265 52 : aPos.X() -= aSize.Width() / 2;
1266 52 : aPos.Y() -= aSize.Height() / 2;
1267 52 : SetLogicRect( Rectangle( aPos, aSize ) );
1268 : }
1269 52 : }
1270 :
1271 340 : IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
1272 : {
1273 170 : SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1274 :
1275 170 : if( pO->IsInSwapOut() )
1276 : {
1277 112 : if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
1278 : {
1279 : // test if this object is visualized from someone
1280 : // ## test only if there are VOCs other than the preview renderer
1281 112 : if(!GetViewContact().HasViewObjectContacts(true))
1282 : {
1283 111 : const SdrSwapGraphicsMode nSwapMode = pModel->GetSwapGraphicsMode();
1284 :
1285 334 : if( ( pGraphicLink ) &&
1286 114 : ( nSwapMode & SdrSwapGraphicsMode::PURGE ) )
1287 : {
1288 1 : pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1289 : }
1290 110 : else if( nSwapMode & SdrSwapGraphicsMode::TEMP )
1291 : {
1292 110 : pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1293 110 : pGraphic->SetUserData();
1294 : }
1295 :
1296 : // #i102380#
1297 111 : sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
1298 :
1299 111 : if(pVC)
1300 : {
1301 111 : pVC->flushGraphicObjects();
1302 : }
1303 : }
1304 : }
1305 : }
1306 58 : else if( pO->IsInSwapIn() )
1307 : {
1308 : // can be loaded from the original document stream later
1309 58 : if( pModel != NULL )
1310 : {
1311 58 : if( pGraphic->HasUserData() )
1312 : {
1313 55 : ::comphelper::LifecycleProxy proxy;
1314 110 : OUString aUserData = pGraphic->GetUserData();
1315 : uno::Reference<io::XInputStream> const xStream(
1316 110 : pModel->GetDocumentStream(aUserData, proxy));
1317 :
1318 55 : ::boost::scoped_ptr<SvStream> const pStream( (xStream.is())
1319 165 : ? ::utl::UcbStreamHelper::CreateStream(xStream)
1320 165 : : 0 );
1321 :
1322 55 : if( pStream != 0 )
1323 : {
1324 55 : Graphic aGraphic;
1325 :
1326 110 : boost::scoped_ptr<com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > > pFilterData;
1327 :
1328 55 : if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
1329 : {
1330 0 : pFilterData.reset(new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 ));
1331 :
1332 0 : const com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
1333 0 : 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 0 : const bool bCreateNativeLink = true;
1337 0 : (*pFilterData)[ 0 ].Name = "PreviewSizeHint";
1338 0 : (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint;
1339 0 : (*pFilterData)[ 1 ].Name = "AllowPartialStreamRead";
1340 0 : (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead;
1341 0 : (*pFilterData)[ 2 ].Name = "CreateNativeLink";
1342 0 : (*pFilterData)[ 2 ].Value <<= bCreateNativeLink;
1343 :
1344 0 : mbIsPreview = true;
1345 : }
1346 :
1347 110 : if(!GraphicFilter::GetGraphicFilter().ImportGraphic(
1348 55 : aGraphic, aUserData, *pStream,
1349 110 : GRFILTER_FORMAT_DONTKNOW, NULL, GraphicFilterImportFlags::NONE, pFilterData.get()))
1350 : {
1351 55 : const OUString aNewUserData( pGraphic->GetUserData() );
1352 55 : pGraphic->SetGraphic( aGraphic );
1353 55 : if( mbIsPreview )
1354 : {
1355 0 : pGraphic->SetUserData(aNewUserData);
1356 : }
1357 : else
1358 : {
1359 55 : pGraphic->SetUserData();
1360 : }
1361 :
1362 : // Graphic successfully swapped in.
1363 55 : pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1364 : }
1365 55 : pFilterData.reset();
1366 :
1367 110 : pStream->ResetError();
1368 55 : }
1369 : }
1370 3 : else if( !ImpUpdateGraphicLink( false ) )
1371 : {
1372 0 : pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1373 : }
1374 : else
1375 : {
1376 3 : pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1377 : }
1378 : }
1379 : else
1380 0 : pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1381 : }
1382 :
1383 170 : return reinterpret_cast<sal_IntPtr>(pRet);
1384 : }
1385 :
1386 0 : void SdrGrafObj::SetGrafAnimationAllowed(bool bNew)
1387 : {
1388 0 : if(mbGrafAnimationAllowed != bNew)
1389 : {
1390 0 : mbGrafAnimationAllowed = bNew;
1391 0 : ActionChanged();
1392 : }
1393 0 : }
1394 :
1395 0 : Reference< XInputStream > SdrGrafObj::getInputStream()
1396 : {
1397 0 : Reference< XInputStream > xStream;
1398 :
1399 0 : if( pModel )
1400 : {
1401 0 : if( pGraphic && GetGraphic().IsLink() )
1402 : {
1403 0 : Graphic aGraphic( GetGraphic() );
1404 0 : GfxLink aLink( aGraphic.GetLink() );
1405 0 : sal_uInt32 nSize = aLink.GetDataSize();
1406 0 : const void* pSourceData = static_cast<const void*>(aLink.GetData());
1407 0 : if( nSize && pSourceData )
1408 : {
1409 0 : sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
1410 0 : memcpy( pBuffer, pSourceData, nSize );
1411 :
1412 0 : SvMemoryStream* pStream = new SvMemoryStream( static_cast<void*>(pBuffer), (sal_Size)nSize, StreamMode::READ );
1413 0 : pStream->ObjectOwnsMemory( true );
1414 0 : xStream.set( new utl::OInputStreamWrapper( pStream, true ) );
1415 0 : }
1416 : }
1417 :
1418 0 : if (!xStream.is() && !aFileName.isEmpty())
1419 : {
1420 0 : SvFileStream* pStream = new SvFileStream( aFileName, StreamMode::READ );
1421 0 : xStream.set( new utl::OInputStreamWrapper( pStream ) );
1422 : }
1423 : }
1424 :
1425 0 : return xStream;
1426 : }
1427 :
1428 : // moved crop handle creation here; this is the object type using them
1429 0 : void SdrGrafObj::addCropHandles(SdrHdlList& rTarget) const
1430 : {
1431 0 : basegfx::B2DHomMatrix aMatrix;
1432 0 : basegfx::B2DPolyPolygon aPolyPolygon;
1433 :
1434 : // get object transformation
1435 0 : TRGetBaseGeometry(aMatrix, aPolyPolygon);
1436 :
1437 : // part of object transformation correction, but used later, so defined outside next scope
1438 0 : double fShearX(0.0), fRotate(0.0);
1439 :
1440 : { // TTTT correct shear, it comes currently mirrored from TRGetBaseGeometry, can be removed with aw080
1441 0 : basegfx::B2DTuple aScale;
1442 0 : basegfx::B2DTuple aTranslate;
1443 :
1444 0 : aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1445 :
1446 0 : if(!basegfx::fTools::equalZero(fShearX))
1447 : {
1448 : // shearX is used, correct it
1449 0 : fShearX = -fShearX;
1450 : }
1451 :
1452 0 : aMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1453 : aScale,
1454 : fShearX,
1455 : fRotate,
1456 0 : aTranslate);
1457 : }
1458 :
1459 : // get crop values
1460 0 : const SdrGrafCropItem& rCrop = static_cast< const SdrGrafCropItem& >(GetMergedItem(SDRATTR_GRAFCROP));
1461 :
1462 0 : if(rCrop.GetLeft() || rCrop.GetTop() || rCrop.GetRight() ||rCrop.GetBottom())
1463 : {
1464 : // decompose object transformation to have current translate and scale
1465 0 : basegfx::B2DVector aScale, aTranslate;
1466 : double fLclRotate, fLclShearX;
1467 :
1468 0 : aMatrix.decompose(aScale, aTranslate, fLclRotate, fLclShearX);
1469 :
1470 0 : if(!aScale.equalZero())
1471 : {
1472 : // get crop scale
1473 : const basegfx::B2DVector aCropScaleFactor(
1474 0 : GetGraphicObject().calculateCropScaling(
1475 : aScale.getX(),
1476 : aScale.getY(),
1477 0 : rCrop.GetLeft(),
1478 0 : rCrop.GetTop(),
1479 0 : rCrop.GetRight(),
1480 0 : rCrop.GetBottom()));
1481 :
1482 : // apply crop scale
1483 0 : const double fCropLeft(rCrop.GetLeft() * aCropScaleFactor.getX());
1484 0 : const double fCropTop(rCrop.GetTop() * aCropScaleFactor.getY());
1485 0 : const double fCropRight(rCrop.GetRight() * aCropScaleFactor.getX());
1486 0 : const double fCropBottom(rCrop.GetBottom() * aCropScaleFactor.getY());
1487 0 : basegfx::B2DHomMatrix aMatrixForCropViewHdl(aMatrix);
1488 :
1489 0 : if(IsMirrored())
1490 : {
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 0 : basegfx::B2DHomMatrix aPreMultiply;
1500 :
1501 : // mirrored X, apply
1502 0 : aPreMultiply.translate(-0.5, 0.0);
1503 0 : aPreMultiply.scale(-1.0, 1.0);
1504 0 : aPreMultiply.translate(0.5, 0.0);
1505 :
1506 0 : aMatrixForCropViewHdl = aMatrixForCropViewHdl * aPreMultiply;
1507 : }
1508 :
1509 : rTarget.AddHdl(
1510 : new SdrCropViewHdl(
1511 : aMatrixForCropViewHdl,
1512 0 : GetGraphicObject().GetGraphic(),
1513 : fCropLeft,
1514 : fCropTop,
1515 : fCropRight,
1516 0 : fCropBottom));
1517 0 : }
1518 : }
1519 :
1520 0 : basegfx::B2DPoint aPos;
1521 :
1522 0 : aPos = aMatrix * basegfx::B2DPoint(0.0, 0.0);
1523 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPLFT, fShearX, fRotate));
1524 0 : aPos = aMatrix * basegfx::B2DPoint(0.5, 0.0);
1525 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPPER, fShearX, fRotate));
1526 0 : aPos = aMatrix * basegfx::B2DPoint(1.0, 0.0);
1527 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPRGT, fShearX, fRotate));
1528 0 : aPos = aMatrix * basegfx::B2DPoint(0.0, 0.5);
1529 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LEFT , fShearX, fRotate));
1530 0 : aPos = aMatrix * basegfx::B2DPoint(1.0, 0.5);
1531 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_RIGHT, fShearX, fRotate));
1532 0 : aPos = aMatrix * basegfx::B2DPoint(0.0, 1.0);
1533 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWLFT, fShearX, fRotate));
1534 0 : aPos = aMatrix * basegfx::B2DPoint(0.5, 1.0);
1535 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LOWER, fShearX, fRotate));
1536 0 : aPos = aMatrix * basegfx::B2DPoint(1.0, 1.0);
1537 0 : rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWRGT, fShearX, fRotate));
1538 435 : }
1539 :
1540 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|