LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/misc - embedhlp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 251 379 66.2 %
Date: 2012-12-17 Functions: 36 41 87.8 %
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             : 
      21             : #include <svtools/embedhlp.hxx>
      22             : #include <svtools/filter.hxx>
      23             : #include <svtools/svtools.hrc>
      24             : #include <svtools/svtresid.hxx>
      25             : 
      26             : #include <comphelper/embeddedobjectcontainer.hxx>
      27             : #include <comphelper/seqstream.hxx>
      28             : #include <toolkit/helper/vclunohelper.hxx>
      29             : #include <unotools/ucbstreamhelper.hxx>
      30             : #include <unotools/streamwrap.hxx>
      31             : 
      32             : #include <tools/globname.hxx>
      33             : #include <sot/clsids.hxx>
      34             : #include <com/sun/star/util/XModifyListener.hpp>
      35             : #include <com/sun/star/util/XModifiable.hpp>
      36             : #include <com/sun/star/embed/EmbedStates.hpp>
      37             : #include <com/sun/star/embed/EmbedMisc.hpp>
      38             : #include <com/sun/star/embed/XStateChangeListener.hpp>
      39             : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
      40             : #include <com/sun/star/datatransfer/XTransferable.hpp>
      41             : #include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
      42             : #include <cppuhelper/implbase4.hxx>
      43             : #include "vcl/svapp.hxx"
      44             : #include <rtl/logfile.hxx>
      45             : #include <osl/mutex.hxx>
      46             : 
      47             : using namespace com::sun::star;
      48             : 
      49             : namespace svt
      50             : {
      51             : 
      52        1196 : class EmbedEventListener_Impl : public ::cppu::WeakImplHelper4 < embed::XStateChangeListener,
      53             :                                                                  document::XEventListener,
      54             :                                                                  util::XModifyListener,
      55             :                                                                  util::XCloseListener >
      56             : {
      57             : public:
      58             :     EmbeddedObjectRef*          pObject;
      59             :     sal_Int32                   nState;
      60             : 
      61         900 :                                 EmbedEventListener_Impl( EmbeddedObjectRef* p ) :
      62             :                                     pObject(p)
      63         900 :                                     , nState(-1)
      64         900 :                                 {}
      65             : 
      66             :     static EmbedEventListener_Impl* Create( EmbeddedObjectRef* );
      67             : 
      68             :     virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
      69             :                                     throw (embed::WrongStateException, uno::RuntimeException);
      70             :     virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
      71             :                                     throw (uno::RuntimeException);
      72             :     virtual void SAL_CALL queryClosing( const lang::EventObject& Source, ::sal_Bool GetsOwnership )
      73             :                                     throw (util::CloseVetoException, uno::RuntimeException);
      74             :     virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException);
      75             :     virtual void SAL_CALL notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException );
      76             :     virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException );
      77             :     virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException);
      78             : };
      79             : 
      80         900 : EmbedEventListener_Impl* EmbedEventListener_Impl::Create( EmbeddedObjectRef* p )
      81             : {
      82         900 :     EmbedEventListener_Impl* xRet = new EmbedEventListener_Impl( p );
      83         900 :     xRet->acquire();
      84             : 
      85         900 :     if ( p->GetObject().is() )
      86             :     {
      87         900 :         p->GetObject()->addStateChangeListener( xRet );
      88             : 
      89         900 :         uno::Reference < util::XCloseable > xClose( p->GetObject(), uno::UNO_QUERY );
      90             :         DBG_ASSERT( xClose.is(), "Object does not support XCloseable!" );
      91         900 :         if ( xClose.is() )
      92         900 :             xClose->addCloseListener( xRet );
      93             : 
      94         900 :         uno::Reference < document::XEventBroadcaster > xBrd( p->GetObject(), uno::UNO_QUERY );
      95         900 :         if ( xBrd.is() )
      96         900 :             xBrd->addEventListener( xRet );
      97             : 
      98         900 :         xRet->nState = p->GetObject()->getCurrentState();
      99         900 :         if ( xRet->nState == embed::EmbedStates::RUNNING )
     100             :         {
     101         874 :             uno::Reference < util::XModifiable > xMod( p->GetObject()->getComponent(), uno::UNO_QUERY );
     102         874 :             if ( xMod.is() )
     103             :                 // listen for changes in running state (update replacements in case of changes)
     104         874 :                 xMod->addModifyListener( xRet );
     105         900 :         }
     106             :     }
     107             : 
     108         900 :     return xRet;
     109             : }
     110             : 
     111         126 : void SAL_CALL EmbedEventListener_Impl::changingState( const lang::EventObject&,
     112             :                                                     ::sal_Int32,
     113             :                                                     ::sal_Int32 )
     114             :     throw ( embed::WrongStateException,
     115             :             uno::RuntimeException )
     116             : {
     117         126 : }
     118             : 
     119         120 : void SAL_CALL EmbedEventListener_Impl::stateChanged( const lang::EventObject&,
     120             :                                                     ::sal_Int32 nOldState,
     121             :                                                     ::sal_Int32 nNewState )
     122             :     throw ( uno::RuntimeException )
     123             : {
     124         120 :     SolarMutexGuard aGuard;
     125         120 :     nState = nNewState;
     126         120 :     if ( !pObject )
     127         120 :         return;
     128             : 
     129         120 :     uno::Reference < util::XModifiable > xMod( pObject->GetObject()->getComponent(), uno::UNO_QUERY );
     130         120 :     if ( nNewState == embed::EmbedStates::RUNNING )
     131             :     {
     132             :         // TODO/LATER: container must be set before!
     133             :         // When is this event created? Who sets the new container when it changed?
     134           0 :         if( ( pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON ) && nOldState != embed::EmbedStates::LOADED && !pObject->IsChart() )
     135             :             // get new replacement after deactivation
     136           0 :             pObject->UpdateReplacement();
     137             : 
     138           0 :         if( pObject->IsChart() && nOldState == embed::EmbedStates::UI_ACTIVE )
     139             :         {
     140             :             //create a new metafile replacement when leaving the edit mode
     141             :             //for buggy documents where the old image looks different from the correct one
     142           0 :             if( xMod.is() && !xMod->isModified() )//in case of modification a new replacement will be requested anyhow
     143           0 :                 pObject->UpdateReplacementOnDemand();
     144             :         }
     145             : 
     146           0 :         if ( xMod.is() && nOldState == embed::EmbedStates::LOADED )
     147             :             // listen for changes (update replacements in case of changes)
     148           0 :             xMod->addModifyListener( this );
     149             :     }
     150         120 :     else if ( nNewState == embed::EmbedStates::LOADED )
     151             :     {
     152             :         // in loaded state we can't listen
     153         120 :         if ( xMod.is() )
     154           0 :             xMod->removeModifyListener( this );
     155         120 :     }
     156             : }
     157             : 
     158        4704 : void SAL_CALL EmbedEventListener_Impl::modified( const lang::EventObject& ) throw (uno::RuntimeException)
     159             : {
     160        4704 :     SolarMutexGuard aGuard;
     161        4704 :     if ( pObject && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON )
     162             :     {
     163        4624 :         if ( nState == embed::EmbedStates::RUNNING )
     164             :         {
     165             :             // updates only necessary in non-active states
     166        4624 :             if( pObject->IsChart() )
     167          80 :                 pObject->UpdateReplacementOnDemand();
     168             :             else
     169        4544 :                 pObject->UpdateReplacement();
     170             :         }
     171           0 :         else if ( nState == embed::EmbedStates::ACTIVE ||
     172             :                   nState == embed::EmbedStates::UI_ACTIVE ||
     173             :                   nState == embed::EmbedStates::INPLACE_ACTIVE )
     174             :         {
     175             :             // in case the object is inplace or UI active the replacement image should be updated on demand
     176           0 :             pObject->UpdateReplacementOnDemand();
     177             :         }
     178        4704 :     }
     179        4704 : }
     180             : 
     181        7912 : void SAL_CALL EmbedEventListener_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException )
     182             : {
     183        7912 :     SolarMutexGuard aGuard;
     184             : 
     185        7912 :     if ( pObject && aEvent.EventName == "OnVisAreaChanged" && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON && !pObject->IsChart() )
     186             :     {
     187           0 :         pObject->UpdateReplacement();
     188        7912 :     }
     189        7912 : }
     190             : 
     191          96 : void SAL_CALL EmbedEventListener_Impl::queryClosing( const lang::EventObject& Source, ::sal_Bool )
     192             :         throw ( util::CloseVetoException, uno::RuntimeException)
     193             : {
     194             :     // An embedded object can be shared between several objects (f.e. for undo purposes)
     195             :     // the object will not be closed before the last "customer" is destroyed
     196             :     // Now the EmbeddedObjectRef helper class works like a "lock" on the object
     197          96 :     if ( pObject && pObject->IsLocked() && Source.Source == pObject->GetObject() )
     198          96 :         throw util::CloseVetoException();
     199           0 : }
     200             : 
     201           0 : void SAL_CALL EmbedEventListener_Impl::notifyClosing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException)
     202             : {
     203           0 :     if ( pObject && Source.Source == pObject->GetObject() )
     204             :     {
     205           0 :         pObject->Clear();
     206           0 :         pObject = 0;
     207             :     }
     208           0 : }
     209             : 
     210         694 : void SAL_CALL EmbedEventListener_Impl::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
     211             : {
     212         694 :     if ( pObject && aEvent.Source == pObject->GetObject() )
     213             :     {
     214           0 :         pObject->Clear();
     215           0 :         pObject = 0;
     216             :     }
     217         694 : }
     218             : 
     219        1602 : struct EmbeddedObjectRef_Impl
     220             : {
     221             :     EmbedEventListener_Impl*                    xListener;
     222             :     ::rtl::OUString                             aPersistName;
     223             :     ::rtl::OUString                             aMediaType;
     224             :     comphelper::EmbeddedObjectContainer*        pContainer;
     225             :     Graphic*                                    pGraphic;
     226             :     sal_Int64                                   nViewAspect;
     227             :     sal_Bool                                        bIsLocked;
     228             :     sal_Bool                                    bNeedUpdate;
     229             : 
     230             :     // #i104867#
     231             :     sal_uInt32                                  mnGraphicVersion;
     232             :     awt::Size                                   aDefaultSizeForChart_In_100TH_MM;//#i103460# charts do not necessaryly have an own size within ODF files, in this case they need to use the size settings from the surrounding frame, which is made available with this member
     233             : };
     234             : 
     235         530 : void EmbeddedObjectRef::Construct_Impl()
     236             : {
     237         530 :     mpImp = new EmbeddedObjectRef_Impl;
     238         530 :     mpImp->pContainer = 0;
     239         530 :     mpImp->pGraphic = 0;
     240         530 :     mpImp->nViewAspect = embed::Aspects::MSOLE_CONTENT;
     241         530 :     mpImp->bIsLocked = sal_False;
     242         530 :     mpImp->bNeedUpdate = sal_False;
     243         530 :     mpImp->mnGraphicVersion = 0;
     244         530 :     mpImp->aDefaultSizeForChart_In_100TH_MM = awt::Size(8000,7000);
     245         530 : }
     246             : 
     247         298 : EmbeddedObjectRef::EmbeddedObjectRef()
     248             : {
     249         298 :     Construct_Impl();
     250         298 : }
     251             : 
     252         232 : EmbeddedObjectRef::EmbeddedObjectRef( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
     253             : {
     254         232 :     Construct_Impl();
     255         232 :     mpImp->nViewAspect = nAspect;
     256         232 :     mxObj = xObj;
     257         232 :     mpImp->xListener = EmbedEventListener_Impl::Create( this );
     258         232 : }
     259             : 
     260         372 : EmbeddedObjectRef::EmbeddedObjectRef( const EmbeddedObjectRef& rObj )
     261             : {
     262         372 :     mpImp = new EmbeddedObjectRef_Impl;
     263         372 :     mpImp->pContainer = rObj.mpImp->pContainer;
     264         372 :     mpImp->nViewAspect = rObj.mpImp->nViewAspect;
     265         372 :     mpImp->bIsLocked = rObj.mpImp->bIsLocked;
     266         372 :     mxObj = rObj.mxObj;
     267         372 :     mpImp->xListener = EmbedEventListener_Impl::Create( this );
     268         372 :     mpImp->aPersistName = rObj.mpImp->aPersistName;
     269         372 :     mpImp->aMediaType = rObj.mpImp->aMediaType;
     270         372 :     mpImp->bNeedUpdate = rObj.mpImp->bNeedUpdate;
     271         372 :     mpImp->aDefaultSizeForChart_In_100TH_MM = rObj.mpImp->aDefaultSizeForChart_In_100TH_MM;
     272             : 
     273         372 :     if ( rObj.mpImp->pGraphic && !rObj.mpImp->bNeedUpdate )
     274         290 :         mpImp->pGraphic = new Graphic( *rObj.mpImp->pGraphic );
     275             :     else
     276          82 :         mpImp->pGraphic = 0;
     277             : 
     278         372 :     mpImp->mnGraphicVersion = 0;
     279         372 : }
     280             : 
     281        1400 : EmbeddedObjectRef::~EmbeddedObjectRef()
     282             : {
     283         700 :     delete mpImp->pGraphic;
     284         700 :     Clear();
     285         700 :     delete mpImp;
     286         700 : }
     287             : 
     288         296 : void EmbeddedObjectRef::Assign( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
     289             : {
     290             :     DBG_ASSERT( !mxObj.is(), "Never assign an already assigned object!" );
     291             : 
     292         296 :     Clear();
     293         296 :     mpImp->nViewAspect = nAspect;
     294         296 :     mxObj = xObj;
     295         296 :     mpImp->xListener = EmbedEventListener_Impl::Create( this );
     296             : 
     297             :     //#i103460#
     298         296 :     if ( IsChart() )
     299             :     {
     300           0 :         uno::Reference < chart2::XDefaultSizeTransmitter > xSizeTransmitter( xObj, uno::UNO_QUERY );
     301             :         DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
     302           0 :         if( xSizeTransmitter.is() )
     303           0 :             xSizeTransmitter->setDefaultSize( mpImp->aDefaultSizeForChart_In_100TH_MM );
     304             :     }
     305         296 : }
     306             : 
     307        1082 : void EmbeddedObjectRef::Clear()
     308             : {
     309        1082 :     if ( mxObj.is() && mpImp->xListener )
     310             :     {
     311         698 :         mxObj->removeStateChangeListener( mpImp->xListener );
     312             : 
     313         698 :         uno::Reference < util::XCloseable > xClose( mxObj, uno::UNO_QUERY );
     314         698 :         if ( xClose.is() )
     315         698 :             xClose->removeCloseListener( mpImp->xListener );
     316             : 
     317         698 :         uno::Reference < document::XEventBroadcaster > xBrd( mxObj, uno::UNO_QUERY );
     318         698 :         if ( xBrd.is() )
     319         698 :             xBrd->removeEventListener( mpImp->xListener );
     320             : 
     321         698 :         if ( mpImp->bIsLocked )
     322             :         {
     323         180 :             if ( xClose.is() )
     324             :             {
     325             :                 try
     326             :                 {
     327         180 :                     mxObj->changeState( embed::EmbedStates::LOADED );
     328         180 :                     xClose->close( sal_True );
     329             :                 }
     330           0 :                 catch (const util::CloseVetoException&)
     331             :                 {
     332             :                     // there's still someone who needs the object!
     333             :                 }
     334           0 :                 catch (const uno::Exception&)
     335             :                 {
     336             :                     OSL_FAIL( "Error on switching of the object to loaded state and closing!\n" );
     337             :                 }
     338             :             }
     339             :         }
     340             : 
     341         698 :         if ( mpImp->xListener )
     342             :         {
     343         698 :             mpImp->xListener->pObject = 0;
     344         698 :             mpImp->xListener->release();
     345         698 :             mpImp->xListener = 0;
     346             :         }
     347             : 
     348         698 :         mxObj = 0;
     349         698 :         mpImp->bNeedUpdate = sal_False;
     350             :     }
     351             : 
     352        1082 :     mpImp->pContainer = 0;
     353        1082 :     mpImp->bIsLocked = sal_False;
     354        1082 :     mpImp->bNeedUpdate = sal_False;
     355        1082 : }
     356             : 
     357         480 : void EmbeddedObjectRef::AssignToContainer( comphelper::EmbeddedObjectContainer* pContainer, const ::rtl::OUString& rPersistName )
     358             : {
     359         480 :     mpImp->pContainer = pContainer;
     360         480 :     mpImp->aPersistName = rPersistName;
     361             : 
     362         480 :     if ( mpImp->pGraphic && !mpImp->bNeedUpdate && pContainer )
     363         290 :         SetGraphicToContainer( *mpImp->pGraphic, *pContainer, mpImp->aPersistName, ::rtl::OUString() );
     364         480 : }
     365             : 
     366          96 : comphelper::EmbeddedObjectContainer* EmbeddedObjectRef::GetContainer() const
     367             : {
     368          96 :     return mpImp->pContainer;
     369             : }
     370             : 
     371        6272 : sal_Int64 EmbeddedObjectRef::GetViewAspect() const
     372             : {
     373        6272 :     return mpImp->nViewAspect;
     374             : }
     375             : 
     376          14 : void EmbeddedObjectRef::SetViewAspect( sal_Int64 nAspect )
     377             : {
     378          14 :     mpImp->nViewAspect = nAspect;
     379          14 : }
     380             : 
     381         482 : void EmbeddedObjectRef::Lock( sal_Bool bLock )
     382             : {
     383         482 :     mpImp->bIsLocked = bLock;
     384         482 : }
     385             : 
     386          96 : sal_Bool EmbeddedObjectRef::IsLocked() const
     387             : {
     388          96 :     return mpImp->bIsLocked;
     389             : }
     390             : 
     391        4546 : void EmbeddedObjectRef::GetReplacement( sal_Bool bUpdate )
     392             : {
     393        4546 :     if ( bUpdate )
     394             :     {
     395        4544 :         DELETEZ( mpImp->pGraphic );
     396        4544 :         mpImp->aMediaType = ::rtl::OUString();
     397        4544 :         mpImp->pGraphic = new Graphic;
     398        4544 :         mpImp->mnGraphicVersion++;
     399             :     }
     400           2 :     else if ( !mpImp->pGraphic )
     401             :     {
     402           2 :         mpImp->pGraphic = new Graphic;
     403           2 :         mpImp->mnGraphicVersion++;
     404             :     }
     405             :     else
     406             :     {
     407             :         OSL_FAIL("No update, but replacement exists already!");
     408        4546 :         return;
     409             :     }
     410             : 
     411        4546 :     SvStream* pGraphicStream = GetGraphicStream( bUpdate );
     412        4546 :     if ( pGraphicStream )
     413             :     {
     414        4546 :         GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
     415        4546 :         if( mpImp->pGraphic )
     416        4546 :             rGF.ImportGraphic( *mpImp->pGraphic, String(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
     417        4546 :         mpImp->mnGraphicVersion++;
     418        4546 :         delete pGraphicStream;
     419             :     }
     420             : }
     421             : 
     422         450 : Graphic* EmbeddedObjectRef::GetGraphic( ::rtl::OUString* pMediaType ) const
     423             : {
     424         450 :     if ( mpImp->bNeedUpdate )
     425             :         // bNeedUpdate will be set to false while retrieving new replacement
     426           0 :         const_cast < EmbeddedObjectRef* >(this)->GetReplacement( sal_True );
     427         450 :     else if ( !mpImp->pGraphic )
     428           2 :         const_cast < EmbeddedObjectRef* >(this)->GetReplacement( sal_False );
     429             : 
     430         450 :     if ( mpImp->pGraphic && pMediaType )
     431           0 :         *pMediaType = mpImp->aMediaType;
     432         450 :     return mpImp->pGraphic;
     433             : }
     434             : 
     435         202 : Size EmbeddedObjectRef::GetSize( MapMode* pTargetMapMode ) const
     436             : {
     437         202 :     MapMode aSourceMapMode( MAP_100TH_MM );
     438         202 :     Size aResult;
     439             : 
     440         202 :     if ( mpImp->nViewAspect == embed::Aspects::MSOLE_ICON )
     441             :     {
     442           0 :         Graphic* pGraphic = GetGraphic();
     443           0 :         if ( pGraphic )
     444             :         {
     445           0 :             aSourceMapMode = pGraphic->GetPrefMapMode();
     446           0 :             aResult = pGraphic->GetPrefSize();
     447             :         }
     448             :         else
     449           0 :             aResult = Size( 2500, 2500 );
     450             :     }
     451             :     else
     452             :     {
     453         202 :         awt::Size aSize;
     454             : 
     455         202 :         if ( mxObj.is() )
     456             :         {
     457             :             try
     458             :             {
     459         202 :                 aSize = mxObj->getVisualAreaSize( mpImp->nViewAspect );
     460             :             }
     461           0 :             catch(const embed::NoVisualAreaSizeException&)
     462             :             {
     463             :             }
     464           2 :             catch(const uno::Exception&)
     465             :             {
     466             :                 OSL_FAIL( "Something went wrong on getting of the size of the object!" );
     467             :             }
     468             : 
     469             :             try
     470             :             {
     471         202 :                 aSourceMapMode = VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj->getMapUnit( mpImp->nViewAspect ) );
     472             :             }
     473           2 :             catch(const uno::Exception&)
     474             :             {
     475             :                 OSL_FAIL( "Can not get the map mode!" );
     476             :             }
     477             :         }
     478             : 
     479         202 :         if ( !aSize.Height && !aSize.Width )
     480             :         {
     481           2 :             aSize.Width = 5000;
     482           2 :             aSize.Height = 5000;
     483             :         }
     484             : 
     485         202 :         aResult = Size( aSize.Width, aSize.Height );
     486             :     }
     487             : 
     488         202 :     if ( pTargetMapMode )
     489         202 :         aResult = OutputDevice::LogicToLogic( aResult, aSourceMapMode, *pTargetMapMode );
     490             : 
     491         202 :     return aResult;
     492             : }
     493             : 
     494           0 : void EmbeddedObjectRef::SetGraphicStream( const uno::Reference< io::XInputStream >& xInGrStream,
     495             :                                             const ::rtl::OUString& rMediaType )
     496             : {
     497           0 :     if ( mpImp->pGraphic )
     498           0 :         delete mpImp->pGraphic;
     499           0 :     mpImp->pGraphic = new Graphic();
     500           0 :     mpImp->aMediaType = rMediaType;
     501           0 :     mpImp->mnGraphicVersion++;
     502             : 
     503           0 :     SvStream* pGraphicStream = ::utl::UcbStreamHelper::CreateStream( xInGrStream );
     504             : 
     505           0 :     if ( pGraphicStream )
     506             :     {
     507           0 :         GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
     508           0 :         rGF.ImportGraphic( *mpImp->pGraphic, String(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
     509           0 :         mpImp->mnGraphicVersion++;
     510             : 
     511           0 :         if ( mpImp->pContainer )
     512             :         {
     513           0 :             pGraphicStream->Seek( 0 );
     514           0 :             uno::Reference< io::XInputStream > xInSeekGrStream = new ::utl::OSeekableInputStreamWrapper( pGraphicStream );
     515             : 
     516           0 :             mpImp->pContainer->InsertGraphicStream( xInSeekGrStream, mpImp->aPersistName, rMediaType );
     517             :         }
     518             : 
     519           0 :         delete pGraphicStream;
     520             :     }
     521             : 
     522           0 :     mpImp->bNeedUpdate = sal_False;
     523             : 
     524           0 : }
     525             : 
     526           8 : void EmbeddedObjectRef::SetGraphic( const Graphic& rGraphic, const ::rtl::OUString& rMediaType )
     527             : {
     528           8 :     if ( mpImp->pGraphic )
     529           0 :         delete mpImp->pGraphic;
     530           8 :     mpImp->pGraphic = new Graphic( rGraphic );
     531           8 :     mpImp->aMediaType = rMediaType;
     532           8 :     mpImp->mnGraphicVersion++;
     533             : 
     534           8 :     if ( mpImp->pContainer )
     535           2 :         SetGraphicToContainer( rGraphic, *mpImp->pContainer, mpImp->aPersistName, rMediaType );
     536             : 
     537           8 :     mpImp->bNeedUpdate = sal_False;
     538           8 : }
     539             : 
     540        4546 : SvStream* EmbeddedObjectRef::GetGraphicStream( sal_Bool bUpdate ) const
     541             : {
     542             :     RTL_LOGFILE_CONTEXT( aLog, "svtools (mv76033) svt::EmbeddedObjectRef::GetGraphicStream" );
     543             :     DBG_ASSERT( bUpdate || mpImp->pContainer, "Can't retrieve current graphic!" );
     544        4546 :     uno::Reference < io::XInputStream > xStream;
     545        4546 :     if ( mpImp->pContainer && !bUpdate )
     546             :     {
     547             :         RTL_LOGFILE_CONTEXT_TRACE( aLog, "getting stream from container" );
     548             :         // try to get graphic stream from container storage
     549           2 :         xStream = mpImp->pContainer->GetGraphicStream( mxObj, &mpImp->aMediaType );
     550           2 :         if ( xStream.is() )
     551             :         {
     552           2 :             const sal_Int32 nConstBufferSize = 32000;
     553           2 :             SvStream *pStream = new SvMemoryStream( 32000, 32000 );
     554             :             try
     555             :             {
     556           2 :                 sal_Int32 nRead=0;
     557           2 :                 uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
     558           2 :                 do
     559             :                 {
     560           2 :                     nRead = xStream->readBytes ( aSequence, nConstBufferSize );
     561           2 :                     pStream->Write( aSequence.getConstArray(), nRead );
     562             :                 }
     563             :                 while ( nRead == nConstBufferSize );
     564           2 :                 pStream->Seek(0);
     565           2 :                 return pStream;
     566             :             }
     567           0 :             catch (const uno::Exception& ex)
     568             :             {
     569             :                 SAL_WARN("svtools", "discarding broken embedded object preview: " << ex.Message);
     570           0 :                 delete pStream;
     571           0 :                 xStream.clear();
     572             :             }
     573             :         }
     574             :     }
     575             : 
     576        4544 :     if ( !xStream.is() )
     577             :     {
     578             :         RTL_LOGFILE_CONTEXT_TRACE( aLog, "getting stream from object" );
     579             :         // update wanted or no stream in container storage available
     580        4544 :         xStream = GetGraphicReplacementStream( mpImp->nViewAspect, mxObj, &mpImp->aMediaType );
     581             : 
     582        4544 :         if ( xStream.is() )
     583             :         {
     584        4544 :             if ( mpImp->pContainer )
     585           0 :                 mpImp->pContainer->InsertGraphicStream( xStream, mpImp->aPersistName, mpImp->aMediaType );
     586             : 
     587        4544 :             SvStream* pResult = ::utl::UcbStreamHelper::CreateStream( xStream );
     588        4544 :             if ( pResult && bUpdate )
     589        4544 :                 mpImp->bNeedUpdate = sal_False;
     590             : 
     591        4544 :             return pResult;
     592             :         }
     593             :     }
     594             : 
     595           0 :     return NULL;
     596             : }
     597             : 
     598           0 : void EmbeddedObjectRef::DrawPaintReplacement( const Rectangle &rRect, const String &rText, OutputDevice *pOut )
     599             : {
     600           0 :     MapMode aMM( MAP_APPFONT );
     601           0 :     Size aAppFontSz = pOut->LogicToLogic( Size( 0, 8 ), &aMM, NULL );
     602           0 :     Font aFnt( rtl::OUString("Helvetica"), aAppFontSz );
     603           0 :     aFnt.SetTransparent( sal_True );
     604           0 :     aFnt.SetColor( Color( COL_LIGHTRED ) );
     605           0 :     aFnt.SetWeight( WEIGHT_BOLD );
     606           0 :     aFnt.SetFamily( FAMILY_SWISS );
     607             : 
     608           0 :     pOut->Push();
     609           0 :     pOut->SetBackground();
     610           0 :     pOut->SetFont( aFnt );
     611             : 
     612           0 :     Point aPt;
     613             :     // Nun den Text so skalieren, dass er in das Rect passt.
     614             :     // Wir fangen mit der Defaultsize an und gehen 1-AppFont runter
     615           0 :     for( sal_uInt16 i = 8; i > 2; i-- )
     616             :     {
     617           0 :         aPt.X() = (rRect.GetWidth()  - pOut->GetTextWidth( rText )) / 2;
     618           0 :         aPt.Y() = (rRect.GetHeight() - pOut->GetTextHeight()) / 2;
     619             : 
     620           0 :         sal_Bool bTiny = sal_False;
     621           0 :         if( aPt.X() < 0 ) bTiny = sal_True, aPt.X() = 0;
     622           0 :         if( aPt.Y() < 0 ) bTiny = sal_True, aPt.Y() = 0;
     623           0 :         if( bTiny )
     624             :         {
     625             :             // heruntergehen bei kleinen Bildern
     626           0 :             aFnt.SetSize( Size( 0, aAppFontSz.Height() * i / 8 ) );
     627           0 :             pOut->SetFont( aFnt );
     628             :         }
     629             :         else
     630           0 :             break;
     631             :     }
     632             : 
     633           0 :     Bitmap aBmp( SvtResId( BMP_PLUGIN ) );
     634           0 :     long nHeight = rRect.GetHeight() - pOut->GetTextHeight();
     635           0 :     long nWidth = rRect.GetWidth();
     636           0 :     if( nHeight > 0 )
     637             :     {
     638           0 :         aPt.Y() = nHeight;
     639           0 :         Point   aP = rRect.TopLeft();
     640           0 :         Size    aBmpSize = aBmp.GetSizePixel();
     641             :         // Bitmap einpassen
     642           0 :         if( nHeight * 10 / nWidth
     643           0 :           > aBmpSize.Height() * 10 / aBmpSize.Width() )
     644             :         {
     645             :             // nach der Breite ausrichten
     646             :             // Proportion beibehalten
     647           0 :             long nH = nWidth * aBmpSize.Height() / aBmpSize.Width();
     648             :             // zentrieren
     649           0 :             aP.Y() += (nHeight - nH) / 2;
     650           0 :             nHeight = nH;
     651             :         }
     652             :         else
     653             :         {
     654             :             // nach der H"ohe ausrichten
     655             :             // Proportion beibehalten
     656           0 :             long nW = nHeight * aBmpSize.Width() / aBmpSize.Height();
     657             :             // zentrieren
     658           0 :             aP.X() += (nWidth - nW) / 2;
     659           0 :             nWidth = nW;
     660             :         }
     661             : 
     662           0 :         pOut->DrawBitmap( aP, Size( nWidth, nHeight ), aBmp );
     663             :     }
     664             : 
     665           0 :     pOut->IntersectClipRegion( rRect );
     666           0 :     aPt += rRect.TopLeft();
     667           0 :     pOut->DrawText( aPt, rText );
     668           0 :     pOut->Pop();
     669           0 : }
     670             : 
     671           0 : void EmbeddedObjectRef::DrawShading( const Rectangle &rRect, OutputDevice *pOut )
     672             : {
     673           0 :     GDIMetaFile * pMtf = pOut->GetConnectMetaFile();
     674           0 :     if( pMtf && pMtf->IsRecord() )
     675           0 :         return;
     676             : 
     677           0 :     pOut->Push();
     678           0 :     pOut->SetLineColor( Color( COL_BLACK ) );
     679             : 
     680           0 :     Size aPixSize = pOut->LogicToPixel( rRect.GetSize() );
     681           0 :     aPixSize.Width() -= 1;
     682           0 :     aPixSize.Height() -= 1;
     683           0 :     Point aPixViewPos = pOut->LogicToPixel( rRect.TopLeft() );
     684           0 :     sal_Int32 nMax = aPixSize.Width() + aPixSize.Height();
     685           0 :     for( sal_Int32 i = 5; i < nMax; i += 5 )
     686             :     {
     687           0 :         Point a1( aPixViewPos ), a2( aPixViewPos );
     688           0 :         if( i > aPixSize.Width() )
     689           0 :             a1 += Point( aPixSize.Width(), i - aPixSize.Width() );
     690             :         else
     691           0 :             a1 += Point( i, 0 );
     692           0 :         if( i > aPixSize.Height() )
     693           0 :             a2 += Point( i - aPixSize.Height(), aPixSize.Height() );
     694             :         else
     695           0 :             a2 += Point( 0, i );
     696             : 
     697           0 :         pOut->DrawLine( pOut->PixelToLogic( a1 ), pOut->PixelToLogic( a2 ) );
     698             :     }
     699             : 
     700           0 :     pOut->Pop();
     701             : 
     702             : }
     703             : 
     704         714 : sal_Bool EmbeddedObjectRef::TryRunningState( const uno::Reference < embed::XEmbeddedObject >& xEmbObj )
     705             : {
     706         714 :     if ( !xEmbObj.is() )
     707           0 :         return sal_False;
     708             : 
     709             :     try
     710             :     {
     711         714 :         if ( xEmbObj->getCurrentState() == embed::EmbedStates::LOADED )
     712           2 :             xEmbObj->changeState( embed::EmbedStates::RUNNING );
     713             :     }
     714           4 :     catch (const uno::Exception&)
     715             :     {
     716           2 :         return sal_False;
     717             :     }
     718             : 
     719         712 :     return sal_True;
     720             : }
     721             : 
     722         292 : void EmbeddedObjectRef::SetGraphicToContainer( const Graphic& rGraphic,
     723             :                                                 comphelper::EmbeddedObjectContainer& aContainer,
     724             :                                                 const ::rtl::OUString& aName,
     725             :                                                 const ::rtl::OUString& aMediaType )
     726             : {
     727         292 :     SvMemoryStream aStream;
     728         292 :     aStream.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
     729         292 :     if ( rGraphic.ExportNative( aStream ) )
     730             :     {
     731         292 :         aStream.Seek( 0 );
     732             : 
     733         292 :            uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( aStream );
     734         292 :            aContainer.InsertGraphicStream( xStream, aName, aMediaType );
     735             :     }
     736             :     else
     737         292 :         OSL_FAIL( "Export of graphic is failed!\n" );
     738         292 : }
     739             : 
     740        4544 : uno::Reference< io::XInputStream > EmbeddedObjectRef::GetGraphicReplacementStream(
     741             :                                                                 sal_Int64 nViewAspect,
     742             :                                                                 const uno::Reference< embed::XEmbeddedObject >& xObj,
     743             :                                                                 ::rtl::OUString* pMediaType )
     744             :     throw()
     745             : {
     746        4544 :     return ::comphelper::EmbeddedObjectContainer::GetGraphicReplacementStream(nViewAspect,xObj,pMediaType);
     747             : }
     748             : 
     749          80 : void EmbeddedObjectRef::UpdateReplacementOnDemand()
     750             : {
     751          80 :     DELETEZ( mpImp->pGraphic );
     752          80 :     mpImp->bNeedUpdate = sal_True;
     753          80 :     mpImp->mnGraphicVersion++;
     754             : 
     755          80 :     if( mpImp->pContainer )
     756             :     {
     757             :         //remove graphic from container thus a new up to date one is requested on save
     758          80 :         mpImp->pContainer->RemoveGraphicStream( mpImp->aPersistName );
     759             :     }
     760          80 : }
     761             : 
     762        5000 : sal_Bool EmbeddedObjectRef::IsChart() const
     763             : {
     764             :     //todo maybe for 3.0:
     765             :     //if the changes work good for chart
     766             :     //we should apply them for all own ole objects
     767             : 
     768             :     //#i83708# #i81857# #i79578# request an ole replacement image only if really necessary
     769             :     //as this call can be very expensive and does block the user interface as long at it takes
     770             : 
     771        5000 :     if ( !mxObj.is() )
     772           0 :         return false;
     773             : 
     774        5000 :     SvGlobalName aObjClsId( mxObj->getClassID() );
     775       50000 :     if(
     776       15000 :         SvGlobalName(SO3_SCH_CLASSID_30) == aObjClsId
     777       15000 :         || SvGlobalName(SO3_SCH_CLASSID_40) == aObjClsId
     778       15000 :         || SvGlobalName(SO3_SCH_CLASSID_50) == aObjClsId
     779       15000 :         || SvGlobalName(SO3_SCH_CLASSID_60) == aObjClsId)
     780             :     {
     781         160 :         return sal_True;
     782             :     }
     783             : 
     784        4840 :     return sal_False;
     785             : }
     786             : 
     787             : // #i104867#
     788          82 : sal_uInt32 EmbeddedObjectRef::getGraphicVersion() const
     789             : {
     790          82 :     return mpImp->mnGraphicVersion;
     791             : }
     792             : 
     793           0 : void EmbeddedObjectRef::SetDefaultSizeForChart( const Size& rSizeIn_100TH_MM )
     794             : {
     795             :     //#i103460# charts do not necessaryly have an own size within ODF files,
     796             :     //for this case they need to use the size settings from the surrounding frame,
     797             :     //which is made available with this method
     798             : 
     799           0 :     mpImp->aDefaultSizeForChart_In_100TH_MM = awt::Size( rSizeIn_100TH_MM.getWidth(), rSizeIn_100TH_MM.getHeight() );
     800             : 
     801           0 :     uno::Reference < chart2::XDefaultSizeTransmitter > xSizeTransmitter( mxObj, uno::UNO_QUERY );
     802             :     DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
     803           0 :     if( xSizeTransmitter.is() )
     804           0 :         xSizeTransmitter->setDefaultSize( mpImp->aDefaultSizeForChart_In_100TH_MM );
     805           0 : }
     806             : 
     807             : } // namespace svt
     808             : 
     809             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10