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