LCOV - code coverage report
Current view: top level - libreoffice/sfx2/source/appl - linksrc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 20 193 10.4 %
Date: 2012-12-27 Functions: 7 46 15.2 %
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           0 : TYPEINIT0( SvLinkSource )
      37             : 
      38           0 : class SvLinkSourceTimer : public Timer
      39             : {
      40             :     SvLinkSource *  pOwner;
      41             :     virtual void    Timeout();
      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             :     String              aDataMimeType;
      74             :     sal_uInt16              nAdviseModes;
      75             :     sal_Bool                bIsDataSink;
      76             : 
      77           2 :     SvLinkSource_Entry_Impl( SvBaseLink* pLink, const String& rMimeType,
      78             :                                 sal_uInt16 nAdvMode )
      79             :         : xSink( pLink ), aDataMimeType( rMimeType ),
      80           2 :             nAdviseModes( nAdvMode ), bIsDataSink( sal_True )
      81           2 :     {}
      82             : 
      83           0 :     SvLinkSource_Entry_Impl( SvBaseLink* pLink )
      84           0 :         : xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( sal_False )
      85           0 :     {}
      86             : 
      87             :     ~SvLinkSource_Entry_Impl();
      88             : };
      89             : 
      90           0 : SvLinkSource_Entry_Impl::~SvLinkSource_Entry_Impl()
      91             : {
      92           0 : }
      93             : 
      94           2 : class SvLinkSource_Array_Impl : public std::vector<SvLinkSource_Entry_Impl*>
      95             : {
      96             : public:
      97           0 :     void DeleteAndDestroy(SvLinkSource_Entry_Impl* p)
      98             :     {
      99           0 :         iterator it = std::find(begin(), end(), p);
     100           0 :         if (it != end())
     101             :         {
     102           0 :             erase(it);
     103           0 :             delete p;
     104             :         }
     105           0 :     }
     106             : 
     107           0 :     ~SvLinkSource_Array_Impl()
     108           0 :     {
     109           0 :         for(const_iterator it = begin(); it != end(); ++it)
     110           0 :             delete *it;
     111           0 :     }
     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           0 :     SvLinkSource_Entry_Impl* Curr()
     123           0 :                             { return nPos < aArr.size() ? aArr[ nPos ] : 0; }
     124             :     SvLinkSource_Entry_Impl* Next();
     125             :     sal_Bool IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry );
     126             : };
     127             : 
     128           0 : SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl(
     129             :         const SvLinkSource_Array_Impl& rArr )
     130           0 :     : aArr( rArr ), rOrigArr( rArr ), nPos( 0 )
     131             : {
     132           0 : }
     133           0 : SvLinkSource_EntryIter_Impl::~SvLinkSource_EntryIter_Impl()
     134             : {
     135           0 :     aArr.clear();
     136           0 : }
     137             : 
     138           0 : sal_Bool SvLinkSource_EntryIter_Impl::IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry )
     139             : {
     140           0 :     return ( nPos < aArr.size() && aArr[nPos] == pEntry
     141           0 :        && std::find( rOrigArr.begin(), rOrigArr.end(), pEntry ) != rOrigArr.end() );
     142             : }
     143             : 
     144           0 : SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next()
     145             : {
     146           0 :     SvLinkSource_Entry_Impl* pRet = 0;
     147           0 :     if( nPos + 1 < (sal_uInt16)aArr.size() )
     148             :     {
     149           0 :         ++nPos;
     150           0 :         if( rOrigArr.size() == aArr.size() &&
     151           0 :             rOrigArr[ nPos ] == aArr[ nPos ] )
     152           0 :             pRet = aArr[ nPos ];
     153             :         else
     154             :         {
     155             :             // then we must search the current (or the next) in the orig
     156           0 :             do {
     157           0 :                 pRet = aArr[ nPos ];
     158           0 :                 if( std::find(rOrigArr.begin(), rOrigArr.end(), pRet ) != rOrigArr.end() )
     159           0 :                     break;
     160           0 :                 pRet = 0;
     161           0 :                 ++nPos;
     162           0 :             } while( nPos < aArr.size() );
     163             : 
     164           0 :             if( nPos >= aArr.size() )
     165           0 :                 pRet = 0;
     166             :         }
     167             :     }
     168           0 :     return pRet;
     169             : }
     170             : 
     171             : struct SvLinkSource_Impl
     172             : {
     173             :     SvLinkSource_Array_Impl aArr;
     174             :     String              aDataMimeType;
     175             :     SvLinkSourceTimer * pTimer;
     176             :     sal_uIntPtr             nTimeout;
     177             :     com::sun::star::uno::Reference<com::sun::star::io::XInputStream>
     178             :     m_xInputStreamToLoadFrom;
     179             :     sal_Bool m_bIsReadOnly;
     180             : 
     181           2 :     SvLinkSource_Impl() : pTimer( 0 ), nTimeout( 3000 ) {}
     182             :     ~SvLinkSource_Impl();
     183             : 
     184             :     void Closed();
     185             : };
     186             : 
     187           0 : SvLinkSource_Impl::~SvLinkSource_Impl()
     188             : {
     189           0 :     delete pTimer;
     190           0 : }
     191             : 
     192           2 : SvLinkSource::SvLinkSource()
     193           2 :      : pImpl( new SvLinkSource_Impl )
     194             : {
     195           2 : }
     196             : 
     197           0 : SvLinkSource::~SvLinkSource()
     198             : {
     199           0 :     delete pImpl;
     200           0 : }
     201             : 
     202             : 
     203           0 : SvLinkSource::StreamToLoadFrom SvLinkSource::getStreamToLoadFrom()
     204             : {
     205             :     return StreamToLoadFrom(
     206             :         pImpl->m_xInputStreamToLoadFrom,
     207           0 :         pImpl->m_bIsReadOnly);
     208             : }
     209             : 
     210           2 : void SvLinkSource::setStreamToLoadFrom(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream,sal_Bool bIsReadOnly )
     211             : {
     212           2 :     pImpl->m_xInputStreamToLoadFrom = xInputStream;
     213           2 :     pImpl->m_bIsReadOnly = bIsReadOnly;
     214           2 : }
     215             : 
     216             : // #i88291#
     217           0 : void SvLinkSource::clearStreamToLoadFrom()
     218             : {
     219           0 :     pImpl->m_xInputStreamToLoadFrom.clear();
     220           0 : }
     221             : 
     222           0 : void  SvLinkSource::Closed()
     223             : {
     224           0 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     225           0 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     226           0 :         if( !p->bIsDataSink )
     227           0 :             p->xSink->Closed();
     228           0 : }
     229             : 
     230           0 : sal_uIntPtr SvLinkSource::GetUpdateTimeout() const
     231             : {
     232           0 :     return pImpl->nTimeout;
     233             : }
     234             : 
     235           2 : void SvLinkSource::SetUpdateTimeout( sal_uIntPtr nTimeout )
     236             : {
     237           2 :     pImpl->nTimeout = nTimeout;
     238           2 :     if( pImpl->pTimer )
     239           0 :         pImpl->pTimer->SetTimeout( nTimeout );
     240           2 : }
     241             : 
     242           0 : void SvLinkSource::SendDataChanged()
     243             : {
     244           0 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     245           0 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     246             :     {
     247           0 :         if( p->bIsDataSink )
     248             :         {
     249           0 :             String sDataMimeType( pImpl->aDataMimeType );
     250           0 :             if( !sDataMimeType.Len() )
     251           0 :                 sDataMimeType = p->aDataMimeType;
     252             : 
     253           0 :             Any aVal;
     254           0 :             if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
     255           0 :                 GetData( aVal, sDataMimeType, sal_True ) )
     256             :             {
     257           0 :                 p->xSink->DataChanged( sDataMimeType, aVal );
     258             : 
     259           0 :                 if ( !aIter.IsValidCurrValue( p ) )
     260           0 :                     continue;
     261             : 
     262           0 :                 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
     263             :                 {
     264           0 :                     pImpl->aArr.DeleteAndDestroy( p );
     265             :                 }
     266             : 
     267           0 :             }
     268             :         }
     269             :     }
     270           0 :     if( pImpl->pTimer )
     271             :     {
     272           0 :         delete pImpl->pTimer;
     273           0 :         pImpl->pTimer = NULL;
     274             :     }
     275           0 :     pImpl->aDataMimeType.Erase();
     276           0 : }
     277             : 
     278           0 : void SvLinkSource::NotifyDataChanged()
     279             : {
     280           0 :     if( pImpl->nTimeout )
     281           0 :         StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
     282             :     else
     283             :     {
     284           0 :         SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     285           0 :         for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     286           0 :             if( p->bIsDataSink )
     287             :             {
     288           0 :                 Any aVal;
     289           0 :                 if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
     290           0 :                     GetData( aVal, p->aDataMimeType, sal_True ) )
     291             :                 {
     292           0 :                     p->xSink->DataChanged( p->aDataMimeType, aVal );
     293             : 
     294           0 :                     if ( !aIter.IsValidCurrValue( p ) )
     295           0 :                         continue;
     296             : 
     297           0 :                     if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
     298             :                     {
     299           0 :                         pImpl->aArr.DeleteAndDestroy( p );
     300             :                     }
     301           0 :                 }
     302             :             }
     303             : 
     304           0 :             if( pImpl->pTimer )
     305             :             {
     306           0 :                 delete pImpl->pTimer;
     307           0 :                 pImpl->pTimer = NULL;
     308           0 :             }
     309             :     }
     310           0 : }
     311             : 
     312             : // notify the sink, the mime type is not
     313             : // a selection criterion
     314           0 : void SvLinkSource::DataChanged( const String & rMimeType,
     315             :                                 const ::com::sun::star::uno::Any & rVal )
     316             : {
     317           0 :     if( pImpl->nTimeout && !rVal.hasValue() )
     318             :     {   // only when no data was included
     319             :         // fire all data to the sink, independent of the requested format
     320           0 :         pImpl->aDataMimeType = rMimeType;
     321           0 :         StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
     322             :     }
     323             :     else
     324             :     {
     325           0 :         SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     326           0 :         for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     327             :         {
     328           0 :             if( p->bIsDataSink )
     329             :             {
     330           0 :                 p->xSink->DataChanged( rMimeType, rVal );
     331             : 
     332           0 :                 if ( !aIter.IsValidCurrValue( p ) )
     333           0 :                     continue;
     334             : 
     335           0 :                 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
     336             :                 {
     337           0 :                     pImpl->aArr.DeleteAndDestroy( p );
     338             :                 }
     339             :             }
     340             :         }
     341             : 
     342           0 :         if( pImpl->pTimer )
     343             :         {
     344           0 :             delete pImpl->pTimer;
     345           0 :             pImpl->pTimer = NULL;
     346           0 :         }
     347             :     }
     348           0 : }
     349             : 
     350             : 
     351             : // only one link is correct
     352           2 : void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const String& rMimeType,
     353             :                                     sal_uInt16 nAdviseModes )
     354             : {
     355             :     SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl(
     356           2 :                     pLink, rMimeType, nAdviseModes );
     357           2 :     pImpl->aArr.push_back( pNew );
     358           2 : }
     359             : 
     360           0 : void SvLinkSource::RemoveAllDataAdvise( SvBaseLink * pLink )
     361             : {
     362           0 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     363           0 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     364           0 :         if( p->bIsDataSink && &p->xSink == pLink )
     365             :         {
     366           0 :             pImpl->aArr.DeleteAndDestroy( p );
     367           0 :         }
     368           0 : }
     369             : 
     370             : // only one link is correct
     371           0 : void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink )
     372             : {
     373           0 :     SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl( pLink );
     374           0 :     pImpl->aArr.push_back( pNew );
     375           0 : }
     376             : 
     377           0 : void SvLinkSource::RemoveConnectAdvise( SvBaseLink * pLink )
     378             : {
     379           0 :     SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
     380           0 :     for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
     381           0 :         if( !p->bIsDataSink && &p->xSink == pLink )
     382             :         {
     383           0 :             pImpl->aArr.DeleteAndDestroy( p );
     384           0 :         }
     385           0 : }
     386             : 
     387           0 : sal_Bool SvLinkSource::HasDataLinks( const SvBaseLink* pLink ) const
     388             : {
     389           0 :     sal_Bool bRet = sal_False;
     390             :     const SvLinkSource_Entry_Impl* p;
     391           0 :     for( sal_uInt16 n = 0, nEnd = pImpl->aArr.size(); n < nEnd; ++n )
     392           0 :         if( ( p = pImpl->aArr[ n ] )->bIsDataSink &&
     393           0 :             ( !pLink || &p->xSink == pLink ) )
     394             :         {
     395           0 :             bRet = sal_True;
     396           0 :             break;
     397             :         }
     398           0 :     return bRet;
     399             : }
     400             : 
     401             : // sal_True => waitinmg for data
     402           0 : sal_Bool SvLinkSource::IsPending() const
     403             : {
     404           0 :     return sal_False;
     405             : }
     406             : 
     407             : // sal_True => data complete loaded
     408           0 : sal_Bool SvLinkSource::IsDataComplete() const
     409             : {
     410           0 :     return sal_True;
     411             : }
     412             : 
     413           0 : sal_Bool SvLinkSource::Connect( SvBaseLink* )
     414             : {
     415           0 :     return sal_True;
     416             : }
     417             : 
     418           0 : sal_Bool SvLinkSource::GetData( ::com::sun::star::uno::Any &, const String &, sal_Bool )
     419             : {
     420           0 :     return sal_False;
     421             : }
     422             : 
     423           0 : void SvLinkSource::Edit( Window *, SvBaseLink *, const Link& )
     424             : {
     425           0 : }
     426             : 
     427             : }
     428             : 
     429             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10