bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / svdraw / svdomedia.cxx
blob085e805ec2ab2be1f10c06386a8f34eb171cb87c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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;
45 // ---------------
46 // - SdrMediaObj -
47 // ---------------
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.
52 struct MediaTempFile
54 OUString const m_TempFileURL;
55 MediaTempFile(OUString const& rURL) : m_TempFileURL(rURL) {}
56 ~MediaTempFile()
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()
74 : SdrRectObj()
75 , m_pImpl( new Impl() )
79 // ------------------------------------------------------------------------------
81 SdrMediaObj::SdrMediaObj( const Rectangle& rRect )
82 : SdrRectObj( rRect )
83 , m_pImpl( new Impl() )
87 // ------------------------------------------------------------------------------
89 SdrMediaObj::~SdrMediaObj()
93 // ------------------------------------------------------------------------------
95 bool SdrMediaObj::HasTextEdit() const
97 return false;
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() );
148 if(aName.Len())
150 rName += sal_Unicode(' ');
151 rName += sal_Unicode('\'');
152 rName += aName;
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)
173 if( this == &rObj )
174 return *this;
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;
180 return *this;
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();
232 if( bShrinkOnly )
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");
287 return 0;
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)
301 if (!pModel)
303 SAL_WARN("svx", "no model");
304 return false;
306 ::comphelper::LifecycleProxy sourceProxy;
307 uno::Reference<io::XInputStream> xInStream;
308 try {
309 xInStream = pModel->GetDocumentStream(rURL, sourceProxy);
311 catch (container::NoSuchElementException const&)
313 SAL_INFO("svx", "not found: '" << OUString(rURL) << "'");
314 return false;
316 catch (uno::Exception const& e)
318 SAL_WARN("svx", "exception: '" << e.Message << "'");
319 return false;
321 if (!xInStream.is())
323 SAL_WARN("svx", "no stream?");
324 return false;
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");
333 return false;
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 << "'");
346 return false;
348 o_rTempFileURL = tempFileURL;
349 return true;
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);
376 if (bSuccess)
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);
387 else
389 m_pImpl->m_MediaProperties.setURL(url,
390 &rNewProperties.getTempURL());
393 else
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 )
415 SetChanged();
416 BroadcastObjectChange();
420 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */