LCOV - code coverage report
Current view: top level - sfx2/source/appl - linksrc.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 132 195 67.7 %
Date: 2014-04-11 Functions: 31 46 67.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <sfx2/linksrc.hxx>
      22             : #include <sfx2/lnkbase.hxx>
      23             : #include <com/sun/star/uno/Any.hxx>
      24             : #include <com/sun/star/uno/Sequence.hxx>
      25             : 
      26             : #include <vcl/timer.hxx>
      27             : #include <vector>
      28             : #include <algorithm>
      29             : 
      30             : 
      31             : using namespace ::com::sun::star::uno;
      32             : 
      33             : namespace sfx2
      34             : {
      35             : 
      36           4 : TYPEINIT0( SvLinkSource )
      37             : 
      38           0 : class SvLinkSourceTimer : public Timer
      39             : {
      40             :     SvLinkSource *  pOwner;
      41             :     virtual void    Timeout() SAL_OVERRIDE;
      42             : public:
      43             :             SvLinkSourceTimer( SvLinkSource * pOwn );
      44             : };
      45             : 
      46           0 : SvLinkSourceTimer::SvLinkSourceTimer( SvLinkSource * pOwn )
      47           0 :     : pOwner( pOwn )
      48             : {
      49           0 : }
      50             : 
      51           0 : void SvLinkSourceTimer::Timeout()
      52             : {
      53             :     // Secure against beeing destroyed in Handler
      54           0 :     SvLinkSourceRef aAdv( pOwner );
      55           0 :     pOwner->SendDataChanged();
      56           0 : }
      57             : 
      58           0 : static void StartTimer( SvLinkSourceTimer ** ppTimer, SvLinkSource * pOwner,
      59             :                         sal_uIntPtr nTimeout )
      60             : {
      61           0 :     if( !*ppTimer )
      62             :     {
      63           0 :         *ppTimer = new SvLinkSourceTimer( pOwner );
      64           0 :         (*ppTimer)->SetTimeout( nTimeout );
      65           0 :         (*ppTimer)->Start();
      66             :     }
      67           0 : }
      68             : 
      69             : 
      70             : struct SvLinkSource_Entry_Impl
      71             : {
      72             :     SvBaseLinkRef       xSink;
      73             :     OUString            aDataMimeType;
      74             :     sal_uInt16          nAdviseModes;
      75             :     bool            bIsDataSink;
      76             : 
      77          47 :     SvLinkSource_Entry_Impl( SvBaseLink* pLink, const OUString& rMimeType,
      78             :                                 sal_uInt16 nAdvMode )
      79             :         : xSink( pLink ), aDataMimeType( rMimeType ),
      80          47 :             nAdviseModes( nAdvMode ), bIsDataSink( true )
      81          47 :     {}
      82             : 
      83           1 :     SvLinkSource_Entry_Impl( SvBaseLink* pLink )
      84           1 :         : xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( false )
      85           1 :     {}
      86             : 
      87             :     ~SvLinkSource_Entry_Impl();
      88             : };
      89             : 
      90          45 : SvLinkSource_Entry_Impl::~SvLinkSource_Entry_Impl()
      91             : {
      92          45 : }
      93             : 
      94         157 : class SvLinkSource_Array_Impl : public std::vector<SvLinkSource_Entry_Impl*>
      95             : {
      96             : public:
      97          45 :     void DeleteAndDestroy(SvLinkSource_Entry_Impl* p)
      98             :     {
      99          45 :         iterator it = std::find(begin(), end(), p);
     100          45 :         if (it != end())
     101             :         {
     102          45 :             erase(it);
     103          45 :             delete p;
     104             :         }
     105          45 :     }
     106             : 
     107         154 :     ~SvLinkSource_Array_Impl()
     108         154 :     {
     109         154 :         for(const_iterator it = begin(); it != end(); ++it)
     110           0 :             delete *it;
     111         154 :     }
     112             : };
     113             : 
     114             : class SvLinkSource_EntryIter_Impl
     115             : {
     116             :     SvLinkSource_Array_Impl aArr;
     117             :     const SvLinkSource_Array_Impl& rOrigArr;
     118             :     sal_uInt16 nPos;
     119             : public:
     120             :     SvLinkSource_EntryIter_Impl( const SvLinkSource_Array_Impl& rArr );
     121             :     ~SvLinkSource_EntryIter_Impl();
     122         104 :     SvLinkSource_Entry_Impl* Curr()
     123         104 :                             { return nPos < aArr.size() ? aArr[ nPos ] : 0; }
     124             :     SvLinkSource_Entry_Impl* Next();
     125             :     bool IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry );
     126             : };
     127             : 
     128         104 : SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl(
     129             :         const SvLinkSource_Array_Impl& rArr )
     130         104 :     : aArr( rArr ), rOrigArr( rArr ), nPos( 0 )
     131             : {
     132         104 : }
     133         208 : SvLinkSource_EntryIter_Impl::~SvLinkSource_EntryIter_Impl()
     134             : {
     135         104 :     aArr.clear();
     136         104 : }
     137             : 
     138          13 : bool SvLinkSource_EntryIter_Impl::IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry )
     139             : {
     140          26 :     return ( nPos < aArr.size() && aArr[nPos] == pEntry
     141          39 :        && std::find( rOrigArr.begin(), rOrigArr.end(), pEntry ) != rOrigArr.end() );
     142             : }
     143             : 
     144          60 : SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next()
     145             : {
     146          60 :     SvLinkSource_Entry_Impl* pRet = 0;
     147          60 :     if( nPos + 1 < (sal_uInt16)aArr.size() )
     148             :     {
     149           2 :         ++nPos;
     150           3 :         if( rOrigArr.size() == aArr.size() &&
     151           1 :             rOrigArr[ nPos ] == aArr[ nPos ] )
     152           1 :             pRet = aArr[ nPos ];
     153             :         else
     154             :         {
     155             :             // then we must search the current (or the next) in the orig
     156           1 :             do {
     157           1 :                 pRet = aArr[ nPos ];
     158           1 :                 if( std::find(rOrigArr.begin(), rOrigArr.end(), pRet ) != rOrigArr.end() )
     159           0 :                     break;
     160           1 :                 pRet = 0;
     161           1 :                 ++nPos;
     162           1 :             } while( nPos < aArr.size() );
     163             : 
     164           1 :             if( nPos >= aArr.size() )
     165           1 :                 pRet = 0;
     166             :         }
     167             :     }
     168          60 :     return pRet;
     169             : }
     170             : 
     171             : struct SvLinkSource_Impl
     172             : {
     173             :     SvLinkSource_Array_Impl aArr;
     174             :     OUString                aDataMimeType;
     175             :     SvLinkSourceTimer *     pTimer;
     176             :     sal_uIntPtr             nTimeout;
     177             :     css::uno::Reference<css::io::XInputStream>
     178             :                            m_xInputStreamToLoadFrom;
     179             :     bool               m_bIsReadOnly;
     180             : 
     181          53 :     SvLinkSource_Impl()
     182             :         : pTimer(0)
     183             :         , nTimeout(3000)
     184          53 :         , m_bIsReadOnly(false)
     185             :     {
     186          53 :     }
     187             :     ~SvLinkSource_Impl();
     188             : };
     189             : 
     190         100 : SvLinkSource_Impl::~SvLinkSource_Impl()
     191             : {
     192          50 :     delete pTimer;
     193          50 : }
     194             : 
     195          53 : SvLinkSource::SvLinkSource()
     196          53 :      : pImpl( new SvLinkSource_Impl )
     197             : {
     198          53 : }
     199             : 
     200         100 : SvLinkSource::~SvLinkSource()
     201             : {
     202          50 :     delete pImpl;
     203          50 : }
     204             : 
     205             : 
     206           6 : SvLinkSource::StreamToLoadFrom SvLinkSource::getStreamToLoadFrom()
     207             : {
     208             :     return StreamToLoadFrom(
     209             :         pImpl->m_xInputStreamToLoadFrom,
     210           6 :         pImpl->m_bIsReadOnly);
     211             : }
     212             : 
     213          41 : void SvLinkSource::setStreamToLoadFrom(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream, bool bIsReadOnly )
     214             : {
     215          41 :     pImpl->m_xInputStreamToLoadFrom = xInputStream;
     216          41 :     pImpl->m_bIsReadOnly = bIsReadOnly;
     217          41 : }
     218             : 
     219             : // #i88291#
     220           0 : void SvLinkSource::clearStreamToLoadFrom()
     221             : {
     222           0 :     pImpl->m_xInputStreamToLoadFrom.clear();
     223           0 : }
     224             : 
     225           1 : void  SvLinkSource::Closed()
     226             : {
     227           1 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     228           2 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     229           1 :         if( !p->bIsDataSink )
     230           2 :             p->xSink->Closed();
     231           1 : }
     232             : 
     233           1 : sal_uIntPtr SvLinkSource::GetUpdateTimeout() const
     234             : {
     235           1 :     return pImpl->nTimeout;
     236             : }
     237             : 
     238          43 : void SvLinkSource::SetUpdateTimeout( sal_uIntPtr nTimeout )
     239             : {
     240          43 :     pImpl->nTimeout = nTimeout;
     241          43 :     if( pImpl->pTimer )
     242           0 :         pImpl->pTimer->SetTimeout( nTimeout );
     243          43 : }
     244             : 
     245           0 : void SvLinkSource::SendDataChanged()
     246             : {
     247           0 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     248           0 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     249             :     {
     250           0 :         if( p->bIsDataSink )
     251             :         {
     252           0 :             OUString sDataMimeType( pImpl->aDataMimeType );
     253           0 :             if( sDataMimeType.isEmpty() )
     254           0 :                 sDataMimeType = p->aDataMimeType;
     255             : 
     256           0 :             Any aVal;
     257           0 :             if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
     258           0 :                 GetData( aVal, sDataMimeType, true ) )
     259             :             {
     260           0 :                 p->xSink->DataChanged( sDataMimeType, aVal );
     261             : 
     262           0 :                 if ( !aIter.IsValidCurrValue( p ) )
     263           0 :                     continue;
     264             : 
     265           0 :                 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
     266             :                 {
     267           0 :                     pImpl->aArr.DeleteAndDestroy( p );
     268             :                 }
     269             : 
     270           0 :             }
     271             :         }
     272             :     }
     273           0 :     if( pImpl->pTimer )
     274             :     {
     275           0 :         delete pImpl->pTimer;
     276           0 :         pImpl->pTimer = NULL;
     277             :     }
     278           0 :     pImpl->aDataMimeType = "";
     279           0 : }
     280             : 
     281           6 : void SvLinkSource::NotifyDataChanged()
     282             : {
     283           6 :     if( pImpl->nTimeout )
     284           0 :         StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
     285             :     else
     286             :     {
     287           6 :         SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     288          12 :         for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     289           6 :             if( p->bIsDataSink )
     290             :             {
     291           6 :                 Any aVal;
     292          12 :                 if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
     293           6 :                     GetData( aVal, p->aDataMimeType, true ) )
     294             :                 {
     295           6 :                     p->xSink->DataChanged( p->aDataMimeType, aVal );
     296             : 
     297           6 :                     if ( !aIter.IsValidCurrValue( p ) )
     298           0 :                         continue;
     299             : 
     300           6 :                     if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
     301             :                     {
     302           0 :                         pImpl->aArr.DeleteAndDestroy( p );
     303             :                     }
     304           6 :                 }
     305             :             }
     306             : 
     307           6 :         if( pImpl->pTimer )
     308             :         {
     309           0 :             delete pImpl->pTimer;
     310           0 :             pImpl->pTimer = NULL;
     311           6 :         }
     312             :     }
     313           6 : }
     314             : 
     315             : // notify the sink, the mime type is not
     316             : // a selection criterion
     317           7 : void SvLinkSource::DataChanged( const OUString & rMimeType,
     318             :                                 const ::com::sun::star::uno::Any & rVal )
     319             : {
     320           7 :     if( pImpl->nTimeout && !rVal.hasValue() )
     321             :     {   // only when no data was included
     322             :         // fire all data to the sink, independent of the requested format
     323           0 :         pImpl->aDataMimeType = rMimeType;
     324           0 :         StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
     325             :     }
     326             :     else
     327             :     {
     328           7 :         SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     329          14 :         for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     330             :         {
     331           7 :             if( p->bIsDataSink )
     332             :             {
     333           7 :                 p->xSink->DataChanged( rMimeType, rVal );
     334             : 
     335           7 :                 if ( !aIter.IsValidCurrValue( p ) )
     336           0 :                     continue;
     337             : 
     338           7 :                 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
     339             :                 {
     340           0 :                     pImpl->aArr.DeleteAndDestroy( p );
     341             :                 }
     342             :             }
     343             :         }
     344             : 
     345           7 :         if( pImpl->pTimer )
     346             :         {
     347           0 :             delete pImpl->pTimer;
     348           0 :             pImpl->pTimer = NULL;
     349           7 :         }
     350             :     }
     351           7 : }
     352             : 
     353             : 
     354             : // only one link is correct
     355          47 : void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const OUString& rMimeType,
     356             :                                     sal_uInt16 nAdviseModes )
     357             : {
     358             :     SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl(
     359          47 :                     pLink, rMimeType, nAdviseModes );
     360          47 :     pImpl->aArr.push_back( pNew );
     361          47 : }
     362             : 
     363          45 : void SvLinkSource::RemoveAllDataAdvise( SvBaseLink * pLink )
     364             : {
     365          45 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     366          90 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     367          45 :         if( p->bIsDataSink && &p->xSink == pLink )
     368             :         {
     369          44 :             pImpl->aArr.DeleteAndDestroy( p );
     370          45 :         }
     371          45 : }
     372             : 
     373             : // only one link is correct
     374           1 : void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink )
     375             : {
     376           1 :     SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl( pLink );
     377           1 :     pImpl->aArr.push_back( pNew );
     378           1 : }
     379             : 
     380          45 : void SvLinkSource::RemoveConnectAdvise( SvBaseLink * pLink )
     381             : {
     382          45 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     383          46 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     384           1 :         if( !p->bIsDataSink && &p->xSink == pLink )
     385             :         {
     386           1 :             pImpl->aArr.DeleteAndDestroy( p );
     387          45 :         }
     388          45 : }
     389             : 
     390          11 : bool SvLinkSource::HasDataLinks( const SvBaseLink* pLink ) const
     391             : {
     392          11 :     bool bRet = false;
     393             :     const SvLinkSource_Entry_Impl* p;
     394          14 :     for( sal_uInt16 n = 0, nEnd = pImpl->aArr.size(); n < nEnd; ++n )
     395          23 :         if( ( p = pImpl->aArr[ n ] )->bIsDataSink &&
     396           0 :             ( !pLink || &p->xSink == pLink ) )
     397             :         {
     398          10 :             bRet = true;
     399          10 :             break;
     400             :         }
     401          11 :     return bRet;
     402             : }
     403             : 
     404             : // sal_True => waitinmg for data
     405           0 : bool SvLinkSource::IsPending() const
     406             : {
     407           0 :     return false;
     408             : }
     409             : 
     410             : // sal_True => data complete loaded
     411           0 : bool SvLinkSource::IsDataComplete() const
     412             : {
     413           0 :     return true;
     414             : }
     415             : 
     416           0 : bool SvLinkSource::Connect( SvBaseLink* )
     417             : {
     418           0 :     return true;
     419             : }
     420             : 
     421           0 : bool SvLinkSource::GetData( ::com::sun::star::uno::Any &, const OUString &, bool )
     422             : {
     423           0 :     return false;
     424             : }
     425             : 
     426           0 : void SvLinkSource::Edit( Window *, SvBaseLink *, const Link& )
     427             : {
     428           0 : }
     429             : 
     430             : }
     431             : 
     432             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10