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-27 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         676 : 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         452 :                                 EmbedEventListener_Impl( EmbeddedObjectRef* p ) :
      62             :                                     pObject(p)
      63         452 :                                     , nState(-1)
      64         452 :                                 {}
      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         452 : EmbedEventListener_Impl* EmbedEventListener_Impl::Create( EmbeddedObjectRef* p )
      81             : {
      82         452 :     EmbedEventListener_Impl* xRet = new EmbedEventListener_Impl( p );
      83         452 :     xRet->acquire();
      84             : 
      85         452 :     if ( p->GetObject().is() )
      86             :     {
      87         452 :         p->GetObject()->addStateChangeListener( xRet );
      88             : 
      89         452 :         uno::Reference < util::XCloseable > xClose( p->GetObject(), uno::UNO_QUERY );
      90             :         DBG_ASSERT( xClose.is(), "Object does not support XCloseable!" );
      91         452 :         if ( xClose.is() )
      92         452 :             xClose->addCloseListener( xRet );
      93             : 
      94         452 :         uno::Reference < document::XEventBroadcaster > xBrd( p->GetObject(), uno::UNO_QUERY );
      95         452 :         if ( xBrd.is() )
      96         452 :             xBrd->addEventListener( xRet );
      97             : 
      98         452 :         xRet->nState = p->GetObject()->getCurrentState();
      99         452 :         if ( xRet->nState == embed::EmbedStates::RUNNING )
     100             :         {
     101         439 :             uno::Reference < util::XModifiable > xMod( p->GetObject()->getComponent(), uno::UNO_QUERY );
     102         439 :             if ( xMod.is() )
     103             :                 // listen for changes in running state (update replacements in case of changes)
     104         439 :                 xMod->addModifyListener( xRet );
     105         452 :         }
     106             :     }
     107             : 
     108         452 :     return xRet;
     109             : }
     110             : 
     111          34 : void SAL_CALL EmbedEventListener_Impl::changingState( const lang::EventObject&,
     112             :                                                     ::sal_Int32,
     113             :                                                     ::sal_Int32 )
     114             :     throw ( embed::WrongStateException,
     115             :             uno::RuntimeException )
     116             : {
     117          34 : }
     118             : 
     119          31 : void SAL_CALL EmbedEventListener_Impl::stateChanged( const lang::EventObject&,
     120             :                                                     ::sal_Int32 nOldState,
     121             :                                                     ::sal_Int32 nNewState )
     122             :     throw ( uno::RuntimeException )
     123             : {
     124          31 :     SolarMutexGuard aGuard;
     125          31 :     nState = nNewState;
     126          31 :     if ( !pObject )
     127          31 :         return;
     128             : 
     129          31 :     uno::Reference < util::XModifiable > xMod( pObject->GetObject()->getComponent(), uno::UNO_QUERY );
     130          31 :     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          31 :     else if ( nNewState == embed::EmbedStates::LOADED )
     151             :     {
     152             :         // in loaded state we can't listen
     153          31 :         if ( xMod.is() )
     154           0 :             xMod->removeModifyListener( this );
     155          31 :     }
     156             : }
     157             : 
     158        2368 : void SAL_CALL EmbedEventListener_Impl::modified( const lang::EventObject& ) throw (uno::RuntimeException)
     159             : {
     160        2368 :     SolarMutexGuard aGuard;
     161        2368 :     if ( pObject && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON )
     162             :     {
     163        2328 :         if ( nState == embed::EmbedStates::RUNNING )
     164             :         {
     165             :             // updates only necessary in non-active states
     166        2328 :             if( pObject->IsChart() )
     167          40 :                 pObject->UpdateReplacementOnDemand();
     168             :             else
     169        2288 :                 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        2368 :     }
     179        2368 : }
     180             : 
     181        3901 : void SAL_CALL EmbedEventListener_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException )
     182             : {
     183        3901 :     SolarMutexGuard aGuard;
     184             : 
     185        3901 :     if ( pObject && aEvent.EventName == "OnVisAreaChanged" && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON && !pObject->IsChart() )
     186             :     {
     187           0 :         pObject->UpdateReplacement();
     188        3901 :     }
     189        3901 : }
     190             : 
     191          48 : 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          48 :     if ( pObject && pObject->IsLocked() && Source.Source == pObject->GetObject() )
     198          48 :         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         357 : void SAL_CALL EmbedEventListener_Impl::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException )
     211             : {
     212         357 :     if ( pObject && aEvent.Source == pObject->GetObject() )
     213             :     {
     214           0 :         pObject->Clear();
     215           0 :         pObject = 0;
     216             :     }
     217         357 : }
     218             : 
     219         833 : 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         266 : void EmbeddedObjectRef::Construct_Impl()
     236             : {
     237         266 :     mpImp = new EmbeddedObjectRef_Impl;
     238         266 :     mpImp->pContainer = 0;
     239         266 :     mpImp->pGraphic = 0;
     240         266 :     mpImp->nViewAspect = embed::Aspects::MSOLE_CONTENT;
     241         266 :     mpImp->bIsLocked = sal_False;
     242         266 :     mpImp->bNeedUpdate = sal_False;
     243         266 :     mpImp->mnGraphicVersion = 0;
     244         266 :     mpImp->aDefaultSizeForChart_In_100TH_MM = awt::Size(8000,7000);
     245         266 : }
     246             : 
     247         150 : EmbeddedObjectRef::EmbeddedObjectRef()
     248             : {
     249         150 :     Construct_Impl();
     250         150 : }
     251             : 
     252         116 : EmbeddedObjectRef::EmbeddedObjectRef( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
     253             : {
     254         116 :     Construct_Impl();
     255         116 :     mpImp->nViewAspect = nAspect;
     256         116 :     mxObj = xObj;
     257         116 :     mpImp->xListener = EmbedEventListener_Impl::Create( this );
     258         116 : }
     259             : 
     260         187 : EmbeddedObjectRef::EmbeddedObjectRef( const EmbeddedObjectRef& rObj )
     261             : {
     262         187 :     mpImp = new EmbeddedObjectRef_Impl;
     263         187 :     mpImp->pContainer = rObj.mpImp->pContainer;
     264         187 :     mpImp->nViewAspect = rObj.mpImp->nViewAspect;
     265         187 :     mpImp->bIsLocked = rObj.mpImp->bIsLocked;
     266         187 :     mxObj = rObj.mxObj;
     267         187 :     mpImp->xListener = EmbedEventListener_Impl::Create( this );
     268         187 :     mpImp->aPersistName = rObj.mpImp->aPersistName;
     269         187 :     mpImp->aMediaType = rObj.mpImp->aMediaType;
     270         187 :     mpImp->bNeedUpdate = rObj.mpImp->bNeedUpdate;
     271         187 :     mpImp->aDefaultSizeForChart_In_100TH_MM = rObj.mpImp->aDefaultSizeForChart_In_100TH_MM;
     272             : 
     273         187 :     if ( rObj.mpImp->pGraphic && !rObj.mpImp->bNeedUpdate )
     274         146 :         mpImp->pGraphic = new Graphic( *rObj.mpImp->pGraphic );
     275             :     else
     276          41 :         mpImp->pGraphic = 0;
     277             : 
     278         187 :     mpImp->mnGraphicVersion = 0;
     279         187 : }
     280             : 
     281         760 : EmbeddedObjectRef::~EmbeddedObjectRef()
     282             : {
     283         380 :     delete mpImp->pGraphic;
     284         380 :     Clear();
     285         380 :     delete mpImp;
     286         380 : }
     287             : 
     288         149 : 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         149 :     Clear();
     293         149 :     mpImp->nViewAspect = nAspect;
     294         149 :     mxObj = xObj;
     295         149 :     mpImp->xListener = EmbedEventListener_Impl::Create( this );
     296             : 
     297             :     //#i103460#
     298         149 :     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         149 : }
     306             : 
     307         601 : void EmbeddedObjectRef::Clear()
     308             : {
     309         601 :     if ( mxObj.is() && mpImp->xListener )
     310             :     {
     311         379 :         mxObj->removeStateChangeListener( mpImp->xListener );
     312             : 
     313         379 :         uno::Reference < util::XCloseable > xClose( mxObj, uno::UNO_QUERY );
     314         379 :         if ( xClose.is() )
     315         379 :             xClose->removeCloseListener( mpImp->xListener );
     316             : 
     317         379 :         uno::Reference < document::XEventBroadcaster > xBrd( mxObj, uno::UNO_QUERY );
     318         379 :         if ( xBrd.is() )
     319         379 :             xBrd->removeEventListener( mpImp->xListener );
     320             : 
     321         379 :         if ( mpImp->bIsLocked )
     322             :         {
     323         119 :             if ( xClose.is() )
     324             :             {
     325             :                 try
     326             :                 {
     327         119 :                     mxObj->changeState( embed::EmbedStates::LOADED );
     328         119 :                     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         379 :         if ( mpImp->xListener )
     342             :         {
     343         379 :             mpImp->xListener->pObject = 0;
     344         379 :             mpImp->xListener->release();
     345         379 :             mpImp->xListener = 0;
     346             :         }
     347             : 
     348         379 :         mxObj = 0;
     349         379 :         mpImp->bNeedUpdate = sal_False;
     350             :     }
     351             : 
     352         601 :     mpImp->pContainer = 0;
     353         601 :     mpImp->bIsLocked = sal_False;
     354         601 :     mpImp->bNeedUpdate = sal_False;
     355         601 : }
     356             : 
     357         241 : void EmbeddedObjectRef::AssignToContainer( comphelper::EmbeddedObjectContainer* pContainer, const ::rtl::OUString& rPersistName )
     358             : {
     359         241 :     mpImp->pContainer = pContainer;
     360         241 :     mpImp->aPersistName = rPersistName;
     361             : 
     362         241 :     if ( mpImp->pGraphic && !mpImp->bNeedUpdate && pContainer )
     363         146 :         SetGraphicToContainer( *mpImp->pGraphic, *pContainer, mpImp->aPersistName, ::rtl::OUString() );
     364         241 : }
     365             : 
     366          48 : comphelper::EmbeddedObjectContainer* EmbeddedObjectRef::GetContainer() const
     367             : {
     368          48 :     return mpImp->pContainer;
     369             : }
     370             : 
     371        2987 : sal_Int64 EmbeddedObjectRef::GetViewAspect() const
     372             : {
     373        2987 :     return mpImp->nViewAspect;
     374             : }
     375             : 
     376           7 : void EmbeddedObjectRef::SetViewAspect( sal_Int64 nAspect )
     377             : {
     378           7 :     mpImp->nViewAspect = nAspect;
     379           7 : }
     380             : 
     381         242 : void EmbeddedObjectRef::Lock( sal_Bool bLock )
     382             : {
     383         242 :     mpImp->bIsLocked = bLock;
     384         242 : }
     385             : 
     386          48 : sal_Bool EmbeddedObjectRef::IsLocked() const
     387             : {
     388          48 :     return mpImp->bIsLocked;
     389             : }
     390             : 
     391        2289 : void EmbeddedObjectRef::GetReplacement( sal_Bool bUpdate )
     392             : {
     393        2289 :     if ( bUpdate )
     394             :     {
     395        2288 :         DELETEZ( mpImp->pGraphic );
     396        2288 :         mpImp->aMediaType = ::rtl::OUString();
     397        2288 :         mpImp->pGraphic = new Graphic;
     398        2288 :         mpImp->mnGraphicVersion++;
     399             :     }
     400           1 :     else if ( !mpImp->pGraphic )
     401             :     {
     402           1 :         mpImp->pGraphic = new Graphic;
     403           1 :         mpImp->mnGraphicVersion++;
     404             :     }
     405             :     else
     406             :     {
     407             :         OSL_FAIL("No update, but replacement exists already!");
     408        2289 :         return;
     409             :     }
     410             : 
     411        2289 :     SvStream* pGraphicStream = GetGraphicStream( bUpdate );
     412        2289 :     if ( pGraphicStream )
     413             :     {
     414        2289 :         GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
     415        2289 :         if( mpImp->pGraphic )
     416        2289 :             rGF.ImportGraphic( *mpImp->pGraphic, String(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
     417        2289 :         mpImp->mnGraphicVersion++;
     418        2289 :         delete pGraphicStream;
     419             :     }
     420             : }
     421             : 
     422         169 : Graphic* EmbeddedObjectRef::GetGraphic( ::rtl::OUString* pMediaType ) const
     423             : {
     424         169 :     if ( mpImp->bNeedUpdate )
     425             :         // bNeedUpdate will be set to false while retrieving new replacement
     426           0 :         const_cast < EmbeddedObjectRef* >(this)->GetReplacement( sal_True );
     427         169 :     else if ( !mpImp->pGraphic )
     428           1 :         const_cast < EmbeddedObjectRef* >(this)->GetReplacement( sal_False );
     429             : 
     430         169 :     if ( mpImp->pGraphic && pMediaType )
     431           0 :         *pMediaType = mpImp->aMediaType;
     432         169 :     return mpImp->pGraphic;
     433             : }
     434             : 
     435         101 : Size EmbeddedObjectRef::GetSize( MapMode* pTargetMapMode ) const
     436             : {
     437         101 :     MapMode aSourceMapMode( MAP_100TH_MM );
     438         101 :     Size aResult;
     439             : 
     440         101 :     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         101 :         awt::Size aSize;
     454             : 
     455         101 :         if ( mxObj.is() )
     456             :         {
     457             :             try
     458             :             {
     459         101 :                 aSize = mxObj->getVisualAreaSize( mpImp->nViewAspect );
     460             :             }
     461           0 :             catch(const embed::NoVisualAreaSizeException&)
     462             :             {
     463             :             }
     464           1 :             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         101 :                 aSourceMapMode = VCLUnoHelper::UnoEmbed2VCLMapUnit( mxObj->getMapUnit( mpImp->nViewAspect ) );
     472             :             }
     473           1 :             catch(const uno::Exception&)
     474             :             {
     475             :                 OSL_FAIL( "Can not get the map mode!" );
     476             :             }
     477             :         }
     478             : 
     479         101 :         if ( !aSize.Height && !aSize.Width )
     480             :         {
     481           1 :             aSize.Width = 5000;
     482           1 :             aSize.Height = 5000;
     483             :         }
     484             : 
     485         101 :         aResult = Size( aSize.Width, aSize.Height );
     486             :     }
     487             : 
     488         101 :     if ( pTargetMapMode )
     489         101 :         aResult = OutputDevice::LogicToLogic( aResult, aSourceMapMode, *pTargetMapMode );
     490             : 
     491         101 :     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           4 : void EmbeddedObjectRef::SetGraphic( const Graphic& rGraphic, const ::rtl::OUString& rMediaType )
     527             : {
     528           4 :     if ( mpImp->pGraphic )
     529           0 :         delete mpImp->pGraphic;
     530           4 :     mpImp->pGraphic = new Graphic( rGraphic );
     531           4 :     mpImp->aMediaType = rMediaType;
     532           4 :     mpImp->mnGraphicVersion++;
     533             : 
     534           4 :     if ( mpImp->pContainer )
     535           1 :         SetGraphicToContainer( rGraphic, *mpImp->pContainer, mpImp->aPersistName, rMediaType );
     536             : 
     537           4 :     mpImp->bNeedUpdate = sal_False;
     538           4 : }
     539             : 
     540        2289 : 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        2289 :     uno::Reference < io::XInputStream > xStream;
     545        2289 :     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           1 :         xStream = mpImp->pContainer->GetGraphicStream( mxObj, &mpImp->aMediaType );
     550           1 :         if ( xStream.is() )
     551             :         {
     552           1 :             const sal_Int32 nConstBufferSize = 32000;
     553           1 :             SvStream *pStream = new SvMemoryStream( 32000, 32000 );
     554             :             try
     555             :             {
     556           1 :                 sal_Int32 nRead=0;
     557           1 :                 uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
     558           1 :                 do
     559             :                 {
     560           1 :                     nRead = xStream->readBytes ( aSequence, nConstBufferSize );
     561           1 :                     pStream->Write( aSequence.getConstArray(), nRead );
     562             :                 }
     563             :                 while ( nRead == nConstBufferSize );
     564           1 :                 pStream->Seek(0);
     565           1 :                 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        2288 :     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        2288 :         xStream = GetGraphicReplacementStream( mpImp->nViewAspect, mxObj, &mpImp->aMediaType );
     581             : 
     582        2288 :         if ( xStream.is() )
     583             :         {
     584        2288 :             if ( mpImp->pContainer )
     585           0 :                 mpImp->pContainer->InsertGraphicStream( xStream, mpImp->aPersistName, mpImp->aMediaType );
     586             : 
     587        2288 :             SvStream* pResult = ::utl::UcbStreamHelper::CreateStream( xStream );
     588        2288 :             if ( pResult && bUpdate )
     589        2288 :                 mpImp->bNeedUpdate = sal_False;
     590             : 
     591        2288 :             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         358 : sal_Bool EmbeddedObjectRef::TryRunningState( const uno::Reference < embed::XEmbeddedObject >& xEmbObj )
     705             : {
     706         358 :     if ( !xEmbObj.is() )
     707           0 :         return sal_False;
     708             : 
     709             :     try
     710             :     {
     711         358 :         if ( xEmbObj->getCurrentState() == embed::EmbedStates::LOADED )
     712           1 :             xEmbObj->changeState( embed::EmbedStates::RUNNING );
     713             :     }
     714           2 :     catch (const uno::Exception&)
     715             :     {
     716           1 :         return sal_False;
     717             :     }
     718             : 
     719         357 :     return sal_True;
     720             : }
     721             : 
     722         147 : void EmbeddedObjectRef::SetGraphicToContainer( const Graphic& rGraphic,
     723             :                                                 comphelper::EmbeddedObjectContainer& aContainer,
     724             :                                                 const ::rtl::OUString& aName,
     725             :                                                 const ::rtl::OUString& aMediaType )
     726             : {
     727         147 :     SvMemoryStream aStream;
     728         147 :     aStream.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
     729         147 :     if ( rGraphic.ExportNative( aStream ) )
     730             :     {
     731         147 :         aStream.Seek( 0 );
     732             : 
     733         147 :            uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( aStream );
     734         147 :            aContainer.InsertGraphicStream( xStream, aName, aMediaType );
     735             :     }
     736             :     else
     737         147 :         OSL_FAIL( "Export of graphic is failed!\n" );
     738         147 : }
     739             : 
     740        2288 : 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        2288 :     return ::comphelper::EmbeddedObjectContainer::GetGraphicReplacementStream(nViewAspect,xObj,pMediaType);
     747             : }
     748             : 
     749          40 : void EmbeddedObjectRef::UpdateReplacementOnDemand()
     750             : {
     751          40 :     DELETEZ( mpImp->pGraphic );
     752          40 :     mpImp->bNeedUpdate = sal_True;
     753          40 :     mpImp->mnGraphicVersion++;
     754             : 
     755          40 :     if( mpImp->pContainer )
     756             :     {
     757             :         //remove graphic from container thus a new up to date one is requested on save
     758          40 :         mpImp->pContainer->RemoveGraphicStream( mpImp->aPersistName );
     759             :     }
     760          40 : }
     761             : 
     762        2517 : 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        2517 :     if ( !mxObj.is() )
     772           0 :         return false;
     773             : 
     774        2517 :     SvGlobalName aObjClsId( mxObj->getClassID() );
     775       25170 :     if(
     776        7551 :         SvGlobalName(SO3_SCH_CLASSID_30) == aObjClsId
     777        7551 :         || SvGlobalName(SO3_SCH_CLASSID_40) == aObjClsId
     778        7551 :         || SvGlobalName(SO3_SCH_CLASSID_50) == aObjClsId
     779        7551 :         || SvGlobalName(SO3_SCH_CLASSID_60) == aObjClsId)
     780             :     {
     781          80 :         return sal_True;
     782             :     }
     783             : 
     784        2437 :     return sal_False;
     785             : }
     786             : 
     787             : // #i104867#
     788          41 : sal_uInt32 EmbeddedObjectRef::getGraphicVersion() const
     789             : {
     790          41 :     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