LCOV - code coverage report
Current view: top level - sfx2/source/appl - lnkbase2.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 116 294 39.5 %
Date: 2014-11-03 Functions: 24 46 52.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/lnkbase.hxx>
      22             : #include <sot/exchange.hxx>
      23             : #include <com/sun/star/uno/Any.hxx>
      24             : #include <com/sun/star/uno/Sequence.hxx>
      25             : #include <com/sun/star/ui/dialogs/TemplateDescription.hpp>
      26             : #include <vcl/layout.hxx>
      27             : #include <sfx2/linkmgr.hxx>
      28             : #include <vcl/svapp.hxx>
      29             : #include "app.hrc"
      30             : #include <sfx2/sfxresid.hxx>
      31             : #include <sfx2/filedlghelper.hxx>
      32             : #include <tools/debug.hxx>
      33             : #include <svl/svdde.hxx>
      34             : 
      35             : using namespace ::com::sun::star;
      36             : using namespace ::com::sun::star::uno;
      37             : 
      38             : namespace sfx2
      39             : {
      40             : 
      41          42 : TYPEINIT0( SvBaseLink )
      42             : 
      43             : static DdeTopic* FindTopic( const OUString &, sal_uInt16* = 0 );
      44             : 
      45             : class  ImplDdeItem;
      46             : 
      47             : struct BaseLink_Impl
      48             : {
      49             :     Link                m_aEndEditLink;
      50             :     LinkManager*      m_pLinkMgr;
      51             :     vcl::Window*             m_pParentWin;
      52             :     FileDialogHelper*   m_pFileDlg;
      53             :     bool                m_bIsConnect;
      54             : 
      55          74 :     BaseLink_Impl() :
      56             :           m_pLinkMgr( NULL )
      57             :         , m_pParentWin( NULL )
      58             :         , m_pFileDlg( NULL )
      59          74 :         , m_bIsConnect( false )
      60          74 :         {}
      61             : 
      62          72 :     ~BaseLink_Impl()
      63          72 :         { delete m_pFileDlg; }
      64             : };
      65             : 
      66             : // only for internal management
      67             : struct ImplBaseLinkData
      68             : {
      69             :     struct tClientType
      70             :     {
      71             :         // applies for all links
      72             :         sal_uIntPtr nCntntType; // Update Format
      73             :         // Not Ole-Links
      74             :         bool    bIntrnlLnk;  // It is an internal link
      75             :         sal_uInt16  nUpdateMode; // UpdateMode
      76             :     };
      77             : 
      78             :     struct tDDEType
      79             :     {
      80             :         ImplDdeItem* pItem;
      81             :     };
      82             : 
      83             :     union {
      84             :         tClientType ClientType;
      85             :         tDDEType DDEType;
      86             :     };
      87          74 :     ImplBaseLinkData()
      88             :     {
      89          74 :         ClientType.nCntntType = 0;
      90          74 :         ClientType.bIntrnlLnk = false;
      91          74 :         ClientType.nUpdateMode = 0;
      92          74 :         DDEType.pItem = NULL;
      93          74 :     }
      94             : };
      95             : 
      96             : 
      97             : class ImplDdeItem : public DdeGetPutItem
      98             : {
      99             :     SvBaseLink* pLink;
     100             :     DdeData aData;
     101             :     Sequence< sal_Int8 > aSeq;  // Datacontainer for DdeData !!!
     102             :     bool bIsValidData : 1;
     103             :     bool bIsInDTOR : 1;
     104             : public:
     105           0 :     ImplDdeItem( SvBaseLink& rLink, const OUString& rStr )
     106             :         : DdeGetPutItem( rStr ), pLink( &rLink ), bIsValidData( false ),
     107           0 :         bIsInDTOR( false )
     108           0 :     {}
     109             :     virtual ~ImplDdeItem();
     110             : 
     111             :     virtual DdeData* Get( sal_uIntPtr ) SAL_OVERRIDE;
     112             :     virtual bool     Put( const DdeData* ) SAL_OVERRIDE;
     113             :     virtual void     AdviseLoop( bool ) SAL_OVERRIDE;
     114             : 
     115           0 :     void Notify()
     116             :     {
     117           0 :         bIsValidData = false;
     118           0 :         DdeGetPutItem::NotifyClient();
     119           0 :     }
     120             : 
     121           0 :     bool IsInDTOR() const { return bIsInDTOR; }
     122             : };
     123             : 
     124             : 
     125             : 
     126           2 : SvBaseLink::SvBaseLink()
     127           2 :     : m_bIsReadOnly(false)
     128             : {
     129           2 :     pImpl = new BaseLink_Impl();
     130           2 :     nObjType = OBJECT_CLIENT_SO;
     131           2 :     pImplData = new ImplBaseLinkData;
     132           2 :     bVisible = bSynchron = bUseCache = true;
     133           2 :     bWasLastEditOK = false;
     134           2 : }
     135             : 
     136             : 
     137             : 
     138          72 : SvBaseLink::SvBaseLink( sal_uInt16 nUpdateMode, sal_uIntPtr nContentType )
     139          72 :     : m_bIsReadOnly(false)
     140             : {
     141          72 :     pImpl = new BaseLink_Impl();
     142          72 :     nObjType = OBJECT_CLIENT_SO;
     143          72 :     pImplData = new ImplBaseLinkData;
     144          72 :     bVisible = bSynchron = bUseCache = true;
     145          72 :     bWasLastEditOK = false;
     146             : 
     147             :     // It it going to be a Ole-Link,
     148          72 :     pImplData->ClientType.nUpdateMode = nUpdateMode;
     149          72 :     pImplData->ClientType.nCntntType = nContentType;
     150          72 :     pImplData->ClientType.bIntrnlLnk = false;
     151          72 : }
     152             : 
     153             : 
     154             : 
     155           0 : SvBaseLink::SvBaseLink( const OUString& rLinkName, sal_uInt16 nObjectType, SvLinkSource* pObj )
     156             :     : pImpl(0)
     157           0 :     , m_bIsReadOnly(false)
     158             : {
     159           0 :     bVisible = bSynchron = bUseCache = true;
     160           0 :     bWasLastEditOK = false;
     161           0 :     aLinkName = rLinkName;
     162           0 :     pImplData = new ImplBaseLinkData;
     163           0 :     nObjType = nObjectType;
     164             : 
     165           0 :     if( !pObj )
     166             :     {
     167             :         DBG_ASSERT( pObj, "Where is my left-most object" );
     168           0 :         return;
     169             :     }
     170             : 
     171           0 :     if( OBJECT_DDE_EXTERN == nObjType )
     172             :     {
     173           0 :         sal_uInt16 nItemStt = 0;
     174           0 :         DdeTopic* pTopic = FindTopic( aLinkName, &nItemStt );
     175           0 :         if( pTopic )
     176             :         {
     177             :             // then we have it all together
     178             :             // MM_TODO how do I get the name
     179           0 :             OUString aStr = aLinkName; // xLinkName->GetDisplayName();
     180           0 :             aStr = aStr.copy( nItemStt );
     181           0 :             pImplData->DDEType.pItem = new ImplDdeItem( *this, aStr );
     182           0 :             pTopic->InsertItem( pImplData->DDEType.pItem );
     183             : 
     184             :             // store the Advice
     185           0 :             xObj = pObj;
     186             :         }
     187             :     }
     188           0 :     else if( pObj->Connect( this ) )
     189           0 :         xObj = pObj;
     190             : }
     191             : 
     192             : 
     193             : 
     194         144 : SvBaseLink::~SvBaseLink()
     195             : {
     196          72 :     Disconnect();
     197             : 
     198          72 :     switch( nObjType )
     199             :     {
     200             :     case OBJECT_DDE_EXTERN:
     201           0 :         if( !pImplData->DDEType.pItem->IsInDTOR() )
     202           0 :             delete pImplData->DDEType.pItem;
     203           0 :         break;
     204             :     }
     205             : 
     206          72 :     delete pImplData;
     207          72 :     delete pImpl;
     208          72 : }
     209             : 
     210           0 : IMPL_LINK( SvBaseLink, EndEditHdl, OUString*, _pNewName )
     211             : {
     212           0 :     OUString sNewName;
     213           0 :     if ( _pNewName )
     214           0 :         sNewName = *_pNewName;
     215           0 :     if ( !ExecuteEdit( sNewName ) )
     216           0 :         sNewName = "";
     217           0 :     bWasLastEditOK = !sNewName.isEmpty();
     218           0 :     if ( pImpl->m_aEndEditLink.IsSet() )
     219           0 :         pImpl->m_aEndEditLink.Call( this );
     220           0 :     return 0;
     221             : }
     222             : 
     223             : 
     224             : 
     225          76 : void SvBaseLink::SetObjType( sal_uInt16 nObjTypeP )
     226             : {
     227             :     DBG_ASSERT( nObjType != OBJECT_CLIENT_DDE, "type already set" );
     228             :     DBG_ASSERT( !xObj.Is(), "object exist" );
     229             : 
     230          76 :     nObjType = nObjTypeP;
     231          76 : }
     232             : 
     233             : 
     234             : 
     235          76 : void SvBaseLink::SetName( const OUString & rNm )
     236             : {
     237          76 :     aLinkName = rNm;
     238          76 : }
     239             : 
     240             : 
     241             : 
     242          10 : void SvBaseLink::SetObj( SvLinkSource * pObj )
     243             : {
     244             :     DBG_ASSERT( (nObjType & OBJECT_CLIENT_SO &&
     245             :                 pImplData->ClientType.bIntrnlLnk) ||
     246             :                 nObjType == OBJECT_CLIENT_GRF,
     247             :                 "no intern link" );
     248          10 :     xObj = pObj;
     249          10 : }
     250             : 
     251             : 
     252             : 
     253          16 : void SvBaseLink::SetLinkSourceName( const OUString & rLnkNm )
     254             : {
     255          16 :     if( aLinkName == rLnkNm )
     256          16 :         return;
     257             : 
     258          16 :     AddNextRef(); // should be superfluous
     259             :     // remove old connection
     260          16 :     Disconnect();
     261             : 
     262          16 :     aLinkName = rLnkNm;
     263             : 
     264             :     // New Connection
     265          16 :     _GetRealObject();
     266          16 :     ReleaseRef(); // should be superfluous
     267             : }
     268             : 
     269             : 
     270             : 
     271             : 
     272             : 
     273             : 
     274          88 : void SvBaseLink::SetUpdateMode( sal_uInt16 nMode )
     275             : {
     276         176 :     if( ( OBJECT_CLIENT_SO & nObjType ) &&
     277          88 :         pImplData->ClientType.nUpdateMode != nMode )
     278             :     {
     279          12 :         AddNextRef();
     280          12 :         Disconnect();
     281             : 
     282          12 :         pImplData->ClientType.nUpdateMode = nMode;
     283          12 :         _GetRealObject();
     284          12 :         ReleaseRef();
     285             :     }
     286          88 : }
     287             : 
     288             : // #i88291#
     289           0 : void SvBaseLink::clearStreamToLoadFrom()
     290             : {
     291           0 :     m_xInputStreamToLoadFrom.clear();
     292           0 :     if( xObj.Is() )
     293             :     {
     294           0 :         xObj->clearStreamToLoadFrom();
     295             :     }
     296           0 : }
     297             : 
     298          88 : bool SvBaseLink::Update()
     299             : {
     300          88 :     if( OBJECT_CLIENT_SO & nObjType )
     301             :     {
     302          88 :         AddNextRef();
     303          88 :         Disconnect();
     304             : 
     305          88 :         _GetRealObject();
     306          88 :         ReleaseRef();
     307          88 :         if( xObj.Is() )
     308             :         {
     309          88 :             xObj->setStreamToLoadFrom(m_xInputStreamToLoadFrom,m_bIsReadOnly);
     310             :             OUString sMimeType( SotExchange::GetFormatMimeType(
     311          88 :                             pImplData->ClientType.nCntntType ));
     312          88 :             Any aData;
     313             : 
     314          88 :             if( xObj->GetData( aData, sMimeType ) )
     315             :             {
     316          88 :                 UpdateResult eRes = DataChanged(sMimeType, aData);
     317          88 :                 bool bSuccess = eRes == SUCCESS;
     318             :                 //for manual Updates there is no need to hold the ServerObject
     319         186 :                 if( OBJECT_CLIENT_DDE == nObjType &&
     320          88 :                     LINKUPDATE_ONCALL == GetUpdateMode() && xObj.Is() )
     321           0 :                     xObj->RemoveAllDataAdvise( this );
     322          88 :                 return bSuccess;
     323             :             }
     324           0 :             if( xObj.Is() )
     325             :             {
     326             :                 // should be asynschron?
     327           0 :                 if( xObj->IsPending() )
     328           0 :                     return true;
     329             : 
     330             :                 // we do not need the object anymore
     331           0 :                 AddNextRef();
     332           0 :                 Disconnect();
     333           0 :                 ReleaseRef();
     334           0 :             }
     335             :         }
     336             :     }
     337           0 :     return false;
     338             : }
     339             : 
     340             : 
     341          24 : sal_uInt16 SvBaseLink::GetUpdateMode() const
     342             : {
     343          24 :     return ( OBJECT_CLIENT_SO & nObjType )
     344             :             ? pImplData->ClientType.nUpdateMode
     345          24 :             : sal::static_int_cast< sal_uInt16 >( LINKUPDATE_ONCALL );
     346             : }
     347             : 
     348             : 
     349         122 : void SvBaseLink::_GetRealObject( bool bConnect)
     350             : {
     351         122 :     if( !pImpl->m_pLinkMgr )
     352         146 :         return;
     353             : 
     354             :     DBG_ASSERT( !xObj.Is(), "object already exist" );
     355             : 
     356          98 :     if( OBJECT_CLIENT_DDE == nObjType )
     357             :     {
     358          10 :         OUString sServer;
     359          40 :         if( pImpl->m_pLinkMgr->GetDisplayNames( this, &sServer ) &&
     360          40 :             sServer == Application::GetAppName() )  // internal Link !!!
     361             :         {
     362             :             // so that the Internal link can be created!
     363          10 :             nObjType = OBJECT_INTERN;
     364          10 :             xObj = pImpl->m_pLinkMgr->CreateObj( this );
     365             : 
     366          10 :             pImplData->ClientType.bIntrnlLnk = true;
     367          10 :             nObjType = OBJECT_CLIENT_DDE;  // so we know what it once was!
     368             :         }
     369             :         else
     370             :         {
     371           0 :             pImplData->ClientType.bIntrnlLnk = false;
     372           0 :             xObj = pImpl->m_pLinkMgr->CreateObj( this );
     373          10 :         }
     374             :     }
     375          88 :     else if( (OBJECT_CLIENT_SO & nObjType) )
     376          88 :         xObj = pImpl->m_pLinkMgr->CreateObj( this );
     377             : 
     378          98 :     if( bConnect && ( !xObj.Is() || !xObj->Connect( this ) ) )
     379           0 :         Disconnect();
     380             : }
     381             : 
     382         112 : sal_uIntPtr SvBaseLink::GetContentType() const
     383             : {
     384         112 :     if( OBJECT_CLIENT_SO & nObjType )
     385         112 :         return pImplData->ClientType.nCntntType;
     386             : 
     387           0 :     return 0;  // all Formats ?
     388             : }
     389             : 
     390             : 
     391          22 : bool SvBaseLink::SetContentType( sal_uIntPtr nType )
     392             : {
     393          22 :     if( OBJECT_CLIENT_SO & nObjType )
     394             :     {
     395          22 :         pImplData->ClientType.nCntntType = nType;
     396          22 :         return true;
     397             :     }
     398           0 :     return false;
     399             : }
     400             : 
     401         600 : LinkManager* SvBaseLink::GetLinkManager()
     402             : {
     403         600 :     return pImpl->m_pLinkMgr;
     404             : }
     405             : 
     406           0 : const LinkManager* SvBaseLink::GetLinkManager() const
     407             : {
     408           0 :     return pImpl->m_pLinkMgr;
     409             : }
     410             : 
     411         176 : void SvBaseLink::SetLinkManager( LinkManager* _pMgr )
     412             : {
     413         176 :     pImpl->m_pLinkMgr = _pMgr;
     414         176 : }
     415             : 
     416         292 : void SvBaseLink::Disconnect()
     417             : {
     418         292 :     if( xObj.Is() )
     419             :     {
     420          98 :         xObj->RemoveAllDataAdvise( this );
     421          98 :         xObj->RemoveConnectAdvise( this );
     422          98 :         xObj.Clear();
     423             :     }
     424         292 : }
     425             : 
     426           0 : SvBaseLink::UpdateResult SvBaseLink::DataChanged( const OUString &, const ::com::sun::star::uno::Any & )
     427             : {
     428           0 :     switch( nObjType )
     429             :     {
     430             :     case OBJECT_DDE_EXTERN:
     431           0 :         if( pImplData->DDEType.pItem )
     432           0 :             pImplData->DDEType.pItem->Notify();
     433           0 :         break;
     434             :     }
     435           0 :     return SUCCESS;
     436             : }
     437             : 
     438           0 : void SvBaseLink::Edit( vcl::Window* pParent, const Link& rEndEditHdl )
     439             : {
     440           0 :     pImpl->m_pParentWin = pParent;
     441           0 :     pImpl->m_aEndEditLink = rEndEditHdl;
     442           0 :     pImpl->m_bIsConnect = xObj.Is();
     443           0 :     if( !pImpl->m_bIsConnect )
     444           0 :         _GetRealObject( xObj.Is() );
     445             : 
     446           0 :     bool bAsync = false;
     447           0 :     Link aLink = LINK( this, SvBaseLink, EndEditHdl );
     448             : 
     449           0 :     if( OBJECT_CLIENT_SO & nObjType && pImplData->ClientType.bIntrnlLnk )
     450             :     {
     451           0 :         if( pImpl->m_pLinkMgr )
     452             :         {
     453           0 :             SvLinkSourceRef ref = pImpl->m_pLinkMgr->CreateObj( this );
     454           0 :             if( ref.Is() )
     455             :             {
     456           0 :                 ref->Edit( pParent, this, aLink );
     457           0 :                 bAsync = true;
     458           0 :             }
     459           0 :         }
     460             :     }
     461             :     else
     462             :     {
     463           0 :         xObj->Edit( pParent, this, aLink );
     464           0 :         bAsync = true;
     465             :     }
     466             : 
     467           0 :     if ( !bAsync )
     468             :     {
     469           0 :         ExecuteEdit( OUString() );
     470           0 :         bWasLastEditOK = false;
     471           0 :         if ( pImpl->m_aEndEditLink.IsSet() )
     472           0 :             pImpl->m_aEndEditLink.Call( this );
     473             :     }
     474           0 : }
     475             : 
     476           0 : bool SvBaseLink::ExecuteEdit( const OUString& _rNewName )
     477             : {
     478           0 :     if( !_rNewName.isEmpty() )
     479             :     {
     480           0 :         SetLinkSourceName( _rNewName );
     481           0 :         if( !Update() )
     482             :         {
     483           0 :             OUString sApp, sTopic, sItem, sError;
     484           0 :             pImpl->m_pLinkMgr->GetDisplayNames( this, &sApp, &sTopic, &sItem );
     485           0 :             if( nObjType == OBJECT_CLIENT_DDE )
     486             :             {
     487           0 :                 sError = SFX2_RESSTR(STR_DDE_ERROR);
     488             : 
     489           0 :                 sal_Int32 nFndPos = sError.indexOf( '%' );
     490           0 :                 if( -1 != nFndPos )
     491             :                 {
     492           0 :                     sError = sError.replaceAt( nFndPos, 1, sApp );
     493           0 :                     nFndPos = nFndPos + sApp.getLength();
     494             : 
     495           0 :                     if( -1 != ( nFndPos = sError.indexOf( '%', nFndPos )))
     496             :                     {
     497           0 :                         sError = sError.replaceAt( nFndPos, 1, sTopic );
     498           0 :                         nFndPos = nFndPos + sTopic.getLength();
     499             : 
     500           0 :                         if( -1 != ( nFndPos = sError.indexOf( '%', nFndPos )))
     501           0 :                             sError = sError.replaceAt( nFndPos, 1, sItem );
     502             :                     }
     503             :                 }
     504             :             }
     505             :             else
     506           0 :                 return false;
     507             : 
     508           0 :             MessageDialog(pImpl->m_pParentWin, sError).Execute();
     509             :         }
     510             :     }
     511           0 :     else if( !pImpl->m_bIsConnect )
     512           0 :         Disconnect();
     513           0 :     pImpl->m_bIsConnect = false;
     514           0 :     return true;
     515             : }
     516             : 
     517           0 : void SvBaseLink::Closed()
     518             : {
     519           0 :     if( xObj.Is() )
     520           0 :         xObj->RemoveAllDataAdvise( this );
     521           0 : }
     522             : 
     523           0 : FileDialogHelper & SvBaseLink::GetInsertFileDialog(const OUString& rFactory) const
     524             : {
     525           0 :     if ( pImpl->m_pFileDlg )
     526           0 :         delete pImpl->m_pFileDlg;
     527             :     pImpl->m_pFileDlg = new FileDialogHelper(
     528             :             ui::dialogs::TemplateDescription::FILEOPEN_SIMPLE,
     529           0 :             SFXWB_INSERT, rFactory);
     530           0 :     return *pImpl->m_pFileDlg;
     531             : }
     532             : 
     533           0 : ImplDdeItem::~ImplDdeItem()
     534             : {
     535           0 :     bIsInDTOR = true;
     536             :     // So that no-one gets the idea to delete the pointer when Disconnecting!
     537           0 :     SvBaseLinkRef aRef( pLink );
     538           0 :     aRef->Disconnect();
     539           0 : }
     540             : 
     541           0 : DdeData* ImplDdeItem::Get( sal_uIntPtr nFormat )
     542             : {
     543           0 :     if( pLink->GetObj() )
     544             :     {
     545             :         // is it still valid?
     546           0 :         if( bIsValidData && nFormat == aData.GetFormat() )
     547           0 :             return &aData;
     548             : 
     549           0 :         Any aValue;
     550           0 :         OUString sMimeType( SotExchange::GetFormatMimeType( nFormat ));
     551           0 :         if( pLink->GetObj()->GetData( aValue, sMimeType ) )
     552             :         {
     553           0 :             if( aValue >>= aSeq )
     554             :             {
     555           0 :                 aData = DdeData( (const char *)aSeq.getConstArray(), aSeq.getLength(), nFormat );
     556             : 
     557           0 :                 bIsValidData = true;
     558           0 :                 return &aData;
     559             :             }
     560           0 :         }
     561             :     }
     562           0 :     aSeq.realloc( 0 );
     563           0 :     bIsValidData = false;
     564           0 :     return 0;
     565             : }
     566             : 
     567             : 
     568           0 : bool ImplDdeItem::Put( const DdeData*  )
     569             : {
     570             :     OSL_FAIL( "ImplDdeItem::Put not implemented" );
     571           0 :     return false;
     572             : }
     573             : 
     574             : 
     575           0 : void ImplDdeItem::AdviseLoop( bool bOpen )
     576             : {
     577             :     // Connection is closed, so also unsubscribe link
     578           0 :     if( pLink->GetObj() )
     579             :     {
     580           0 :         if( bOpen )
     581             :         {
     582             :             // A connection is re-established
     583           0 :             if( OBJECT_DDE_EXTERN == pLink->GetObjType() )
     584             :             {
     585           0 :                 pLink->GetObj()->AddDataAdvise( pLink, OUString("text/plain;charset=utf-16"),  ADVISEMODE_NODATA );
     586           0 :                 pLink->GetObj()->AddConnectAdvise( pLink );
     587             :             }
     588             :         }
     589             :         else
     590             :         {
     591             :             // So that no-one gets the idea to delete the pointer
     592             :             // when Disconnecting!
     593           0 :             SvBaseLinkRef aRef( pLink );
     594           0 :             aRef->Disconnect();
     595             :         }
     596             :     }
     597           0 : }
     598             : 
     599             : 
     600           0 : static DdeTopic* FindTopic( const OUString & rLinkName, sal_uInt16* pItemStt )
     601             : {
     602           0 :     if( rLinkName.isEmpty() )
     603           0 :         return 0;
     604             : 
     605           0 :     OUString sNm( rLinkName );
     606           0 :     sal_Int32 nTokenPos = 0;
     607           0 :     OUString sService( sNm.getToken( 0, cTokenSeparator, nTokenPos ) );
     608             : 
     609           0 :     DdeServices& rSvc = DdeService::GetServices();
     610           0 :     for (DdeServices::iterator aI = rSvc.begin(); aI != rSvc.end(); ++aI)
     611             :     {
     612           0 :         DdeService* pService = *aI;
     613           0 :         if( pService->GetName() == sService )
     614             :         {
     615             :             // then we search for the Topic
     616           0 :             OUString sTopic( sNm.getToken( 0, cTokenSeparator, nTokenPos ) );
     617           0 :             if( pItemStt )
     618           0 :                 *pItemStt = nTokenPos;
     619             : 
     620           0 :             std::vector<DdeTopic*>& rTopics = pService->GetTopics();
     621             : 
     622           0 :             for( int i = 0; i < 2; ++i )
     623             :             {
     624           0 :                 for( std::vector<DdeTopic*>::iterator iterTopic = rTopics.begin();
     625           0 :                      iterTopic != rTopics.end(); ++iterTopic )
     626           0 :                     if( (*iterTopic)->GetName() == sTopic )
     627           0 :                         return *iterTopic;
     628             : 
     629             :                 // Topic not found?
     630             :                 // then we try once to create it
     631           0 :                 if( i || !pService->MakeTopic( sTopic ) )
     632           0 :                     break;  // did not work, exiting
     633             :             }
     634           0 :             break;
     635             :         }
     636             :     }
     637           0 :     return 0;
     638             : }
     639             : 
     640         951 : }
     641             : 
     642             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10