LCOV - code coverage report
Current view: top level - svx/source/svdraw - svdomedia.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 101 206 49.0 %
Date: 2014-04-11 Functions: 19 32 59.4 %
Legend: Lines: hit not hit

          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 <svx/svdomedia.hxx>
      21             : 
      22             : #include <rtl/ustring.hxx>
      23             : #include <osl/file.hxx>
      24             : 
      25             : #include <com/sun/star/document/XStorageBasedDocument.hpp>
      26             : #include <com/sun/star/embed/XStorage.hpp>
      27             : 
      28             : #include <ucbhelper/content.hxx>
      29             : #include <comphelper/processfactory.hxx>
      30             : #include <comphelper/storagehelper.hxx>
      31             : 
      32             : #include <vcl/svapp.hxx>
      33             : 
      34             : #include <svx/svdmodel.hxx>
      35             : #include "svx/svdglob.hxx"
      36             : #include "svx/svdstr.hrc"
      37             : #include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx>
      38             : #include <avmedia/mediawindow.hxx>
      39             : 
      40             : // For handling of glTF models
      41             : #include <unotools/tempfile.hxx>
      42             : #include <tools/urlobj.hxx>
      43             : 
      44             : using namespace ::com::sun::star;
      45             : 
      46             : 
      47             : // - SdrMediaObj -
      48             : 
      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
      53             : {
      54             :     OUString const m_TempFileURL;
      55           4 :     MediaTempFile(OUString const& rURL) : m_TempFileURL(rURL) {}
      56           2 :     ~MediaTempFile()
      57           2 :     {
      58           2 :         ::osl::File::remove(m_TempFileURL);
      59           2 :     }
      60             : };
      61             : 
      62           8 : struct SdrMediaObj::Impl
      63             : {
      64             :     ::avmedia::MediaItem                  m_MediaProperties;
      65             :     ::boost::shared_ptr< MediaTempFile >  m_pTempFile;
      66             :     uno::Reference< graphic::XGraphic >   m_xCachedSnapshot;
      67             : };
      68             : 
      69         221 : TYPEINIT1( SdrMediaObj, SdrRectObj );
      70             : 
      71             : 
      72             : 
      73           5 : SdrMediaObj::SdrMediaObj()
      74             :     : SdrRectObj()
      75           5 :     , m_pImpl( new Impl() )
      76             : {
      77           5 : }
      78             : 
      79           0 : SdrMediaObj::SdrMediaObj( const Rectangle& rRect )
      80             :     : SdrRectObj( rRect )
      81           0 :     , m_pImpl( new Impl() )
      82             : {
      83           0 : }
      84             : 
      85           6 : SdrMediaObj::~SdrMediaObj()
      86             : {
      87           6 : }
      88             : 
      89           0 : bool SdrMediaObj::HasTextEdit() const
      90             : {
      91           0 :     return false;
      92             : }
      93             : 
      94           5 : sdr::contact::ViewContact* SdrMediaObj::CreateObjectSpecificViewContact()
      95             : {
      96           5 :     return new ::sdr::contact::ViewContactOfSdrMediaObj( *this );
      97             : }
      98             : 
      99           0 : void SdrMediaObj::TakeObjInfo( SdrObjTransformInfoRec& rInfo ) const
     100             : {
     101           0 :     rInfo.bSelectAllowed = true;
     102           0 :     rInfo.bMoveAllowed = true;
     103           0 :     rInfo.bResizeFreeAllowed = true;
     104           0 :     rInfo.bResizePropAllowed = true;
     105           0 :     rInfo.bRotateFreeAllowed = false;
     106           0 :     rInfo.bRotate90Allowed = false;
     107           0 :     rInfo.bMirrorFreeAllowed = false;
     108           0 :     rInfo.bMirror45Allowed = false;
     109           0 :     rInfo.bMirror90Allowed = false;
     110           0 :     rInfo.bTransparenceAllowed = false;
     111           0 :     rInfo.bGradientAllowed = false;
     112           0 :     rInfo.bShearAllowed = false;
     113           0 :     rInfo.bEdgeRadiusAllowed = false;
     114           0 :     rInfo.bNoOrthoDesired = false;
     115           0 :     rInfo.bNoContortion = false;
     116           0 :     rInfo.bCanConvToPath = false;
     117           0 :     rInfo.bCanConvToPoly = false;
     118           0 :     rInfo.bCanConvToContour = false;
     119           0 :     rInfo.bCanConvToPathLineToArea = false;
     120           0 :     rInfo.bCanConvToPolyLineToArea = false;
     121           0 : }
     122             : 
     123          63 : sal_uInt16 SdrMediaObj::GetObjIdentifier() const
     124             : {
     125          63 :     return sal_uInt16( OBJ_MEDIA );
     126             : }
     127             : 
     128           0 : OUString SdrMediaObj::TakeObjNameSingul() const
     129             : {
     130           0 :     OUStringBuffer sName(ImpGetResStr(STR_ObjNameSingulMEDIA));
     131             : 
     132           0 :     OUString aName(GetName());
     133             : 
     134           0 :     if (!aName.isEmpty())
     135             :     {
     136           0 :         sName.append(' ');
     137           0 :         sName.append('\'');
     138           0 :         sName.append(aName);
     139           0 :         sName.append('\'');
     140             :     }
     141             : 
     142           0 :     return sName.makeStringAndClear();
     143             : }
     144             : 
     145           0 : OUString SdrMediaObj::TakeObjNamePlural() const
     146             : {
     147           0 :     return ImpGetResStr(STR_ObjNamePluralMEDIA);
     148             : }
     149             : 
     150           0 : SdrMediaObj* SdrMediaObj::Clone() const
     151             : {
     152           0 :     return CloneHelper< SdrMediaObj >();
     153             : }
     154             : 
     155           0 : SdrMediaObj& SdrMediaObj::operator=(const SdrMediaObj& rObj)
     156             : {
     157           0 :     if( this == &rObj )
     158           0 :         return *this;
     159           0 :     SdrRectObj::operator=( rObj );
     160             : 
     161           0 :     m_pImpl->m_pTempFile = rObj.m_pImpl->m_pTempFile; // before props
     162           0 :     setMediaProperties( rObj.getMediaProperties() );
     163           0 :     m_pImpl->m_xCachedSnapshot = rObj.m_pImpl->m_xCachedSnapshot;
     164           0 :     return *this;
     165             : }
     166             : 
     167           0 : uno::Reference< graphic::XGraphic > SdrMediaObj::getSnapshot()
     168             : {
     169           0 :     if( !m_pImpl->m_xCachedSnapshot.is() )
     170             :     {
     171           0 :         OUString aRealURL = m_pImpl->m_MediaProperties.getTempURL();
     172           0 :         if( aRealURL.isEmpty() )
     173           0 :             aRealURL = m_pImpl->m_MediaProperties.getURL();
     174           0 :         m_pImpl->m_xCachedSnapshot = avmedia::MediaWindow::grabFrame( aRealURL, m_pImpl->m_MediaProperties.getReferer(), true );
     175             :     }
     176           0 :     return m_pImpl->m_xCachedSnapshot;
     177             : }
     178             : 
     179           0 : void SdrMediaObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly /* = false */ )
     180             : {
     181           0 :     Size aSize( Application::GetDefaultDevice()->PixelToLogic( getPreferredSize(), MAP_100TH_MM ) );
     182           0 :     Size aMaxSize( rMaxRect.GetSize() );
     183             : 
     184           0 :     if( aSize.Height() != 0 && aSize.Width() != 0 )
     185             :     {
     186           0 :         Point aPos( rMaxRect.TopLeft() );
     187             : 
     188             :         // if graphic is too large, fit it to the page
     189           0 :         if ( (!bShrinkOnly                          ||
     190           0 :              ( aSize.Height() > aMaxSize.Height() ) ||
     191           0 :              ( aSize.Width()  > aMaxSize.Width()  ) )&&
     192           0 :              aSize.Height() && aMaxSize.Height() )
     193             :         {
     194           0 :             float fGrfWH =  (float)aSize.Width() /
     195           0 :                             (float)aSize.Height();
     196           0 :             float fWinWH =  (float)aMaxSize.Width() /
     197           0 :                             (float)aMaxSize.Height();
     198             : 
     199             :             // scale graphic to page size
     200           0 :             if ( fGrfWH < fWinWH )
     201             :             {
     202           0 :                 aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
     203           0 :                 aSize.Height()= aMaxSize.Height();
     204             :             }
     205           0 :             else if ( fGrfWH > 0.F )
     206             :             {
     207           0 :                 aSize.Width() = aMaxSize.Width();
     208           0 :                 aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
     209             :             }
     210             : 
     211           0 :             aPos = rMaxRect.Center();
     212             :         }
     213             : 
     214           0 :         if( bShrinkOnly )
     215           0 :             aPos = aRect.TopLeft();
     216             : 
     217           0 :         aPos.X() -= aSize.Width() / 2;
     218           0 :         aPos.Y() -= aSize.Height() / 2;
     219           0 :         SetLogicRect( Rectangle( aPos, aSize ) );
     220             :     }
     221           0 : }
     222             : 
     223           0 : void SdrMediaObj::setURL( const OUString& rURL, const OUString& rReferer, const OUString& rMimeType )
     224             : {
     225           0 :     ::avmedia::MediaItem aURLItem;
     226           0 :     if( !rMimeType.isEmpty() )
     227           0 :         m_pImpl->m_MediaProperties.setMimeType(rMimeType);
     228           0 :     aURLItem.setURL( rURL, "", rReferer );
     229           0 :     setMediaProperties( aURLItem );
     230           0 : }
     231             : 
     232           5 : const OUString& SdrMediaObj::getURL() const
     233             : {
     234           5 :     return m_pImpl->m_MediaProperties.getURL();
     235             : }
     236             : 
     237          44 : void SdrMediaObj::setMediaProperties( const ::avmedia::MediaItem& rState )
     238             : {
     239          44 :     mediaPropertiesChanged( rState );
     240          44 :     static_cast< ::sdr::contact::ViewContactOfSdrMediaObj& >( GetViewContact() ).executeMediaItem( getMediaProperties() );
     241          44 : }
     242             : 
     243          62 : const ::avmedia::MediaItem& SdrMediaObj::getMediaProperties() const
     244             : {
     245          62 :     return m_pImpl->m_MediaProperties;
     246             : }
     247             : 
     248           0 : Size SdrMediaObj::getPreferredSize() const
     249             : {
     250           0 :     return static_cast< ::sdr::contact::ViewContactOfSdrMediaObj& >( GetViewContact() ).getPreferredSize();
     251             : }
     252             : 
     253           2 : uno::Reference<io::XInputStream> SdrMediaObj::GetInputStream()
     254             : {
     255           2 :     if (!m_pImpl->m_pTempFile)
     256             :     {
     257             :         SAL_WARN("svx", "this is only intended for embedded media");
     258           0 :         return 0;
     259             :     }
     260           2 :     ucbhelper::Content tempFile(m_pImpl->m_pTempFile->m_TempFileURL,
     261             :                 uno::Reference<ucb::XCommandEnvironment>(),
     262           4 :                 comphelper::getProcessComponentContext());
     263           2 :     return tempFile.openStream();
     264             : }
     265             : 
     266           2 : static bool lcl_HandleJsonPackageURL(
     267             :     const OUString& rURL,
     268             :     SdrModel* const pModel,
     269             :     OUString& o_rTempFileURL)
     270             : {
     271             :     // Create a temporary folder which will contain all files of glTF model
     272           2 :     const OUString sTempFolder = ::utl::TempFile( NULL, true ).GetURL();
     273             : 
     274           2 :     const sal_uInt16 nPackageLength = OString("vnd.sun.star.Package:").getLength();
     275           4 :     const OUString sUrlPath = rURL.copy(nPackageLength,rURL.lastIndexOf("/")-nPackageLength);
     276             :     try
     277             :     {
     278             :         // Base storage:
     279             :         uno::Reference<document::XStorageBasedDocument> const xSBD(
     280           2 :             pModel->getUnoModel(), uno::UNO_QUERY_THROW);
     281             :         const uno::Reference<embed::XStorage> xStorage(
     282           4 :             xSBD->getDocumentStorage(), uno::UNO_QUERY_THROW);
     283             : 
     284             :         // Model source
     285           4 :         ::comphelper::LifecycleProxy proxy;
     286             :         const uno::Reference<embed::XStorage> xModelStorage(
     287             :             ::comphelper::OStorageHelper::GetStorageAtPath(xStorage, sUrlPath,
     288           4 :                 embed::ElementModes::READ, proxy));
     289             : 
     290             :         // Copy all files of glTF model from storage to the temp folder
     291           4 :         uno::Reference< container::XNameAccess > xNameAccess( xModelStorage, uno::UNO_QUERY );
     292           4 :         const uno::Sequence< OUString > aFilenames = xNameAccess->getElementNames();
     293          12 :         for( sal_Int32 nFileIndex = 0; nFileIndex < aFilenames.getLength(); ++nFileIndex )
     294             :         {
     295             :             // Generate temp file path
     296          10 :             const OUString& rFilename = aFilenames[nFileIndex];
     297          10 :             INetURLObject aUrlObj(sTempFolder);
     298          10 :             aUrlObj.insertName(rFilename);
     299          20 :             const OUString sFilepath = aUrlObj.GetMainURL( INetURLObject::NO_DECODE );
     300             : 
     301             :             // Media URL will point at json file
     302          10 :             if( rFilename.endsWith(".json") )
     303           2 :                 o_rTempFileURL = sFilepath;
     304             : 
     305             :             // Create temp file and fill it from storage
     306             :             ::ucbhelper::Content aTargetContent(sFilepath,
     307          20 :                 uno::Reference<ucb::XCommandEnvironment>(), comphelper::getProcessComponentContext());
     308             : 
     309             :             uno::Reference<io::XStream> const xStream(
     310          20 :                 xModelStorage->openStreamElement(rFilename,embed::ElementModes::READ), uno::UNO_SET_THROW);
     311             :             uno::Reference<io::XInputStream> const xInputStream(
     312          20 :                 xStream->getInputStream(), uno::UNO_SET_THROW);
     313             : 
     314          10 :             aTargetContent.writeStream(xInputStream,true);
     315          12 :         }
     316             : 
     317             :     }
     318           0 :     catch (uno::Exception const& e)
     319             :     {
     320             :         SAL_INFO("svx", "exception while copying glTF related files to temp directory '" << e.Message << "'");
     321             :     }
     322           4 :     return true;
     323             : }
     324             : 
     325             : /// copy a stream from XStorage to temp file
     326           3 : static bool lcl_HandlePackageURL(
     327             :         OUString const & rURL,
     328             :         SdrModel *const pModel,
     329             :         OUString & o_rTempFileURL)
     330             : {
     331           3 :     if (!pModel)
     332             :     {
     333             :         SAL_WARN("svx", "no model");
     334           0 :         return false;
     335             :     }
     336           3 :     ::comphelper::LifecycleProxy sourceProxy;
     337           6 :     uno::Reference<io::XInputStream> xInStream;
     338             :     try {
     339           3 :         xInStream = pModel->GetDocumentStream(rURL, sourceProxy);
     340             :     }
     341           0 :     catch (container::NoSuchElementException const&)
     342             :     {
     343             :         SAL_INFO("svx", "not found: '" << OUString(rURL) << "'");
     344           0 :         return false;
     345             :     }
     346           0 :     catch (uno::Exception const& e)
     347             :     {
     348             :         SAL_WARN("svx", "exception: '" << e.Message << "'");
     349           0 :         return false;
     350             :     }
     351           3 :     if (!xInStream.is())
     352             :     {
     353             :         SAL_WARN("svx", "no stream?");
     354           1 :         return false;
     355             :     }
     356             : 
     357           4 :     OUString tempFileURL;
     358             :     ::osl::FileBase::RC const err =
     359           2 :         ::osl::FileBase::createTempFile(0, 0, & tempFileURL);
     360           2 :     if (::osl::FileBase::E_None != err)
     361             :     {
     362             :         SAL_INFO("svx", "cannot create temp file");
     363           0 :         return false;
     364             :     }
     365             : 
     366             :     try
     367             :     {
     368             :         ::ucbhelper::Content tempContent(tempFileURL,
     369             :                 uno::Reference<ucb::XCommandEnvironment>(),
     370           2 :                 comphelper::getProcessComponentContext());
     371           2 :         tempContent.writeStream(xInStream, true); // copy stream to file
     372             :     }
     373           0 :     catch (uno::Exception const& e)
     374             :     {
     375             :         SAL_WARN("svx", "exception: '" << e.Message << "'");
     376           0 :         return false;
     377             :     }
     378           2 :     o_rTempFileURL = tempFileURL;
     379           5 :     return true;
     380             : }
     381             : 
     382          44 : void SdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewProperties )
     383             : {
     384          44 :     bool bBroadcastChanged = false;
     385          44 :     const sal_uInt32 nMaskSet = rNewProperties.getMaskSet();
     386             : 
     387             :     // use only a subset of MediaItem properties for own own properties
     388          44 :     if( AVMEDIA_SETMASK_MIME_TYPE & nMaskSet )
     389           5 :         m_pImpl->m_MediaProperties.setMimeType( rNewProperties.getMimeType() );
     390             : 
     391          49 :     if( ( AVMEDIA_SETMASK_URL & nMaskSet ) &&
     392           5 :         ( rNewProperties.getURL() != getURL() ))
     393             :     {
     394           5 :         m_pImpl->m_xCachedSnapshot.clear();
     395           5 :         OUString const url(rNewProperties.getURL());
     396           5 :         if (url.startsWithIgnoreAsciiCase("vnd.sun.star.Package:"))
     397             :         {
     398          10 :             if (   !m_pImpl->m_pTempFile
     399           5 :                 || (m_pImpl->m_pTempFile->m_TempFileURL !=
     400           0 :                                 rNewProperties.getTempURL()))
     401             :             {
     402           5 :                 OUString tempFileURL;
     403             :                 bool bSuccess;
     404           5 :                 if( url.endsWith(".json") )
     405           2 :                     bSuccess = lcl_HandleJsonPackageURL(url, GetModel(), tempFileURL);
     406             :                 else
     407           3 :                     bSuccess = lcl_HandlePackageURL( url, GetModel(), tempFileURL);
     408           5 :                 if (bSuccess)
     409             :                 {
     410           4 :                     m_pImpl->m_pTempFile.reset(new MediaTempFile(tempFileURL));
     411           4 :                     m_pImpl->m_MediaProperties.setURL(url, tempFileURL, "");
     412             :                 }
     413             :                 else // this case is for Clone via operator=
     414             :                 {
     415           1 :                     m_pImpl->m_pTempFile.reset();
     416           1 :                     m_pImpl->m_MediaProperties.setURL("", "", "");
     417           5 :                 }
     418             :             }
     419             :             else
     420             :             {
     421           0 :                 m_pImpl->m_MediaProperties.setURL(url,
     422           0 :                         rNewProperties.getTempURL(), "");
     423             :             }
     424             :         }
     425             :         else
     426             :         {
     427           0 :             m_pImpl->m_pTempFile.reset();
     428           0 :             m_pImpl->m_MediaProperties.setURL(url, "", rNewProperties.getReferer());
     429             :         }
     430           5 :         bBroadcastChanged = true;
     431             :     }
     432             : 
     433          44 :     if( AVMEDIA_SETMASK_LOOP & nMaskSet )
     434          10 :         m_pImpl->m_MediaProperties.setLoop( rNewProperties.isLoop() );
     435             : 
     436          44 :     if( AVMEDIA_SETMASK_MUTE & nMaskSet )
     437          10 :         m_pImpl->m_MediaProperties.setMute( rNewProperties.isMute() );
     438             : 
     439          44 :     if( AVMEDIA_SETMASK_VOLUMEDB & nMaskSet )
     440          10 :         m_pImpl->m_MediaProperties.setVolumeDB( rNewProperties.getVolumeDB() );
     441             : 
     442          44 :     if( AVMEDIA_SETMASK_ZOOM & nMaskSet )
     443           4 :         m_pImpl->m_MediaProperties.setZoom( rNewProperties.getZoom() );
     444             : 
     445          44 :     if( bBroadcastChanged )
     446             :     {
     447           5 :         SetChanged();
     448           5 :         BroadcastObjectChange();
     449             :     }
     450          44 : }
     451             : 
     452             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10