1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svx/svdomedia.hxx>
23 #include <rtl/ustring.hxx>
24 #include <osl/file.hxx>
26 #include <com/sun/star/document/XStorageBasedDocument.hpp>
27 #include <com/sun/star/embed/XStorage.hpp>
29 #include <ucbhelper/content.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <comphelper/storagehelper.hxx>
33 #include <vcl/svapp.hxx>
35 #include <svx/svdmodel.hxx>
36 #include "svx/svdglob.hxx"
37 #include "svx/svdstr.hrc"
38 #include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx>
39 #include <avmedia/mediawindow.hxx>
43 using namespace ::com::sun::star
;
49 // Note: the temp file is read only, until it is deleted!
50 // It may be shared between multiple documents in case of copy/paste,
51 // hence the shared_ptr.
54 OUString
const m_TempFileURL
;
55 MediaTempFile(OUString
const& rURL
) : m_TempFileURL(rURL
) {}
58 ::osl::File::remove(m_TempFileURL
);
62 struct SdrMediaObj::Impl
64 ::avmedia::MediaItem m_MediaProperties
;
65 ::boost::shared_ptr
< MediaTempFile
> m_pTempFile
;
66 uno::Reference
< graphic::XGraphic
> m_xCachedSnapshot
;
69 TYPEINIT1( SdrMediaObj
, SdrRectObj
);
71 // ------------------------------------------------------------------------------
73 SdrMediaObj::SdrMediaObj()
75 , m_pImpl( new Impl() )
79 // ------------------------------------------------------------------------------
81 SdrMediaObj::SdrMediaObj( const Rectangle
& rRect
)
83 , m_pImpl( new Impl() )
87 // ------------------------------------------------------------------------------
89 SdrMediaObj::~SdrMediaObj()
93 // ------------------------------------------------------------------------------
95 bool SdrMediaObj::HasTextEdit() const
100 // ------------------------------------------------------------------------------
102 sdr::contact::ViewContact
* SdrMediaObj::CreateObjectSpecificViewContact()
104 return new ::sdr::contact::ViewContactOfSdrMediaObj( *this );
107 // ------------------------------------------------------------------------------
109 void SdrMediaObj::TakeObjInfo( SdrObjTransformInfoRec
& rInfo
) const
111 rInfo
.bSelectAllowed
= true;
112 rInfo
.bMoveAllowed
= true;
113 rInfo
.bResizeFreeAllowed
= true;
114 rInfo
.bResizePropAllowed
= true;
115 rInfo
.bRotateFreeAllowed
= false;
116 rInfo
.bRotate90Allowed
= false;
117 rInfo
.bMirrorFreeAllowed
= false;
118 rInfo
.bMirror45Allowed
= false;
119 rInfo
.bMirror90Allowed
= false;
120 rInfo
.bTransparenceAllowed
= false;
121 rInfo
.bGradientAllowed
= false;
122 rInfo
.bShearAllowed
= false;
123 rInfo
.bEdgeRadiusAllowed
= false;
124 rInfo
.bNoOrthoDesired
= false;
125 rInfo
.bNoContortion
= false;
126 rInfo
.bCanConvToPath
= false;
127 rInfo
.bCanConvToPoly
= false;
128 rInfo
.bCanConvToContour
= false;
129 rInfo
.bCanConvToPathLineToArea
= false;
130 rInfo
.bCanConvToPolyLineToArea
= false;
133 // ------------------------------------------------------------------------------
135 sal_uInt16
SdrMediaObj::GetObjIdentifier() const
137 return sal_uInt16( OBJ_MEDIA
);
140 // ------------------------------------------------------------------------------
142 void SdrMediaObj::TakeObjNameSingul(XubString
& rName
) const
144 rName
=ImpGetResStr(STR_ObjNameSingulMEDIA
);
146 String
aName( GetName() );
150 rName
+= sal_Unicode(' ');
151 rName
+= sal_Unicode('\'');
153 rName
+= sal_Unicode('\'');
157 // ------------------------------------------------------------------------------
159 void SdrMediaObj::TakeObjNamePlural(XubString
& rName
) const
161 rName
=ImpGetResStr(STR_ObjNamePluralMEDIA
);
164 // ------------------------------------------------------------------------------
166 SdrMediaObj
* SdrMediaObj::Clone() const
168 return CloneHelper
< SdrMediaObj
>();
171 SdrMediaObj
& SdrMediaObj::operator=(const SdrMediaObj
& rObj
)
175 SdrRectObj::operator=( rObj
);
177 m_pImpl
->m_pTempFile
= rObj
.m_pImpl
->m_pTempFile
; // before props
178 setMediaProperties( rObj
.getMediaProperties() );
179 m_pImpl
->m_xCachedSnapshot
= rObj
.m_pImpl
->m_xCachedSnapshot
;
183 uno::Reference
< graphic::XGraphic
> SdrMediaObj::getSnapshot()
185 if( !m_pImpl
->m_xCachedSnapshot
.is() )
187 OUString aRealURL
= m_pImpl
->m_MediaProperties
.getTempURL();
188 if( aRealURL
.isEmpty() )
189 aRealURL
= m_pImpl
->m_MediaProperties
.getURL();
190 m_pImpl
->m_xCachedSnapshot
= avmedia::MediaWindow::grabFrame( aRealURL
, true );
192 return m_pImpl
->m_xCachedSnapshot
;
195 // ------------------------------------------------------------------------------
197 void SdrMediaObj::AdjustToMaxRect( const Rectangle
& rMaxRect
, bool bShrinkOnly
/* = false */ )
199 Size
aSize( Application::GetDefaultDevice()->PixelToLogic( getPreferredSize(), MAP_100TH_MM
) );
200 Size
aMaxSize( rMaxRect
.GetSize() );
202 if( aSize
.Height() != 0 && aSize
.Width() != 0 )
204 Point
aPos( rMaxRect
.TopLeft() );
206 // if graphic is too large, fit it to the page
207 if ( (!bShrinkOnly
||
208 ( aSize
.Height() > aMaxSize
.Height() ) ||
209 ( aSize
.Width() > aMaxSize
.Width() ) )&&
210 aSize
.Height() && aMaxSize
.Height() )
212 float fGrfWH
= (float)aSize
.Width() /
213 (float)aSize
.Height();
214 float fWinWH
= (float)aMaxSize
.Width() /
215 (float)aMaxSize
.Height();
217 // scale graphic to page size
218 if ( fGrfWH
< fWinWH
)
220 aSize
.Width() = (long)(aMaxSize
.Height() * fGrfWH
);
221 aSize
.Height()= aMaxSize
.Height();
223 else if ( fGrfWH
> 0.F
)
225 aSize
.Width() = aMaxSize
.Width();
226 aSize
.Height()= (long)(aMaxSize
.Width() / fGrfWH
);
229 aPos
= rMaxRect
.Center();
233 aPos
= aRect
.TopLeft();
235 aPos
.X() -= aSize
.Width() / 2;
236 aPos
.Y() -= aSize
.Height() / 2;
237 SetLogicRect( Rectangle( aPos
, aSize
) );
241 // ------------------------------------------------------------------------------
243 void SdrMediaObj::setURL( const OUString
& rURL
)
245 ::avmedia::MediaItem aURLItem
;
247 aURLItem
.setURL( rURL
, 0 );
248 setMediaProperties( aURLItem
);
251 // ------------------------------------------------------------------------------
253 const OUString
& SdrMediaObj::getURL() const
255 return m_pImpl
->m_MediaProperties
.getURL();
258 // ------------------------------------------------------------------------------
260 void SdrMediaObj::setMediaProperties( const ::avmedia::MediaItem
& rState
)
262 mediaPropertiesChanged( rState
);
263 static_cast< ::sdr::contact::ViewContactOfSdrMediaObj
& >( GetViewContact() ).executeMediaItem( getMediaProperties() );
266 // ------------------------------------------------------------------------------
268 const ::avmedia::MediaItem
& SdrMediaObj::getMediaProperties() const
270 return m_pImpl
->m_MediaProperties
;
273 // ------------------------------------------------------------------------------
275 Size
SdrMediaObj::getPreferredSize() const
277 return static_cast< ::sdr::contact::ViewContactOfSdrMediaObj
& >( GetViewContact() ).getPreferredSize();
280 // ------------------------------------------------------------------------------
282 uno::Reference
<io::XInputStream
> SdrMediaObj::GetInputStream()
284 if (!m_pImpl
->m_pTempFile
)
286 SAL_WARN("svx", "this is only intended for embedded media");
289 ucbhelper::Content
tempFile(m_pImpl
->m_pTempFile
->m_TempFileURL
,
290 uno::Reference
<ucb::XCommandEnvironment
>(),
291 comphelper::getProcessComponentContext());
292 return tempFile
.openStream();
295 /// copy a stream from XStorage to temp file
296 static bool lcl_HandlePackageURL(
297 OUString
const & rURL
,
298 SdrModel
*const pModel
,
299 OUString
& o_rTempFileURL
)
303 SAL_WARN("svx", "no model");
306 ::comphelper::LifecycleProxy sourceProxy
;
307 uno::Reference
<io::XInputStream
> xInStream
;
309 xInStream
= pModel
->GetDocumentStream(rURL
, sourceProxy
);
311 catch (container::NoSuchElementException
const&)
313 SAL_INFO("svx", "not found: '" << OUString(rURL
) << "'");
316 catch (uno::Exception
const& e
)
318 SAL_WARN("svx", "exception: '" << e
.Message
<< "'");
323 SAL_WARN("svx", "no stream?");
327 OUString tempFileURL
;
328 ::osl::FileBase::RC
const err
=
329 ::osl::FileBase::createTempFile(0, 0, & tempFileURL
);
330 if (::osl::FileBase::E_None
!= err
)
332 SAL_INFO("svx", "cannot create temp file");
338 ::ucbhelper::Content
tempContent(tempFileURL
,
339 uno::Reference
<ucb::XCommandEnvironment
>(),
340 comphelper::getProcessComponentContext());
341 tempContent
.writeStream(xInStream
, true); // copy stream to file
343 catch (uno::Exception
const& e
)
345 SAL_WARN("svx", "exception: '" << e
.Message
<< "'");
348 o_rTempFileURL
= tempFileURL
;
352 static char const s_PkgScheme
[] = "vnd.sun.star.Package:";
354 void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem
& rNewProperties
)
356 bool bBroadcastChanged
= false;
357 const sal_uInt32 nMaskSet
= rNewProperties
.getMaskSet();
359 // use only a subset of MediaItem properties for own own properties
360 if( ( AVMEDIA_SETMASK_URL
& nMaskSet
) &&
361 ( rNewProperties
.getURL() != getURL() ))
363 m_pImpl
->m_xCachedSnapshot
.clear();
364 OUString
const url(rNewProperties
.getURL());
365 if ((0 == rtl_ustr_ascii_shortenedCompareIgnoreAsciiCase_WithLength(
366 url
.getStr(), url
.getLength(),
367 s_PkgScheme
, SAL_N_ELEMENTS(s_PkgScheme
) - 1)))
369 if ( !m_pImpl
->m_pTempFile
370 || (m_pImpl
->m_pTempFile
->m_TempFileURL
!=
371 rNewProperties
.getTempURL()))
373 OUString tempFileURL
;
374 bool const bSuccess
= lcl_HandlePackageURL(
375 url
, GetModel(), tempFileURL
);
378 m_pImpl
->m_pTempFile
.reset(new MediaTempFile(tempFileURL
));
379 m_pImpl
->m_MediaProperties
.setURL(url
, & tempFileURL
);
381 else // this case is for Clone via operator=
383 m_pImpl
->m_pTempFile
.reset();
384 m_pImpl
->m_MediaProperties
.setURL(OUString(), 0);
389 m_pImpl
->m_MediaProperties
.setURL(url
,
390 &rNewProperties
.getTempURL());
395 m_pImpl
->m_pTempFile
.reset();
396 m_pImpl
->m_MediaProperties
.setURL(url
, 0);
398 bBroadcastChanged
= true;
401 if( AVMEDIA_SETMASK_LOOP
& nMaskSet
)
402 m_pImpl
->m_MediaProperties
.setLoop( rNewProperties
.isLoop() );
404 if( AVMEDIA_SETMASK_MUTE
& nMaskSet
)
405 m_pImpl
->m_MediaProperties
.setMute( rNewProperties
.isMute() );
407 if( AVMEDIA_SETMASK_VOLUMEDB
& nMaskSet
)
408 m_pImpl
->m_MediaProperties
.setVolumeDB( rNewProperties
.getVolumeDB() );
410 if( AVMEDIA_SETMASK_ZOOM
& nMaskSet
)
411 m_pImpl
->m_MediaProperties
.setZoom( rNewProperties
.getZoom() );
413 if( bBroadcastChanged
)
416 BroadcastObjectChange();
420 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */