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