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