LCOV - code coverage report
Current view: top level - svtools/source/misc - embedhlp.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 268 436 61.5 %
Date: 2014-04-11 Functions: 41 46 89.1 %
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 <vcl/graphicfilter.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             : #include <com/sun/star/chart2/XChartDocument.hpp>
      32             : #include <com/sun/star/chart2/XCoordinateSystem.hpp>
      33             : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
      34             : #include <com/sun/star/chart2/XDiagram.hpp>
      35             : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
      36             : #include <com/sun/star/chart2/XChartType.hpp>
      37             : #include <tools/globname.hxx>
      38             : #include <comphelper/classids.hxx>
      39             : #include <com/sun/star/util/XModifyListener.hpp>
      40             : #include <com/sun/star/util/XModifiable.hpp>
      41             : #include <com/sun/star/embed/Aspects.hpp>
      42             : #include <com/sun/star/embed/EmbedMisc.hpp>
      43             : #include <com/sun/star/embed/EmbedStates.hpp>
      44             : #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
      45             : #include <com/sun/star/embed/XEmbeddedObject.hpp>
      46             : #include <com/sun/star/embed/XStateChangeListener.hpp>
      47             : #include <com/sun/star/datatransfer/XTransferable.hpp>
      48             : #include <com/sun/star/chart2/XDefaultSizeTransmitter.hpp>
      49             : #include <cppuhelper/implbase4.hxx>
      50             : #include "vcl/svapp.hxx"
      51             : #include <osl/mutex.hxx>
      52             : 
      53             : using namespace com::sun::star;
      54             : 
      55             : namespace svt {
      56             : 
      57        2078 : class EmbedEventListener_Impl : public ::cppu::WeakImplHelper4 < embed::XStateChangeListener,
      58             :                                                                  document::XEventListener,
      59             :                                                                  util::XModifyListener,
      60             :                                                                  util::XCloseListener >
      61             : {
      62             : public:
      63             :     EmbeddedObjectRef*          pObject;
      64             :     sal_Int32                   nState;
      65             : 
      66        1060 :                                 EmbedEventListener_Impl( EmbeddedObjectRef* p ) :
      67             :                                     pObject(p)
      68        1060 :                                     , nState(-1)
      69        1060 :                                 {}
      70             : 
      71             :     static EmbedEventListener_Impl* Create( EmbeddedObjectRef* );
      72             : 
      73             :     virtual void SAL_CALL changingState( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
      74             :                                     throw (embed::WrongStateException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
      75             :     virtual void SAL_CALL stateChanged( const lang::EventObject& aEvent, ::sal_Int32 nOldState, ::sal_Int32 nNewState )
      76             :                                     throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
      77             :     virtual void SAL_CALL queryClosing( const lang::EventObject& Source, sal_Bool GetsOwnership )
      78             :                                     throw (util::CloseVetoException, uno::RuntimeException, std::exception) SAL_OVERRIDE;
      79             :     virtual void SAL_CALL notifyClosing( const lang::EventObject& Source ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE;
      80             :     virtual void SAL_CALL notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
      81             :     virtual void SAL_CALL disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException, std::exception ) SAL_OVERRIDE;
      82             :     virtual void SAL_CALL modified( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
      83             : };
      84             : 
      85        1060 : EmbedEventListener_Impl* EmbedEventListener_Impl::Create( EmbeddedObjectRef* p )
      86             : {
      87        1060 :     EmbedEventListener_Impl* xRet = new EmbedEventListener_Impl( p );
      88        1060 :     xRet->acquire();
      89             : 
      90        1060 :     if ( p->GetObject().is() )
      91             :     {
      92        1046 :         p->GetObject()->addStateChangeListener( xRet );
      93             : 
      94        1046 :         uno::Reference < util::XCloseable > xClose( p->GetObject(), uno::UNO_QUERY );
      95             :         DBG_ASSERT( xClose.is(), "Object does not support XCloseable!" );
      96        1046 :         if ( xClose.is() )
      97        1046 :             xClose->addCloseListener( xRet );
      98             : 
      99        2092 :         uno::Reference < document::XEventBroadcaster > xBrd( p->GetObject(), uno::UNO_QUERY );
     100        1046 :         if ( xBrd.is() )
     101        1046 :             xBrd->addEventListener( xRet );
     102             : 
     103        1046 :         xRet->nState = p->GetObject()->getCurrentState();
     104        1046 :         if ( xRet->nState == embed::EmbedStates::RUNNING )
     105             :         {
     106         928 :             uno::Reference < util::XModifiable > xMod( p->GetObject()->getComponent(), uno::UNO_QUERY );
     107         928 :             if ( xMod.is() )
     108             :                 // listen for changes in running state (update replacements in case of changes)
     109         926 :                 xMod->addModifyListener( xRet );
     110        1046 :         }
     111             :     }
     112             : 
     113        1060 :     return xRet;
     114             : }
     115             : 
     116         200 : void SAL_CALL EmbedEventListener_Impl::changingState( const lang::EventObject&,
     117             :                                                     ::sal_Int32,
     118             :                                                     ::sal_Int32 )
     119             :     throw ( embed::WrongStateException,
     120             :             uno::RuntimeException, std::exception )
     121             : {
     122         200 : }
     123             : 
     124         194 : void SAL_CALL EmbedEventListener_Impl::stateChanged( const lang::EventObject&,
     125             :                                                     ::sal_Int32 nOldState,
     126             :                                                     ::sal_Int32 nNewState )
     127             :     throw ( uno::RuntimeException, std::exception )
     128             : {
     129         194 :     SolarMutexGuard aGuard;
     130         194 :     nState = nNewState;
     131         194 :     if ( !pObject )
     132         194 :         return;
     133             : 
     134         388 :     uno::Reference < util::XModifiable > xMod( pObject->GetObject()->getComponent(), uno::UNO_QUERY );
     135         194 :     if ( nNewState == embed::EmbedStates::RUNNING )
     136             :     {
     137             :         // TODO/LATER: container must be set before!
     138             :         // When is this event created? Who sets the new container when it changed?
     139          81 :         if( ( pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON ) && nOldState != embed::EmbedStates::LOADED && !pObject->IsChart() )
     140             :             // get new replacement after deactivation
     141           0 :             pObject->UpdateReplacement();
     142             : 
     143          81 :         if( pObject->IsChart() && nOldState == embed::EmbedStates::UI_ACTIVE )
     144             :         {
     145             :             //create a new metafile replacement when leaving the edit mode
     146             :             //for buggy documents where the old image looks different from the correct one
     147           1 :             if( xMod.is() && !xMod->isModified() )//in case of modification a new replacement will be requested anyhow
     148           0 :                 pObject->UpdateReplacementOnDemand();
     149             :         }
     150             : 
     151          81 :         if ( xMod.is() && nOldState == embed::EmbedStates::LOADED )
     152             :             // listen for changes (update replacements in case of changes)
     153          80 :             xMod->addModifyListener( this );
     154             :     }
     155         113 :     else if ( nNewState == embed::EmbedStates::LOADED )
     156             :     {
     157             :         // in loaded state we can't listen
     158         112 :         if ( xMod.is() )
     159           0 :             xMod->removeModifyListener( this );
     160         194 :     }
     161             : }
     162             : 
     163        6091 : void SAL_CALL EmbedEventListener_Impl::modified( const lang::EventObject& ) throw (uno::RuntimeException, std::exception)
     164             : {
     165        6091 :     SolarMutexGuard aGuard;
     166        6091 :     if ( pObject && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON )
     167             :     {
     168        5267 :         if ( nState == embed::EmbedStates::RUNNING )
     169             :         {
     170             :             // updates only necessary in non-active states
     171        5255 :             if( pObject->IsChart() )
     172         269 :                 pObject->UpdateReplacementOnDemand();
     173             :             else
     174        4986 :                 pObject->UpdateReplacement();
     175             :         }
     176          24 :         else if ( nState == embed::EmbedStates::ACTIVE ||
     177          12 :                   nState == embed::EmbedStates::UI_ACTIVE ||
     178           0 :                   nState == embed::EmbedStates::INPLACE_ACTIVE )
     179             :         {
     180             :             // in case the object is inplace or UI active the replacement image should be updated on demand
     181          12 :             pObject->UpdateReplacementOnDemand();
     182             :         }
     183        6091 :     }
     184        6091 : }
     185             : 
     186        8641 : void SAL_CALL EmbedEventListener_Impl::notifyEvent( const document::EventObject& aEvent ) throw( uno::RuntimeException, std::exception )
     187             : {
     188        8641 :     SolarMutexGuard aGuard;
     189             : 
     190        8641 :     if ( pObject && aEvent.EventName == "OnVisAreaChanged" && pObject->GetViewAspect() != embed::Aspects::MSOLE_ICON && !pObject->IsChart() )
     191             :     {
     192          14 :         pObject->UpdateReplacement();
     193        8641 :     }
     194        8641 : }
     195             : 
     196         150 : void SAL_CALL EmbedEventListener_Impl::queryClosing( const lang::EventObject& Source, sal_Bool )
     197             :         throw ( util::CloseVetoException, uno::RuntimeException, std::exception)
     198             : {
     199             :     // An embedded object can be shared between several objects (f.e. for undo purposes)
     200             :     // the object will not be closed before the last "customer" is destroyed
     201             :     // Now the EmbeddedObjectRef helper class works like a "lock" on the object
     202         150 :     if ( pObject && pObject->IsLocked() && Source.Source == pObject->GetObject() )
     203         150 :         throw util::CloseVetoException();
     204           0 : }
     205             : 
     206           0 : void SAL_CALL EmbedEventListener_Impl::notifyClosing( const lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception)
     207             : {
     208           0 :     if ( pObject && Source.Source == pObject->GetObject() )
     209             :     {
     210           0 :         pObject->Clear();
     211           0 :         pObject = 0;
     212             :     }
     213           0 : }
     214             : 
     215         999 : void SAL_CALL EmbedEventListener_Impl::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException, std::exception )
     216             : {
     217         999 :     if ( pObject && aEvent.Source == pObject->GetObject() )
     218             :     {
     219           0 :         pObject->Clear();
     220           0 :         pObject = 0;
     221             :     }
     222         999 : }
     223             : 
     224             : struct EmbeddedObjectRef_Impl
     225             : {
     226             :     uno::Reference <embed::XEmbeddedObject> mxObj;
     227             : 
     228             :     EmbedEventListener_Impl*                    xListener;
     229             :     OUString                             aPersistName;
     230             :     OUString                             aMediaType;
     231             :     comphelper::EmbeddedObjectContainer*        pContainer;
     232             :     Graphic*                                    pGraphic;
     233             :     sal_Int64                                   nViewAspect;
     234             :     bool                                        bIsLocked:1;
     235             :     bool                                        bNeedUpdate:1;
     236             : 
     237             :     // #i104867#
     238             :     sal_uInt32                                  mnGraphicVersion;
     239             :     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
     240             : 
     241         642 :     EmbeddedObjectRef_Impl() :
     242             :         xListener(0),
     243             :         pContainer(NULL),
     244             :         pGraphic(NULL),
     245             :         nViewAspect(embed::Aspects::MSOLE_CONTENT),
     246             :         bIsLocked(false),
     247             :         bNeedUpdate(false),
     248             :         mnGraphicVersion(0),
     249         642 :         aDefaultSizeForChart_In_100TH_MM(awt::Size(8000,7000))
     250         642 :     {}
     251             : 
     252         409 :     EmbeddedObjectRef_Impl( const EmbeddedObjectRef_Impl& r ) :
     253             :         mxObj(r.mxObj),
     254             :         xListener(0),
     255             :         aPersistName(r.aPersistName),
     256             :         aMediaType(r.aMediaType),
     257             :         pContainer(r.pContainer),
     258             :         pGraphic(NULL),
     259             :         nViewAspect(r.nViewAspect),
     260             :         bIsLocked(r.bIsLocked),
     261             :         bNeedUpdate(r.bNeedUpdate),
     262             :         mnGraphicVersion(0),
     263         409 :         aDefaultSizeForChart_In_100TH_MM(r.aDefaultSizeForChart_In_100TH_MM)
     264             :     {
     265         409 :         if (r.pGraphic && !r.bNeedUpdate)
     266         284 :             pGraphic = new Graphic(*r.pGraphic);
     267         409 :     }
     268             : 
     269        1045 :     ~EmbeddedObjectRef_Impl()
     270        1045 :     {
     271        1045 :         delete pGraphic;
     272        1045 :     }
     273             : };
     274             : 
     275        7513 : const uno::Reference <embed::XEmbeddedObject>& EmbeddedObjectRef::operator->() const
     276             : {
     277        7513 :     return mpImpl->mxObj;
     278             : }
     279             : 
     280       16023 : const uno::Reference <embed::XEmbeddedObject>& EmbeddedObjectRef::GetObject() const
     281             : {
     282       16023 :     return mpImpl->mxObj;
     283             : }
     284             : 
     285         507 : EmbeddedObjectRef::EmbeddedObjectRef() : mpImpl(new EmbeddedObjectRef_Impl) {}
     286             : 
     287         135 : EmbeddedObjectRef::EmbeddedObjectRef( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Int64 nAspect ) :
     288         135 :     mpImpl(new EmbeddedObjectRef_Impl)
     289             : {
     290         135 :     mpImpl->nViewAspect = nAspect;
     291         135 :     mpImpl->mxObj = xObj;
     292         135 :     mpImpl->xListener = EmbedEventListener_Impl::Create( this );
     293         135 : }
     294             : 
     295         409 : EmbeddedObjectRef::EmbeddedObjectRef( const EmbeddedObjectRef& rObj ) :
     296         409 :     mpImpl(new EmbeddedObjectRef_Impl(*rObj.mpImpl))
     297             : {
     298         409 :     mpImpl->xListener = EmbedEventListener_Impl::Create( this );
     299         409 : }
     300             : 
     301        1045 : EmbeddedObjectRef::~EmbeddedObjectRef()
     302             : {
     303        1045 :     Clear();
     304        1045 :     delete mpImpl;
     305        1045 : }
     306             : 
     307         516 : void EmbeddedObjectRef::Assign( const uno::Reference < embed::XEmbeddedObject >& xObj, sal_Int64 nAspect )
     308             : {
     309             :     DBG_ASSERT(!mpImpl->mxObj.is(), "Never assign an already assigned object!");
     310             : 
     311         516 :     Clear();
     312         516 :     mpImpl->nViewAspect = nAspect;
     313         516 :     mpImpl->mxObj = xObj;
     314         516 :     mpImpl->xListener = EmbedEventListener_Impl::Create( this );
     315             : 
     316             :     //#i103460#
     317         516 :     if ( IsChart() )
     318             :     {
     319         152 :         uno::Reference < chart2::XDefaultSizeTransmitter > xSizeTransmitter( xObj, uno::UNO_QUERY );
     320             :         DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
     321         152 :         if( xSizeTransmitter.is() )
     322         152 :             xSizeTransmitter->setDefaultSize( mpImpl->aDefaultSizeForChart_In_100TH_MM );
     323             :     }
     324         516 : }
     325             : 
     326        1996 : void EmbeddedObjectRef::Clear()
     327             : {
     328        1996 :     if (mpImpl->mxObj.is() && mpImpl->xListener)
     329             :     {
     330        1040 :         mpImpl->mxObj->removeStateChangeListener(mpImpl->xListener);
     331             : 
     332        1040 :         uno::Reference<util::XCloseable> xClose(mpImpl->mxObj, uno::UNO_QUERY);
     333        1040 :         if ( xClose.is() )
     334        1040 :             xClose->removeCloseListener( mpImpl->xListener );
     335             : 
     336        2080 :         uno::Reference<document::XEventBroadcaster> xBrd(mpImpl->mxObj, uno::UNO_QUERY);
     337        1040 :         if ( xBrd.is() )
     338        1040 :             xBrd->removeEventListener( mpImpl->xListener );
     339             : 
     340        1040 :         if ( mpImpl->bIsLocked )
     341             :         {
     342         486 :             if ( xClose.is() )
     343             :             {
     344             :                 try
     345             :                 {
     346         486 :                     mpImpl->mxObj->changeState(embed::EmbedStates::LOADED);
     347         486 :                     xClose->close( true );
     348             :                 }
     349          53 :                 catch (const util::CloseVetoException&)
     350             :                 {
     351             :                     // there's still someone who needs the object!
     352             :                 }
     353           0 :                 catch (const uno::Exception&)
     354             :                 {
     355             :                     OSL_FAIL( "Error on switching of the object to loaded state and closing!\n" );
     356             :                 }
     357             :             }
     358             :         }
     359             : 
     360        1040 :         if ( mpImpl->xListener )
     361             :         {
     362        1040 :             mpImpl->xListener->pObject = 0;
     363        1040 :             mpImpl->xListener->release();
     364        1040 :             mpImpl->xListener = 0;
     365             :         }
     366             : 
     367        1040 :         mpImpl->mxObj = NULL;
     368        2080 :         mpImpl->bNeedUpdate = false;
     369             :     }
     370             : 
     371        1996 :     mpImpl->pContainer = 0;
     372        1996 :     mpImpl->bIsLocked = false;
     373        1996 :     mpImpl->bNeedUpdate = false;
     374        1996 : }
     375             : 
     376        9817 : bool EmbeddedObjectRef::is() const
     377             : {
     378        9817 :     return mpImpl->mxObj.is();
     379             : }
     380             : 
     381         762 : void EmbeddedObjectRef::AssignToContainer( comphelper::EmbeddedObjectContainer* pContainer, const OUString& rPersistName )
     382             : {
     383         762 :     mpImpl->pContainer = pContainer;
     384         762 :     mpImpl->aPersistName = rPersistName;
     385             : 
     386         762 :     if ( mpImpl->pGraphic && !mpImpl->bNeedUpdate && pContainer )
     387         286 :         SetGraphicToContainer( *mpImpl->pGraphic, *pContainer, mpImpl->aPersistName, OUString() );
     388         762 : }
     389             : 
     390         198 : comphelper::EmbeddedObjectContainer* EmbeddedObjectRef::GetContainer() const
     391             : {
     392         198 :     return mpImpl->pContainer;
     393             : }
     394             : 
     395        7961 : sal_Int64 EmbeddedObjectRef::GetViewAspect() const
     396             : {
     397        7961 :     return mpImpl->nViewAspect;
     398             : }
     399             : 
     400         179 : void EmbeddedObjectRef::SetViewAspect( sal_Int64 nAspect )
     401             : {
     402         179 :     mpImpl->nViewAspect = nAspect;
     403         179 : }
     404             : 
     405         800 : void EmbeddedObjectRef::Lock( bool bLock )
     406             : {
     407         800 :     mpImpl->bIsLocked = bLock;
     408         800 : }
     409             : 
     410         150 : bool EmbeddedObjectRef::IsLocked() const
     411             : {
     412         150 :     return mpImpl->bIsLocked;
     413             : }
     414             : 
     415        5008 : void EmbeddedObjectRef::GetReplacement( bool bUpdate )
     416             : {
     417        5008 :     if ( bUpdate )
     418             :     {
     419        5000 :         DELETEZ( mpImpl->pGraphic );
     420        5000 :         mpImpl->aMediaType = OUString();
     421        5000 :         mpImpl->pGraphic = new Graphic;
     422        5000 :         mpImpl->mnGraphicVersion++;
     423             :     }
     424           8 :     else if ( !mpImpl->pGraphic )
     425             :     {
     426           8 :         mpImpl->pGraphic = new Graphic;
     427           8 :         mpImpl->mnGraphicVersion++;
     428             :     }
     429             :     else
     430             :     {
     431             :         OSL_FAIL("No update, but replacement exists already!");
     432        5008 :         return;
     433             :     }
     434             : 
     435        5008 :     SvStream* pGraphicStream = GetGraphicStream( bUpdate );
     436        5008 :     if ( pGraphicStream )
     437             :     {
     438        5008 :         GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
     439        5008 :         if( mpImpl->pGraphic )
     440        5008 :             rGF.ImportGraphic( *mpImpl->pGraphic, OUString(), *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
     441        5008 :         mpImpl->mnGraphicVersion++;
     442        5008 :         delete pGraphicStream;
     443             :     }
     444             : }
     445             : 
     446          72 : const Graphic* EmbeddedObjectRef::GetGraphic( OUString* pMediaType ) const
     447             : {
     448             :     try
     449             :     {
     450          72 :         if ( mpImpl->bNeedUpdate )
     451             :             // bNeedUpdate will be set to false while retrieving new replacement
     452           0 :             const_cast < EmbeddedObjectRef* >(this)->GetReplacement(true);
     453          72 :         else if ( !mpImpl->pGraphic )
     454           8 :             const_cast < EmbeddedObjectRef* >(this)->GetReplacement(false);
     455             :     }
     456           0 :     catch( const uno::Exception& ex )
     457             :     {
     458             :         SAL_WARN("svtools.misc", "Something went wrong on getting the graphic: " << ex.Message);
     459             :     }
     460             : 
     461          72 :     if ( mpImpl->pGraphic && pMediaType )
     462           0 :         *pMediaType = mpImpl->aMediaType;
     463          72 :     return mpImpl->pGraphic;
     464             : }
     465             : 
     466         253 : Size EmbeddedObjectRef::GetSize( MapMode* pTargetMapMode ) const
     467             : {
     468         253 :     MapMode aSourceMapMode( MAP_100TH_MM );
     469         253 :     Size aResult;
     470             : 
     471         253 :     if ( mpImpl->nViewAspect == embed::Aspects::MSOLE_ICON )
     472             :     {
     473           0 :         const Graphic* pGraphic = GetGraphic();
     474           0 :         if ( pGraphic )
     475             :         {
     476           0 :             aSourceMapMode = pGraphic->GetPrefMapMode();
     477           0 :             aResult = pGraphic->GetPrefSize();
     478             :         }
     479             :         else
     480           0 :             aResult = Size( 2500, 2500 );
     481             :     }
     482             :     else
     483             :     {
     484         253 :         awt::Size aSize;
     485             : 
     486         253 :         if (mpImpl->mxObj.is())
     487             :         {
     488             :             try
     489             :             {
     490         253 :                 aSize = mpImpl->mxObj->getVisualAreaSize(mpImpl->nViewAspect);
     491             :             }
     492          13 :             catch(const embed::NoVisualAreaSizeException&)
     493             :             {
     494             :             }
     495           1 :             catch(const uno::Exception&)
     496             :             {
     497             :                 OSL_FAIL( "Something went wrong on getting of the size of the object!" );
     498             :             }
     499             : 
     500             :             try
     501             :             {
     502         253 :                 aSourceMapMode = VCLUnoHelper::UnoEmbed2VCLMapUnit(mpImpl->mxObj->getMapUnit(mpImpl->nViewAspect));
     503             :             }
     504           1 :             catch(const uno::Exception&)
     505             :             {
     506             :                 OSL_FAIL( "Can not get the map mode!" );
     507             :             }
     508             :         }
     509             : 
     510         253 :         if ( !aSize.Height && !aSize.Width )
     511             :         {
     512          68 :             aSize.Width = 5000;
     513          68 :             aSize.Height = 5000;
     514             :         }
     515             : 
     516         253 :         aResult = Size( aSize.Width, aSize.Height );
     517             :     }
     518             : 
     519         253 :     if ( pTargetMapMode )
     520         253 :         aResult = OutputDevice::LogicToLogic( aResult, aSourceMapMode, *pTargetMapMode );
     521             : 
     522         253 :     return aResult;
     523             : }
     524             : 
     525           0 : void EmbeddedObjectRef::SetGraphicStream( const uno::Reference< io::XInputStream >& xInGrStream,
     526             :                                             const OUString& rMediaType )
     527             : {
     528           0 :     if ( mpImpl->pGraphic )
     529           0 :         delete mpImpl->pGraphic;
     530           0 :     mpImpl->pGraphic = new Graphic();
     531           0 :     mpImpl->aMediaType = rMediaType;
     532           0 :     mpImpl->mnGraphicVersion++;
     533             : 
     534           0 :     SvStream* pGraphicStream = ::utl::UcbStreamHelper::CreateStream( xInGrStream );
     535             : 
     536           0 :     if ( pGraphicStream )
     537             :     {
     538           0 :         GraphicFilter& rGF = GraphicFilter::GetGraphicFilter();
     539           0 :         rGF.ImportGraphic( *mpImpl->pGraphic, "", *pGraphicStream, GRFILTER_FORMAT_DONTKNOW );
     540           0 :         mpImpl->mnGraphicVersion++;
     541             : 
     542           0 :         if ( mpImpl->pContainer )
     543             :         {
     544           0 :             pGraphicStream->Seek( 0 );
     545           0 :             uno::Reference< io::XInputStream > xInSeekGrStream = new ::utl::OSeekableInputStreamWrapper( pGraphicStream );
     546             : 
     547           0 :             mpImpl->pContainer->InsertGraphicStream( xInSeekGrStream, mpImpl->aPersistName, rMediaType );
     548             :         }
     549             : 
     550           0 :         delete pGraphicStream;
     551             :     }
     552             : 
     553           0 :     mpImpl->bNeedUpdate = false;
     554             : 
     555           0 : }
     556             : 
     557          40 : void EmbeddedObjectRef::SetGraphic( const Graphic& rGraphic, const OUString& rMediaType )
     558             : {
     559          40 :     if ( mpImpl->pGraphic )
     560           0 :         delete mpImpl->pGraphic;
     561          40 :     mpImpl->pGraphic = new Graphic( rGraphic );
     562          40 :     mpImpl->aMediaType = rMediaType;
     563          40 :     mpImpl->mnGraphicVersion++;
     564             : 
     565          40 :     if ( mpImpl->pContainer )
     566          22 :         SetGraphicToContainer( rGraphic, *mpImpl->pContainer, mpImpl->aPersistName, rMediaType );
     567             : 
     568          40 :     mpImpl->bNeedUpdate = false;
     569          40 : }
     570             : 
     571        5008 : SvStream* EmbeddedObjectRef::GetGraphicStream( bool bUpdate ) const
     572             : {
     573             :     DBG_ASSERT( bUpdate || mpImpl->pContainer, "Can't retrieve current graphic!" );
     574        5008 :     uno::Reference < io::XInputStream > xStream;
     575        5008 :     if ( mpImpl->pContainer && !bUpdate )
     576             :     {
     577             :         SAL_INFO( "svtools.misc", "getting stream from container" );
     578             :         // try to get graphic stream from container storage
     579           8 :         xStream = mpImpl->pContainer->GetGraphicStream(mpImpl->mxObj, &mpImpl->aMediaType);
     580           8 :         if ( xStream.is() )
     581             :         {
     582           8 :             const sal_Int32 nConstBufferSize = 32000;
     583           8 :             SvStream *pStream = new SvMemoryStream( 32000, 32000 );
     584             :             try
     585             :             {
     586           8 :                 sal_Int32 nRead=0;
     587           8 :                 uno::Sequence < sal_Int8 > aSequence ( nConstBufferSize );
     588           8 :                 do
     589             :                 {
     590           8 :                     nRead = xStream->readBytes ( aSequence, nConstBufferSize );
     591           8 :                     pStream->Write( aSequence.getConstArray(), nRead );
     592             :                 }
     593             :                 while ( nRead == nConstBufferSize );
     594           8 :                 pStream->Seek(0);
     595           8 :                 return pStream;
     596             :             }
     597           0 :             catch (const uno::Exception& ex)
     598             :             {
     599             :                 SAL_WARN("svtools.misc", "discarding broken embedded object preview: " << ex.Message);
     600           0 :                 delete pStream;
     601           0 :                 xStream.clear();
     602             :             }
     603             :         }
     604             :     }
     605             : 
     606        5000 :     if ( !xStream.is() )
     607             :     {
     608             :         SAL_INFO( "svtools.misc", "getting stream from object" );
     609             :         // update wanted or no stream in container storage available
     610        5000 :         xStream = GetGraphicReplacementStream(mpImpl->nViewAspect, mpImpl->mxObj, &mpImpl->aMediaType);
     611             : 
     612        5000 :         if ( xStream.is() )
     613             :         {
     614        5000 :             if ( mpImpl->pContainer )
     615         552 :                 mpImpl->pContainer->InsertGraphicStream( xStream, mpImpl->aPersistName, mpImpl->aMediaType );
     616             : 
     617        5000 :             SvStream* pResult = ::utl::UcbStreamHelper::CreateStream( xStream );
     618        5000 :             if ( pResult && bUpdate )
     619        5000 :                 mpImpl->bNeedUpdate = false;
     620             : 
     621        5000 :             return pResult;
     622             :         }
     623             :     }
     624             : 
     625           0 :     return NULL;
     626             : }
     627             : 
     628           0 : void EmbeddedObjectRef::DrawPaintReplacement( const Rectangle &rRect, const OUString &rText, OutputDevice *pOut )
     629             : {
     630           0 :     MapMode aMM( MAP_APPFONT );
     631           0 :     Size aAppFontSz = pOut->LogicToLogic( Size( 0, 8 ), &aMM, NULL );
     632           0 :     Font aFnt( OUString("Helvetica"), aAppFontSz );
     633           0 :     aFnt.SetTransparent( true );
     634           0 :     aFnt.SetColor( Color( COL_LIGHTRED ) );
     635           0 :     aFnt.SetWeight( WEIGHT_BOLD );
     636           0 :     aFnt.SetFamily( FAMILY_SWISS );
     637             : 
     638           0 :     pOut->Push();
     639           0 :     pOut->SetBackground();
     640           0 :     pOut->SetFont( aFnt );
     641             : 
     642           0 :     Point aPt;
     643             : 
     644             :     // Now scale text such that it fits in the rectangle
     645             :     // We start with the default size and decrease 1-AppFont
     646           0 :     for( sal_uInt16 i = 8; i > 2; i-- )
     647             :     {
     648           0 :         aPt.X() = (rRect.GetWidth()  - pOut->GetTextWidth( rText )) / 2;
     649           0 :         aPt.Y() = (rRect.GetHeight() - pOut->GetTextHeight()) / 2;
     650             : 
     651           0 :         bool bTiny = false;
     652           0 :         if( aPt.X() < 0 ) bTiny = true, aPt.X() = 0;
     653           0 :         if( aPt.Y() < 0 ) bTiny = true, aPt.Y() = 0;
     654           0 :         if( bTiny )
     655             :         {
     656             :             // decrease for small images
     657           0 :             aFnt.SetSize( Size( 0, aAppFontSz.Height() * i / 8 ) );
     658           0 :             pOut->SetFont( aFnt );
     659             :         }
     660             :         else
     661           0 :             break;
     662             :     }
     663             : 
     664           0 :     Bitmap aBmp( SvtResId( BMP_PLUGIN ) );
     665           0 :     long nHeight = rRect.GetHeight() - pOut->GetTextHeight();
     666           0 :     long nWidth = rRect.GetWidth();
     667           0 :     if(nHeight > 0 && nWidth > 0 && aBmp.GetSizePixel().Width() > 0)
     668             :     {
     669           0 :         aPt.Y() = nHeight;
     670           0 :         Point   aP = rRect.TopLeft();
     671           0 :         Size    aBmpSize = aBmp.GetSizePixel();
     672             :         // fit bitmap in
     673           0 :         if( nHeight * 10 / nWidth
     674           0 :           > aBmpSize.Height() * 10 / aBmpSize.Width() )
     675             :         {
     676             :             // adjust to the width
     677             :             // keep proportions
     678           0 :             long nH = nWidth * aBmpSize.Height() / aBmpSize.Width();
     679             :             // center
     680           0 :             aP.Y() += (nHeight - nH) / 2;
     681           0 :             nHeight = nH;
     682             :         }
     683             :         else
     684             :         {
     685             :             // adjust to the height
     686             :             // keep proportions
     687           0 :             long nW = nHeight * aBmpSize.Width() / aBmpSize.Height();
     688             :             // center
     689           0 :             aP.X() += (nWidth - nW) / 2;
     690           0 :             nWidth = nW;
     691             :         }
     692             : 
     693           0 :         pOut->DrawBitmap( aP, Size( nWidth, nHeight ), aBmp );
     694             :     }
     695             : 
     696           0 :     pOut->IntersectClipRegion( rRect );
     697           0 :     aPt += rRect.TopLeft();
     698           0 :     pOut->DrawText( aPt, rText );
     699           0 :     pOut->Pop();
     700           0 : }
     701             : 
     702           0 : void EmbeddedObjectRef::DrawShading( const Rectangle &rRect, OutputDevice *pOut )
     703             : {
     704           0 :     GDIMetaFile * pMtf = pOut->GetConnectMetaFile();
     705           0 :     if( pMtf && pMtf->IsRecord() )
     706           0 :         return;
     707             : 
     708           0 :     pOut->Push();
     709           0 :     pOut->SetLineColor( Color( COL_BLACK ) );
     710             : 
     711           0 :     Size aPixSize = pOut->LogicToPixel( rRect.GetSize() );
     712           0 :     aPixSize.Width() -= 1;
     713           0 :     aPixSize.Height() -= 1;
     714           0 :     Point aPixViewPos = pOut->LogicToPixel( rRect.TopLeft() );
     715           0 :     sal_Int32 nMax = aPixSize.Width() + aPixSize.Height();
     716           0 :     for( sal_Int32 i = 5; i < nMax; i += 5 )
     717             :     {
     718           0 :         Point a1( aPixViewPos ), a2( aPixViewPos );
     719           0 :         if( i > aPixSize.Width() )
     720           0 :             a1 += Point( aPixSize.Width(), i - aPixSize.Width() );
     721             :         else
     722           0 :             a1 += Point( i, 0 );
     723           0 :         if( i > aPixSize.Height() )
     724           0 :             a2 += Point( i - aPixSize.Height(), aPixSize.Height() );
     725             :         else
     726           0 :             a2 += Point( 0, i );
     727             : 
     728           0 :         pOut->DrawLine( pOut->PixelToLogic( a1 ), pOut->PixelToLogic( a2 ) );
     729             :     }
     730             : 
     731           0 :     pOut->Pop();
     732             : 
     733             : }
     734             : 
     735         918 : bool EmbeddedObjectRef::TryRunningState( const uno::Reference < embed::XEmbeddedObject >& xEmbObj )
     736             : {
     737         918 :     if ( !xEmbObj.is() )
     738           0 :         return false;
     739             : 
     740             :     try
     741             :     {
     742         918 :         if ( xEmbObj->getCurrentState() == embed::EmbedStates::LOADED )
     743          42 :             xEmbObj->changeState( embed::EmbedStates::RUNNING );
     744             :     }
     745          14 :     catch (const uno::Exception&)
     746             :     {
     747           7 :         return false;
     748             :     }
     749             : 
     750         911 :     return true;
     751             : }
     752             : 
     753         322 : void EmbeddedObjectRef::SetGraphicToContainer( const Graphic& rGraphic,
     754             :                                                 comphelper::EmbeddedObjectContainer& aContainer,
     755             :                                                 const OUString& aName,
     756             :                                                 const OUString& aMediaType )
     757             : {
     758         322 :     SvMemoryStream aStream;
     759         322 :     aStream.SetVersion( SOFFICE_FILEFORMAT_CURRENT );
     760         322 :     if ( rGraphic.ExportNative( aStream ) )
     761             :     {
     762         322 :         aStream.Seek( 0 );
     763             : 
     764         322 :            uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( aStream );
     765         322 :            aContainer.InsertGraphicStream( xStream, aName, aMediaType );
     766             :     }
     767             :     else
     768         322 :         OSL_FAIL( "Export of graphic is failed!\n" );
     769         322 : }
     770             : 
     771        5000 : uno::Reference< io::XInputStream > EmbeddedObjectRef::GetGraphicReplacementStream(
     772             :                                                                 sal_Int64 nViewAspect,
     773             :                                                                 const uno::Reference< embed::XEmbeddedObject >& xObj,
     774             :                                                                 OUString* pMediaType )
     775             :     throw()
     776             : {
     777        5000 :     return ::comphelper::EmbeddedObjectContainer::GetGraphicReplacementStream(nViewAspect,xObj,pMediaType);
     778             : }
     779             : 
     780        5000 : void EmbeddedObjectRef::UpdateReplacement()
     781             : {
     782        5000 :     GetReplacement( true );
     783        5000 : }
     784             : 
     785         281 : void EmbeddedObjectRef::UpdateReplacementOnDemand()
     786             : {
     787         281 :     DELETEZ( mpImpl->pGraphic );
     788         281 :     mpImpl->bNeedUpdate = true;
     789         281 :     mpImpl->mnGraphicVersion++;
     790             : 
     791         281 :     if( mpImpl->pContainer )
     792             :     {
     793             :         //remove graphic from container thus a new up to date one is requested on save
     794         274 :         mpImpl->pContainer->RemoveGraphicStream( mpImpl->aPersistName );
     795             :     }
     796         281 : }
     797             : 
     798        6137 : bool EmbeddedObjectRef::IsChart() const
     799             : {
     800             :     //todo maybe for 3.0:
     801             :     //if the changes work good for chart
     802             :     //we should apply them for all own ole objects
     803             : 
     804             :     //#i83708# #i81857# #i79578# request an ole replacement image only if really necessary
     805             :     //as this call can be very expensive and does block the user interface as long at it takes
     806             : 
     807        6137 :     if (!mpImpl->mxObj.is())
     808          14 :         return false;
     809             : 
     810        6123 :     SvGlobalName aObjClsId(mpImpl->mxObj->getClassID());
     811       12246 :     if(
     812       24492 :         SvGlobalName(SO3_SCH_CLASSID_30) == aObjClsId
     813       12246 :         || SvGlobalName(SO3_SCH_CLASSID_40) == aObjClsId
     814       12246 :         || SvGlobalName(SO3_SCH_CLASSID_50) == aObjClsId
     815       30615 :         || SvGlobalName(SO3_SCH_CLASSID_60) == aObjClsId)
     816             :     {
     817         771 :         return true;
     818             :     }
     819             : 
     820        5352 :     return false;
     821             : }
     822             : 
     823             : // MT: Only used for getting accessible attributes, which are not localized
     824           0 : OUString EmbeddedObjectRef::GetChartType()
     825             : {
     826           0 :     OUString Style;
     827           0 :     if ( mpImpl->mxObj.is() )
     828             :     {
     829           0 :         if ( IsChart() )
     830             :         {
     831           0 :             if ( svt::EmbeddedObjectRef::TryRunningState( mpImpl->mxObj ) )
     832             :             {
     833           0 :                 uno::Reference< chart2::XChartDocument > xChart( mpImpl->mxObj->getComponent(), uno::UNO_QUERY );
     834           0 :                 if (xChart.is())
     835             :                 {
     836           0 :                     uno::Reference< chart2::XDiagram > xDiagram( xChart->getFirstDiagram());
     837           0 :                     if( ! xDiagram.is())
     838           0 :                         return OUString();
     839           0 :                     uno::Reference< chart2::XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY_THROW );
     840           0 :                     uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > aCooSysSeq( xCooSysCnt->getCoordinateSystems());
     841             :                     // IA2 CWS. Unused: int nCoordinateCount = aCooSysSeq.getLength();
     842           0 :                     sal_Bool bGetChartType = sal_False;
     843           0 :                     for( sal_Int32 nCooSysIdx=0; nCooSysIdx<aCooSysSeq.getLength(); ++nCooSysIdx )
     844             :                     {
     845           0 :                         uno::Reference< chart2::XChartTypeContainer > xCTCnt( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY_THROW );
     846           0 :                         uno::Sequence< uno::Reference< chart2::XChartType > > aChartTypes( xCTCnt->getChartTypes());
     847           0 :                         int nDimesionCount = aCooSysSeq[nCooSysIdx]->getDimension();
     848           0 :                         if( nDimesionCount == 3 )
     849           0 :                             Style += "3D ";
     850             :                         else
     851           0 :                             Style += "2D ";
     852           0 :                         for( sal_Int32 nCTIdx=0; nCTIdx<aChartTypes.getLength(); ++nCTIdx )
     853             :                         {
     854           0 :                             OUString strChartType = aChartTypes[nCTIdx]->getChartType();
     855           0 :                             if (strChartType == "com.sun.star.chart2.AreaChartType")
     856             :                             {
     857           0 :                                 Style += "Areas";
     858           0 :                                 bGetChartType = sal_True;
     859             :                             }
     860           0 :                             else if (strChartType == "com.sun.star.chart2.BarChartType")
     861             :                             {
     862           0 :                                 Style += "Bars";
     863           0 :                                 bGetChartType = sal_True;
     864             :                             }
     865           0 :                             else if (strChartType == "com.sun.star.chart2.ColumnChartType")
     866             :                             {
     867           0 :                                 uno::Reference< beans::XPropertySet > xProp( aCooSysSeq[nCooSysIdx], uno::UNO_QUERY );
     868           0 :                                 if( xProp.is())
     869             :                                 {
     870           0 :                                     bool bCurrent = false;
     871           0 :                                     if( xProp->getPropertyValue( OUString("SwapXAndYAxis") ) >>= bCurrent )
     872             :                                     {
     873           0 :                                         if (bCurrent)
     874           0 :                                             Style += "Bars";
     875             :                                         else
     876           0 :                                             Style += "Columns";
     877           0 :                                         bGetChartType = sal_True;
     878             :                                     }
     879           0 :                                 }
     880             :                             }
     881           0 :                             else if (strChartType == "com.sun.star.chart2.LineChartType")
     882             :                             {
     883           0 :                                 Style += "Lines";
     884           0 :                                 bGetChartType = sal_True;
     885             :                             }
     886           0 :                             else if (strChartType == "com.sun.star.chart2.ScatterChartType")
     887             :                             {
     888           0 :                                 Style += "XY Chart";
     889           0 :                                 bGetChartType = sal_True;
     890             :                             }
     891           0 :                             else if (strChartType == "com.sun.star.chart2.PieChartType")
     892             :                             {
     893           0 :                                 Style += "Pies";
     894           0 :                                 bGetChartType = sal_True;
     895             :                             }
     896           0 :                             else if (strChartType == "com.sun.star.chart2.NetChartType")
     897             :                             {
     898           0 :                                 Style += "Radar";
     899           0 :                                 bGetChartType = sal_True;
     900             :                             }
     901           0 :                             else if (strChartType == "com.sun.star.chart2.CandleStickChartType")
     902             :                             {
     903           0 :                                 Style += "Candle Stick Chart";
     904           0 :                                 bGetChartType = sal_True;
     905             :                             }
     906           0 :                             if (bGetChartType)
     907           0 :                                 return Style;
     908           0 :                         }
     909           0 :                     }
     910           0 :                 }
     911             :             }
     912             :         }
     913             :     }
     914           0 :     return Style;
     915             : }
     916             : 
     917             : // #i104867#
     918          55 : sal_uInt32 EmbeddedObjectRef::getGraphicVersion() const
     919             : {
     920          55 :     return mpImpl->mnGraphicVersion;
     921             : }
     922             : 
     923          31 : void EmbeddedObjectRef::SetDefaultSizeForChart( const Size& rSizeIn_100TH_MM )
     924             : {
     925             :     //#i103460# charts do not necessaryly have an own size within ODF files,
     926             :     //for this case they need to use the size settings from the surrounding frame,
     927             :     //which is made available with this method
     928             : 
     929          31 :     mpImpl->aDefaultSizeForChart_In_100TH_MM = awt::Size( rSizeIn_100TH_MM.getWidth(), rSizeIn_100TH_MM.getHeight() );
     930             : 
     931          31 :     uno::Reference<chart2::XDefaultSizeTransmitter> xSizeTransmitter(mpImpl->mxObj, uno::UNO_QUERY);
     932             :     DBG_ASSERT( xSizeTransmitter.is(), "Object does not support XDefaultSizeTransmitter -> will cause #i103460#!" );
     933          31 :     if( xSizeTransmitter.is() )
     934          31 :         xSizeTransmitter->setDefaultSize( mpImpl->aDefaultSizeForChart_In_100TH_MM );
     935          31 : }
     936             : 
     937             : } // namespace svt
     938             : 
     939             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10