LCOV - code coverage report
Current view: top level - sfx2/source/appl - linkmgr2.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 223 343 65.0 %
Date: 2014-11-03 Functions: 26 29 89.7 %
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             : #include <comphelper/string.hxx>
      21             : #include <sfx2/linkmgr.hxx>
      22             : #include <com/sun/star/document/UpdateDocMode.hpp>
      23             : #include <sfx2/objsh.hxx>
      24             : #include <svl/urihelper.hxx>
      25             : #include <sot/formats.hxx>
      26             : #include <tools/urlobj.hxx>
      27             : #include <sot/exchange.hxx>
      28             : #include <tools/debug.hxx>
      29             : #include <vcl/msgbox.hxx>
      30             : #include <sfx2/lnkbase.hxx>
      31             : #include <sfx2/app.hxx>
      32             : #include <vcl/graph.hxx>
      33             : #include <svl/stritem.hxx>
      34             : #include <svl/eitem.hxx>
      35             : #include <svl/intitem.hxx>
      36             : #include <unotools/localfilehelper.hxx>
      37             : #include <i18nlangtag/languagetag.hxx>
      38             : #include <sfx2/request.hxx>
      39             : #include <vcl/dibtools.hxx>
      40             : #include "unotools/charclass.hxx"
      41             : 
      42             : #include "fileobj.hxx"
      43             : #include "impldde.hxx"
      44             : #include "app.hrc"
      45             : #include <sfx2/sfxresid.hxx>
      46             : 
      47             : #include <com/sun/star/lang/XComponent.hpp>
      48             : #include <com/sun/star/util/XCloseable.hpp>
      49             : 
      50             : using ::com::sun::star::uno::UNO_QUERY;
      51             : using ::com::sun::star::uno::Reference;
      52             : using ::com::sun::star::lang::XComponent;
      53             : using ::com::sun::star::util::XCloseable;
      54             : 
      55             : namespace sfx2
      56             : {
      57             : 
      58          20 : class SvxInternalLink : public sfx2::SvLinkSource
      59             : {
      60             : public:
      61          10 :     SvxInternalLink() {}
      62             : 
      63             :     virtual bool Connect( sfx2::SvBaseLink* ) SAL_OVERRIDE;
      64             : };
      65             : 
      66             : 
      67        6716 : LinkManager::LinkManager(SfxObjectShell* p)
      68        6716 :     : pPersist( p )
      69             : {
      70        6716 : }
      71             : 
      72             : 
      73       13418 : LinkManager::~LinkManager()
      74             : {
      75        6709 :     for( size_t n = 0; n < aLinkTbl.size(); ++n)
      76             :     {
      77           0 :         SvBaseLinkRef* pTmp = aLinkTbl[ n ];
      78           0 :         if( pTmp->Is() )
      79             :         {
      80           0 :             (*pTmp)->Disconnect();
      81           0 :             (*pTmp)->SetLinkManager( NULL );
      82             :         }
      83           0 :         delete pTmp;
      84             :     }
      85        6709 : }
      86             : 
      87           0 : void LinkManager::InsertCachedComp(const Reference<XComponent>& xComp)
      88             : {
      89           0 :     maCachedComps.push_back(xComp);
      90           0 : }
      91             : 
      92          16 : void LinkManager::CloseCachedComps()
      93             : {
      94          16 :     CompVector::iterator itr = maCachedComps.begin(), itrEnd = maCachedComps.end();
      95          16 :     for (; itr != itrEnd; ++itr)
      96             :     {
      97           0 :         Reference<XCloseable> xCloseable(*itr, UNO_QUERY);
      98           0 :         if (!xCloseable.is())
      99           0 :             continue;
     100             : 
     101           0 :         xCloseable->close(true);
     102           0 :     }
     103          16 :     maCachedComps.clear();
     104          16 : }
     105             : 
     106             : 
     107             : 
     108          70 : void LinkManager::Remove( SvBaseLink *pLink )
     109             : {
     110             :     // No duplicate links inserted
     111          70 :     int bFound = sal_False;
     112         140 :     for( size_t n = 0; n < aLinkTbl.size(); )
     113             :     {
     114          52 :         SvBaseLinkRef* pTmp = aLinkTbl[ n ];
     115          52 :         if( pLink == *pTmp )
     116             :         {
     117          52 :             (*pTmp)->Disconnect();
     118          52 :             (*pTmp)->SetLinkManager( NULL );
     119          52 :             (*pTmp).Clear();
     120          52 :             bFound = sal_True;
     121             :         }
     122             : 
     123             :         // Remove empty ones if they exist
     124          52 :         if( !pTmp->Is() )
     125             :         {
     126          52 :             delete pTmp;
     127          52 :             aLinkTbl.erase( aLinkTbl.begin() + n );
     128          52 :             if( bFound )
     129         122 :                 return ;
     130             :         }
     131             :         else
     132           0 :             ++n;
     133             :     }
     134             : }
     135             : 
     136             : 
     137          34 : void LinkManager::Remove( size_t nPos, size_t nCnt )
     138             : {
     139          34 :     if( nCnt && nPos < aLinkTbl.size() )
     140             :     {
     141          34 :         if (sal::static_int_cast<size_t>(nPos + nCnt) > aLinkTbl.size())
     142           0 :             nCnt = aLinkTbl.size() - nPos;
     143             : 
     144          70 :         for( size_t n = nPos; n < nPos + nCnt; ++n)
     145             :         {
     146          36 :             SvBaseLinkRef* pTmp = aLinkTbl[ n ];
     147          36 :             if( pTmp->Is() )
     148             :             {
     149          36 :                 (*pTmp)->Disconnect();
     150          36 :                 (*pTmp)->SetLinkManager( NULL );
     151             :             }
     152          36 :             delete pTmp;
     153             :         }
     154          34 :         aLinkTbl.erase( aLinkTbl.begin() + nPos, aLinkTbl.begin() + nPos + nCnt );
     155             :     }
     156          34 : }
     157             : 
     158             : 
     159          88 : bool LinkManager::Insert( SvBaseLink* pLink )
     160             : {
     161          90 :     for( size_t n = 0; n < aLinkTbl.size(); ++n )
     162             :     {
     163           2 :         SvBaseLinkRef* pTmp = aLinkTbl[ n ];
     164           2 :         if( !pTmp->Is() )
     165             :         {
     166           0 :             delete pTmp;
     167           0 :             aLinkTbl.erase( aLinkTbl.begin() + n-- );
     168             :         }
     169           2 :         else if( pLink == *pTmp )
     170           0 :             return false; // No duplicate links inserted
     171             :     }
     172             : 
     173          88 :     SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
     174          88 :     pLink->SetLinkManager( this );
     175          88 :     aLinkTbl.push_back( pTmp );
     176          88 :     return true;
     177             : }
     178             : 
     179             : 
     180          70 : bool LinkManager::InsertLink( SvBaseLink * pLink,
     181             :                                 sal_uInt16 nObjType,
     182             :                                 sal_uInt16 nUpdateMode,
     183             :                                 const OUString* pName )
     184             : {
     185             :     // This First
     186          70 :     pLink->SetObjType( nObjType );
     187          70 :     if( pName )
     188          70 :         pLink->SetName( *pName );
     189          70 :     pLink->SetUpdateMode( nUpdateMode );
     190          70 :     return Insert( pLink );
     191             : }
     192             : 
     193             : 
     194           6 : bool LinkManager::InsertDDELink( SvBaseLink * pLink,
     195             :                                     const OUString& rServer,
     196             :                                     const OUString& rTopic,
     197             :                                     const OUString& rItem )
     198             : {
     199           6 :     if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
     200           0 :         return false;
     201             : 
     202           6 :     OUString sCmd;
     203           6 :     ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
     204             : 
     205           6 :     pLink->SetObjType( OBJECT_CLIENT_DDE );
     206           6 :     pLink->SetName( sCmd );
     207           6 :     return Insert( pLink );
     208             : }
     209             : 
     210             : 
     211          12 : bool LinkManager::InsertDDELink( SvBaseLink * pLink )
     212             : {
     213             :     DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
     214          12 :     if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
     215           0 :         return false;
     216             : 
     217          12 :     if( pLink->GetObjType() == OBJECT_CLIENT_SO )
     218           0 :         pLink->SetObjType( OBJECT_CLIENT_DDE );
     219             : 
     220          12 :     return Insert( pLink );
     221             : }
     222             : 
     223             : 
     224             : // Obtain the string for the dialog
     225         398 : bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
     226             :                                         OUString* pType,
     227             :                                         OUString* pFile,
     228             :                                         OUString* pLinkStr,
     229             :                                         OUString* pFilter ) const
     230             : {
     231         398 :     bool bRet = false;
     232         398 :     const OUString sLNm( pLink->GetLinkSourceName() );
     233         398 :     if( !sLNm.isEmpty() )
     234             :     {
     235         398 :         switch( pLink->GetObjType() )
     236             :         {
     237             :             case OBJECT_CLIENT_FILE:
     238             :             case OBJECT_CLIENT_GRF:
     239             :             case OBJECT_CLIENT_OLE:
     240             :                 {
     241         378 :                     sal_Int32 nPos = 0;
     242         378 :                     OUString sFile( sLNm.getToken( 0, ::sfx2::cTokenSeparator, nPos ) );
     243         756 :                     OUString sRange( sLNm.getToken( 0, ::sfx2::cTokenSeparator, nPos ) );
     244             : 
     245         378 :                     if( pFile )
     246         374 :                         *pFile = sFile;
     247         378 :                     if( pLinkStr )
     248         178 :                         *pLinkStr = sRange;
     249         378 :                     if( pFilter )
     250         286 :                         *pFilter = nPos == -1 ? OUString() : sLNm.copy(nPos);
     251             : 
     252         378 :                     if( pType )
     253             :                     {
     254          10 :                         sal_uInt16 nObjType = pLink->GetObjType();
     255          30 :                         *pType = SfxResId(
     256           0 :                                     ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
     257             :                                             ? RID_SVXSTR_FILELINK
     258          10 :                                             : RID_SVXSTR_GRAFIKLINK).toString();
     259             :                     }
     260         756 :                     bRet = true;
     261             :                 }
     262         378 :                 break;
     263             :             case OBJECT_CLIENT_DDE:
     264             :                 {
     265          20 :                     sal_Int32 nTmp = 0;
     266          20 :                     OUString sCmd( sLNm );
     267          40 :                     OUString sServer( sCmd.getToken( 0, cTokenSeparator, nTmp ) );
     268          40 :                     OUString sTopic( sCmd.getToken( 0, cTokenSeparator, nTmp ) );
     269             : 
     270          20 :                     if( pType )
     271          10 :                         *pType = sServer;
     272          20 :                     if( pFile )
     273          10 :                         *pFile = sTopic;
     274          20 :                     if( pLinkStr )
     275          10 :                         *pLinkStr = sCmd.copy( nTmp );
     276          40 :                     bRet = true;
     277             :                 }
     278          20 :                 break;
     279             :             default:
     280           0 :                 break;
     281             :         }
     282             :     }
     283             : 
     284         398 :     return bRet;
     285             : }
     286             : 
     287           0 : void LinkManager::UpdateAllLinks(
     288             :     bool bAskUpdate,
     289             :     bool /*bCallErrHdl*/,
     290             :     bool bUpdateGrfLinks,
     291             :     vcl::Window* pParentWin )
     292             : {
     293             :     // First make a copy of the array in order to update links
     294             :     // links in ... no contact between them!
     295           0 :     std::vector<SvBaseLink*> aTmpArr;
     296           0 :     for( size_t n = 0; n < aLinkTbl.size(); ++n )
     297             :     {
     298           0 :         SvBaseLink* pLink = *aLinkTbl[ n ];
     299           0 :         if( !pLink )
     300             :         {
     301           0 :             Remove( n-- );
     302           0 :             continue;
     303             :         }
     304           0 :         aTmpArr.push_back( pLink );
     305             :     }
     306             : 
     307           0 :     for( size_t n = 0; n < aTmpArr.size(); ++n )
     308             :     {
     309           0 :         SvBaseLink* pLink = aTmpArr[ n ];
     310             : 
     311             :         // search first in the array after the entry
     312           0 :         bool bFound = false;
     313           0 :         for( size_t i = 0; i < aLinkTbl.size(); ++i )
     314           0 :             if( pLink == *aLinkTbl[ i ] )
     315             :             {
     316           0 :                 bFound = true;
     317           0 :                 break;
     318             :             }
     319             : 
     320           0 :         if( !bFound )
     321           0 :             continue;  // was not available!
     322             : 
     323             :         // Graphic-Links not to update yet
     324           0 :         if( !pLink->IsVisible() ||
     325           0 :             ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
     326           0 :             continue;
     327             : 
     328           0 :         if( bAskUpdate )
     329             :         {
     330           0 :             int nRet = QueryBox( pParentWin, WB_YES_NO | WB_DEF_YES, SfxResId( STR_QUERY_UPDATE_LINKS ).toString() ).Execute();
     331           0 :             if( RET_YES != nRet )
     332             :             {
     333           0 :                 SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
     334             : 
     335           0 :                 if(pShell)
     336             :                 {
     337           0 :                     comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = pShell->getEmbeddedObjectContainer();
     338           0 :                     rEmbeddedObjectContainer.setUserAllowsLinkUpdate(false);
     339             :                 }
     340             : 
     341           0 :                 return ;        // nothing should be updated
     342             :             }
     343           0 :             bAskUpdate = false;  // once is enough
     344             :         }
     345             : 
     346           0 :         pLink->Update();
     347             :     }
     348           0 :     CloseCachedComps();
     349             : }
     350             : 
     351             : 
     352             : 
     353          98 : SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
     354             : {
     355          98 :     switch( pLink->GetObjType() )
     356             :     {
     357             :         case OBJECT_CLIENT_FILE:
     358             :         case OBJECT_CLIENT_GRF:
     359             :         case OBJECT_CLIENT_OLE:
     360          88 :             return new SvFileObject;
     361             :         case OBJECT_INTERN:
     362          10 :             return new SvxInternalLink;
     363             :         case OBJECT_CLIENT_DDE:
     364           0 :             return new SvDDEObject;
     365             :         default:
     366           0 :             return SvLinkSourceRef();
     367             :        }
     368             : }
     369             : 
     370          12 : bool LinkManager::InsertServer( SvLinkSource* pObj )
     371             : {
     372             :     // no duplicate inserts
     373          12 :     if( !pObj )
     374           0 :         return false;
     375             : 
     376          12 :     return aServerTbl.insert( pObj ).second;
     377             : }
     378             : 
     379             : 
     380          10 : void LinkManager::RemoveServer( SvLinkSource* pObj )
     381             : {
     382          10 :     aServerTbl.erase( pObj );
     383          10 : }
     384             : 
     385             : 
     386           8 : void MakeLnkName( OUString& rName, const OUString* pType, const OUString& rFile,
     387             :                     const OUString& rLink, const OUString* pFilter )
     388             : {
     389           8 :     if( pType )
     390             :     {
     391           6 :         rName = comphelper::string::strip(*pType, ' ');
     392           6 :         rName += OUString(cTokenSeparator);
     393             :     }
     394           2 :     else if( !rName.isEmpty() )
     395           2 :         rName = "";
     396             : 
     397           8 :     rName += rFile;
     398             : 
     399           8 :     rName = comphelper::string::strip(rName, ' ');
     400           8 :     rName += OUString(cTokenSeparator);
     401           8 :     rName = comphelper::string::strip(rName, ' ');
     402           8 :     rName += rLink;
     403           8 :     if( pFilter )
     404             :     {
     405           2 :         rName += OUString(cTokenSeparator);
     406           2 :         rName += *pFilter;
     407           2 :         rName = comphelper::string::strip(rName, ' ');
     408             :     }
     409           8 : }
     410             : 
     411         520 : void LinkManager::ReconnectDdeLink(SfxObjectShell& rServer)
     412             : {
     413         520 :     SfxMedium* pMed = rServer.GetMedium();
     414         520 :     if (!pMed)
     415         520 :         return;
     416             : 
     417         520 :     const ::sfx2::SvBaseLinks& rLinks = GetLinks();
     418         520 :     size_t n = rLinks.size();
     419             : 
     420         530 :     for (size_t i = 0; i < n; ++i)
     421             :     {
     422          10 :         ::sfx2::SvBaseLink* p = *rLinks[i];
     423          10 :         OUString aType, aFile, aLink, aFilter;
     424          10 :         if (!GetDisplayNames(p, &aType, &aFile, &aLink, &aFilter))
     425           0 :             continue;
     426             : 
     427          10 :         if (aType != "soffice")
     428             :             // DDE connections between OOo apps are always named 'soffice'.
     429          10 :             continue;
     430             : 
     431           0 :         OUString aTmp;
     432           0 :         OUString aURL = aFile;
     433           0 :         if (utl::LocalFileHelper::ConvertPhysicalNameToURL(aFile, aTmp))
     434           0 :             aURL = aTmp;
     435             : 
     436           0 :         if (!aURL.equalsIgnoreAsciiCase(pMed->GetName()))
     437             :             // This DDE link is not associated with this server shell...  Skip it.
     438           0 :             continue;
     439             : 
     440           0 :         if (aLink.isEmpty())
     441           0 :             continue;
     442             : 
     443           0 :         LinkServerShell(aLink, rServer, *p);
     444           0 :     }
     445             : }
     446             : 
     447           0 : void LinkManager::LinkServerShell(const OUString& rPath, SfxObjectShell& rServer, ::sfx2::SvBaseLink& rLink) const
     448             : {
     449           0 :     ::sfx2::SvLinkSource* pSrvSrc = rServer.DdeCreateLinkSource(rPath);
     450           0 :     if (pSrvSrc)
     451             :     {
     452           0 :         ::com::sun::star::datatransfer::DataFlavor aFl;
     453           0 :         SotExchange::GetFormatDataFlavor(rLink.GetContentType(), aFl);
     454           0 :         rLink.SetObj(pSrvSrc);
     455             :         pSrvSrc->AddDataAdvise(
     456             :             &rLink, aFl.MimeType,
     457           0 :             sfx2::LINKUPDATE_ONCALL == rLink.GetUpdateMode() ? ADVISEMODE_ONLYONCE : 0);
     458             :     }
     459           0 : }
     460             : 
     461          70 : bool LinkManager::InsertFileLink(
     462             :     sfx2::SvBaseLink& rLink, sal_uInt16 nFileType, const OUString& rFileNm,
     463             :     const OUString* pFilterNm, const OUString* pRange)
     464             : {
     465          70 :     if (!(OBJECT_CLIENT_SO & rLink.GetObjType()))
     466           0 :         return false;
     467             : 
     468          70 :     OUStringBuffer aBuf;
     469          70 :     aBuf.append(rFileNm);
     470          70 :     aBuf.append(sfx2::cTokenSeparator);
     471             : 
     472          70 :     if (pRange)
     473          38 :         aBuf.append(*pRange);
     474             : 
     475          70 :     if (pFilterNm)
     476             :     {
     477          48 :         aBuf.append(sfx2::cTokenSeparator);
     478          48 :         aBuf.append(*pFilterNm);
     479             :     }
     480             : 
     481         140 :     OUString aCmd = aBuf.makeStringAndClear();
     482         140 :     return InsertLink(&rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &aCmd);
     483             : }
     484             : 
     485             : // A transfer is aborted, so cancel all download media
     486             : // (for now this is only of interest for the file links!)
     487        4595 : void LinkManager::CancelTransfers()
     488             : {
     489             :     SvFileObject* pFileObj;
     490             :     sfx2::SvBaseLink* pLnk;
     491             : 
     492        4595 :     const sfx2::SvBaseLinks& rLnks = GetLinks();
     493        9198 :     for( size_t n = rLnks.size(); n; )
     494          24 :         if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
     495          24 :             OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
     496             :             0 != ( pFileObj = static_cast<SvFileObject*>(pLnk->GetObj()) ) )
     497           8 :             pFileObj->CancelTransfers();
     498        4595 : }
     499             :     // For the purpose of sending Status information from the file object to
     500             :     // the base link, there exist a dedicated ClipBoardId. The SvData-object
     501             :     // gets the appropriate information as a string
     502             :     // For now this is required for file object in conjunction with JavaScript
     503             :     // - needs information about Load/Abort/Error
     504          74 : sal_uIntPtr LinkManager::RegisterStatusInfoId()
     505             : {
     506             :     static sal_uIntPtr nFormat = 0;
     507             : 
     508          74 :     if( !nFormat )
     509             :     {
     510             :         nFormat = SotExchange::RegisterFormatName(
     511           2 :                     OUString("StatusInfo from SvxInternalLink"));
     512             :     }
     513          74 :     return nFormat;
     514             : }
     515             : 
     516             : 
     517             : 
     518          28 : bool LinkManager::GetGraphicFromAny( const OUString& rMimeType,
     519             :                                 const ::com::sun::star::uno::Any & rValue,
     520             :                                 Graphic& rGrf )
     521             : {
     522          28 :     bool bRet = false;
     523          28 :     ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
     524          28 :     if( rValue.hasValue() && ( rValue >>= aSeq ) )
     525             :     {
     526          56 :         SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
     527          56 :                                 STREAM_READ );
     528          28 :         aMemStm.Seek( 0 );
     529             : 
     530          28 :         switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
     531             :         {
     532             :         case SOT_FORMATSTR_ID_SVXB:
     533             :             {
     534          28 :                 ReadGraphic( aMemStm, rGrf );
     535          28 :                 bRet = true;
     536             :             }
     537          28 :             break;
     538             :         case FORMAT_GDIMETAFILE:
     539             :             {
     540           0 :                 GDIMetaFile aMtf;
     541           0 :                 aMtf.Read( aMemStm );
     542           0 :                 rGrf = aMtf;
     543           0 :                 bRet = true;
     544             :             }
     545           0 :             break;
     546             :         case FORMAT_BITMAP:
     547             :             {
     548           0 :                 Bitmap aBmp;
     549           0 :                 ReadDIB(aBmp, aMemStm, true);
     550           0 :                 rGrf = aBmp;
     551           0 :                 bRet = true;
     552             :             }
     553           0 :             break;
     554          28 :         }
     555             :     }
     556          28 :     return bRet;
     557             : }
     558             : 
     559             : 
     560             : 
     561          40 : OUString lcl_DDE_RelToAbs( const OUString& rTopic, const OUString& rBaseURL )
     562             : {
     563          40 :     OUString sRet;
     564          80 :     INetURLObject aURL( rTopic );
     565          40 :     if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
     566          40 :         utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
     567          40 :     if( sRet.isEmpty() )
     568          40 :         sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
     569          80 :     return sRet;
     570             : }
     571             : 
     572          10 : bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
     573             : {
     574          10 :     SfxObjectShell* pFndShell = 0;
     575          10 :     sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
     576          20 :     OUString sTopic, sItem, sReferer;
     577          10 :     LinkManager* pLinkMgr = pLink->GetLinkManager();
     578          10 :     if (pLinkMgr && pLinkMgr->GetDisplayNames(pLink, 0, &sTopic, &sItem) && !sTopic.isEmpty())
     579             :     {
     580             :         // first only loop over the DocumentShells the shells and find those
     581             :         // with the name:
     582          10 :         CharClass aCC( LanguageTag( LANGUAGE_SYSTEM) );
     583             : 
     584          10 :         TypeId aType( TYPE(SfxObjectShell) );
     585             : 
     586          10 :         bool bFirst = true;
     587          10 :         SfxObjectShell* pShell = pLinkMgr->GetPersist();
     588          10 :         if( pShell && pShell->GetMedium() )
     589             :         {
     590          10 :             sReferer = pShell->GetMedium()->GetBaseURL();
     591          10 :             SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, false );
     592          10 :             if ( pItem )
     593          10 :                 nUpdateMode = pItem->GetValue();
     594             :         }
     595             : 
     596          20 :         OUString sNmURL(aCC.lowercase(lcl_DDE_RelToAbs(sTopic, sReferer)));
     597             : 
     598          10 :         if ( !pShell )
     599             :         {
     600           0 :             bFirst = false;
     601           0 :             pShell = SfxObjectShell::GetFirst( &aType, false );
     602             :         }
     603             : 
     604          20 :         OUString sTmp;
     605          40 :         while( pShell )
     606             :         {
     607          30 :             if( sTmp.isEmpty() )
     608             :             {
     609          30 :                 sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
     610          30 :                 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
     611             :             }
     612             : 
     613             : 
     614          30 :             sTmp = aCC.lowercase( sTmp );
     615          30 :             if( sTmp == sNmURL )  // we want these
     616             :             {
     617          10 :                 pFndShell = pShell;
     618          10 :                 break;
     619             :             }
     620             : 
     621          20 :             if( bFirst )
     622             :             {
     623          10 :                 bFirst = false;
     624          10 :                 pShell = SfxObjectShell::GetFirst( &aType, false );
     625             :             }
     626             :             else
     627          10 :                 pShell = SfxObjectShell::GetNext( *pShell, &aType, false );
     628             : 
     629          20 :             sTmp = "";
     630          10 :         }
     631             :     }
     632             : 
     633             :     // empty topics are not allowed - which document is it
     634          10 :     if( sTopic.isEmpty() )
     635           0 :         return false;
     636             : 
     637          10 :     if (pFndShell)
     638             :     {
     639          10 :         sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
     640          10 :         if( pNewSrc )
     641             :         {
     642          10 :             ::com::sun::star::datatransfer::DataFlavor aFl;
     643          10 :             SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
     644             : 
     645          10 :             pLink->SetObj( pNewSrc );
     646             :             pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
     647          10 :                                 sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
     648             :                                     ? ADVISEMODE_ONLYONCE
     649          10 :                                     : 0 );
     650          10 :             return true;
     651             :         }
     652             :     }
     653             :     else
     654             :     {
     655             :         // then try to download the file:
     656           0 :         INetURLObject aURL( sTopic );
     657           0 :         INetProtocol eOld = aURL.GetProtocol();
     658           0 :         aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
     659           0 :         if( INET_PROT_NOT_VALID != eOld ||
     660           0 :             INET_PROT_HTTP != aURL.GetProtocol() )
     661             :         {
     662           0 :             SfxStringItem aName( SID_FILE_NAME, sTopic );
     663           0 :             SfxBoolItem aMinimized(SID_MINIMIZED, true);
     664           0 :             SfxBoolItem aHidden(SID_HIDDEN, true);
     665           0 :             SfxStringItem aTarget( SID_TARGETNAME, OUString("_blank") );
     666           0 :             SfxStringItem aReferer( SID_REFERER, sReferer );
     667           0 :             SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
     668           0 :             SfxBoolItem aReadOnly(SID_DOC_READONLY, false);
     669             : 
     670             :             // Disable automatic re-connection to avoid this link instance
     671             :             // being destroyed at re-connection.
     672           0 :             SfxBoolItem aDdeConnect(SID_DDE_RECONNECT_ONLOAD, false);
     673             : 
     674             :             // #i14200# (DDE-link crashes wordprocessor)
     675           0 :             SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
     676           0 :             aArgs.Put(aReferer);
     677           0 :             aArgs.Put(aTarget);
     678           0 :             aArgs.Put(aHidden);
     679           0 :             aArgs.Put(aMinimized);
     680           0 :             aArgs.Put(aName);
     681           0 :             aArgs.Put(aUpdate);
     682           0 :             aArgs.Put(aReadOnly);
     683           0 :             aArgs.Put(aDdeConnect);
     684           0 :             Reference<XComponent> xComp = SfxObjectShell::CreateAndLoadComponent(aArgs);
     685           0 :             pFndShell = SfxObjectShell::GetShellFromComponent(xComp);
     686           0 :             if (xComp.is() && pFndShell)
     687             :             {
     688           0 :                 pLinkMgr->InsertCachedComp(xComp);
     689           0 :                 pLinkMgr->LinkServerShell(sItem, *pFndShell, *pLink);
     690           0 :                 return true;
     691           0 :             }
     692           0 :         }
     693             :     }
     694             : 
     695          10 :     return false;
     696             : }
     697             : 
     698             : 
     699         951 : }
     700             : 
     701             : 
     702             : 
     703             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10