LCOV - code coverage report
Current view: top level - sfx2/source/appl - linkmgr2.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 232 343 67.6 %
Date: 2015-06-13 12:38:46 Functions: 24 27 88.9 %
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          10 : class SvxInternalLink : public sfx2::SvLinkSource
      59             : {
      60             : public:
      61           5 :     SvxInternalLink() {}
      62             : 
      63             :     virtual bool Connect( sfx2::SvBaseLink* ) SAL_OVERRIDE;
      64             : };
      65             : 
      66             : 
      67        4061 : LinkManager::LinkManager(SfxObjectShell* p)
      68        4061 :     : pPersist( p )
      69             : {
      70        4061 : }
      71             : 
      72             : 
      73        8078 : LinkManager::~LinkManager()
      74             : {
      75        4039 :     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        4039 : }
      86             : 
      87           0 : void LinkManager::InsertCachedComp(const Reference<XComponent>& xComp)
      88             : {
      89           0 :     maCachedComps.push_back(xComp);
      90           0 : }
      91             : 
      92          15 : void LinkManager::CloseCachedComps()
      93             : {
      94          15 :     CompVector::iterator itr = maCachedComps.begin(), itrEnd = maCachedComps.end();
      95          15 :     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          15 :     maCachedComps.clear();
     104          15 : }
     105             : 
     106             : 
     107             : 
     108          48 : void LinkManager::Remove( SvBaseLink *pLink )
     109             : {
     110             :     // No duplicate links inserted
     111          48 :     bool bFound = false;
     112          96 :     for( size_t n = 0; n < aLinkTbl.size(); )
     113             :     {
     114          30 :         SvBaseLinkRef* pTmp = aLinkTbl[ n ];
     115          30 :         if( pLink == *pTmp )
     116             :         {
     117          30 :             (*pTmp)->Disconnect();
     118          30 :             (*pTmp)->SetLinkManager( NULL );
     119          30 :             (*pTmp).Clear();
     120          30 :             bFound = true;
     121             :         }
     122             : 
     123             :         // Remove empty ones if they exist
     124          30 :         if( !pTmp->Is() )
     125             :         {
     126          30 :             delete pTmp;
     127          30 :             aLinkTbl.erase( aLinkTbl.begin() + n );
     128          30 :             if( bFound )
     129          78 :                 return ;
     130             :         }
     131             :         else
     132           0 :             ++n;
     133             :     }
     134             : }
     135             : 
     136             : 
     137          30 : void LinkManager::Remove( size_t nPos, size_t nCnt )
     138             : {
     139          30 :     if( nCnt && nPos < aLinkTbl.size() )
     140             :     {
     141          30 :         if (sal::static_int_cast<size_t>(nPos + nCnt) > aLinkTbl.size())
     142           0 :             nCnt = aLinkTbl.size() - nPos;
     143             : 
     144          64 :         for( size_t n = nPos; n < nPos + nCnt; ++n)
     145             :         {
     146          34 :             SvBaseLinkRef* pTmp = aLinkTbl[ n ];
     147          34 :             if( pTmp->Is() )
     148             :             {
     149          34 :                 (*pTmp)->Disconnect();
     150          34 :                 (*pTmp)->SetLinkManager( NULL );
     151             :             }
     152          34 :             delete pTmp;
     153             :         }
     154          30 :         aLinkTbl.erase( aLinkTbl.begin() + nPos, aLinkTbl.begin() + nPos + nCnt );
     155             :     }
     156          30 : }
     157             : 
     158             : 
     159          65 : bool LinkManager::Insert( SvBaseLink* pLink )
     160             : {
     161          73 :     for( size_t n = 0; n < aLinkTbl.size(); ++n )
     162             :     {
     163           8 :         SvBaseLinkRef* pTmp = aLinkTbl[ n ];
     164           8 :         if( !pTmp->Is() )
     165             :         {
     166           0 :             delete pTmp;
     167           0 :             aLinkTbl.erase( aLinkTbl.begin() + n-- );
     168             :         }
     169           8 :         else if( pLink == *pTmp )
     170           0 :             return false; // No duplicate links inserted
     171             :     }
     172             : 
     173          65 :     SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
     174          65 :     pLink->SetLinkManager( this );
     175          65 :     aLinkTbl.push_back( pTmp );
     176          65 :     return true;
     177             : }
     178             : 
     179             : 
     180          62 : bool LinkManager::InsertLink( SvBaseLink * pLink,
     181             :                                 sal_uInt16 nObjType,
     182             :                                 SfxLinkUpdateMode nUpdateMode,
     183             :                                 const OUString* pName )
     184             : {
     185             :     // This First
     186          62 :     pLink->SetObjType( nObjType );
     187          62 :     if( pName )
     188          62 :         pLink->SetName( *pName );
     189          62 :     pLink->SetUpdateMode( nUpdateMode );
     190          62 :     return Insert( pLink );
     191             : }
     192             : 
     193             : 
     194           3 : bool LinkManager::InsertDDELink( SvBaseLink * pLink,
     195             :                                     const OUString& rServer,
     196             :                                     const OUString& rTopic,
     197             :                                     const OUString& rItem )
     198             : {
     199           3 :     if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
     200           0 :         return false;
     201             : 
     202           3 :     OUString sCmd;
     203           3 :     ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
     204             : 
     205           3 :     pLink->SetObjType( OBJECT_CLIENT_DDE );
     206           3 :     pLink->SetName( sCmd );
     207           3 :     return Insert( pLink );
     208             : }
     209             : 
     210             : 
     211           0 : bool LinkManager::InsertDDELink( SvBaseLink * pLink )
     212             : {
     213             :     DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
     214           0 :     if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
     215           0 :         return false;
     216             : 
     217           0 :     if( pLink->GetObjType() == OBJECT_CLIENT_SO )
     218           0 :         pLink->SetObjType( OBJECT_CLIENT_DDE );
     219             : 
     220           0 :     return Insert( pLink );
     221             : }
     222             : 
     223             : 
     224             : // Obtain the string for the dialog
     225         145 : bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
     226             :                                         OUString* pType,
     227             :                                         OUString* pFile,
     228             :                                         OUString* pLinkStr,
     229             :                                         OUString* pFilter )
     230             : {
     231         145 :     bool bRet = false;
     232         145 :     const OUString sLNm( pLink->GetLinkSourceName() );
     233         145 :     if( !sLNm.isEmpty() )
     234             :     {
     235         145 :         switch( pLink->GetObjType() )
     236             :         {
     237             :             case OBJECT_CLIENT_FILE:
     238             :             case OBJECT_CLIENT_GRF:
     239             :             case OBJECT_CLIENT_OLE:
     240             :                 {
     241         135 :                     sal_Int32 nPos = 0;
     242         135 :                     OUString sFile( sLNm.getToken( 0, ::sfx2::cTokenSeparator, nPos ) );
     243         270 :                     OUString sRange( sLNm.getToken( 0, ::sfx2::cTokenSeparator, nPos ) );
     244             : 
     245         135 :                     if( pFile )
     246         134 :                         *pFile = sFile;
     247         135 :                     if( pLinkStr )
     248          27 :                         *pLinkStr = sRange;
     249         135 :                     if( pFilter )
     250          99 :                         *pFilter = nPos == -1 ? OUString() : sLNm.copy(nPos);
     251             : 
     252         135 :                     if( pType )
     253             :                     {
     254           5 :                         sal_uInt16 nObjType = pLink->GetObjType();
     255          15 :                         *pType = SfxResId(
     256           0 :                                     ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
     257             :                                             ? RID_SVXSTR_FILELINK
     258           5 :                                             : RID_SVXSTR_GRAFIKLINK).toString();
     259             :                     }
     260         270 :                     bRet = true;
     261             :                 }
     262         135 :                 break;
     263             :             case OBJECT_CLIENT_DDE:
     264             :                 {
     265          10 :                     sal_Int32 nTmp = 0;
     266          10 :                     OUString sCmd( sLNm );
     267          20 :                     OUString sServer( sCmd.getToken( 0, cTokenSeparator, nTmp ) );
     268          20 :                     OUString sTopic( sCmd.getToken( 0, cTokenSeparator, nTmp ) );
     269             : 
     270          10 :                     if( pType )
     271           5 :                         *pType = sServer;
     272          10 :                     if( pFile )
     273           5 :                         *pFile = sTopic;
     274          10 :                     if( pLinkStr )
     275           5 :                         *pLinkStr = sCmd.copy( nTmp );
     276          20 :                     bRet = true;
     277             :                 }
     278          10 :                 break;
     279             :             default:
     280           0 :                 break;
     281             :         }
     282             :     }
     283             : 
     284         145 :     return bRet;
     285             : }
     286             : 
     287           3 : 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           3 :     std::vector<SvBaseLink*> aTmpArr;
     296           6 :     for( size_t n = 0; n < aLinkTbl.size(); ++n )
     297             :     {
     298           3 :         SvBaseLink* pLink = *aLinkTbl[ n ];
     299           3 :         if( !pLink )
     300             :         {
     301           0 :             Remove( n-- );
     302           0 :             continue;
     303             :         }
     304           3 :         aTmpArr.push_back( pLink );
     305             :     }
     306             : 
     307           6 :     for( size_t n = 0; n < aTmpArr.size(); ++n )
     308             :     {
     309           3 :         SvBaseLink* pLink = aTmpArr[ n ];
     310             : 
     311             :         // search first in the array after the entry
     312           3 :         bool bFound = false;
     313           3 :         for( size_t i = 0; i < aLinkTbl.size(); ++i )
     314           3 :             if( pLink == *aLinkTbl[ i ] )
     315             :             {
     316           3 :                 bFound = true;
     317           3 :                 break;
     318             :             }
     319             : 
     320           3 :         if( !bFound )
     321           0 :             continue;  // was not available!
     322             : 
     323             :         // Graphic-Links not to update yet
     324           9 :         if( !pLink->IsVisible() ||
     325           6 :             ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
     326           3 :             continue;
     327             : 
     328           0 :         if( bAskUpdate )
     329             :         {
     330           0 :             int nRet = ScopedVclPtr<QueryBox>::Create( 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           3 :                 return ;        // nothing should be updated
     342             :             }
     343           0 :             bAskUpdate = false;  // once is enough
     344             :         }
     345             : 
     346           0 :         pLink->Update();
     347             :     }
     348           3 :     CloseCachedComps();
     349             : }
     350             : 
     351             : 
     352             : 
     353          69 : SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
     354             : {
     355          69 :     switch( pLink->GetObjType() )
     356             :     {
     357             :         case OBJECT_CLIENT_FILE:
     358             :         case OBJECT_CLIENT_GRF:
     359             :         case OBJECT_CLIENT_OLE:
     360          64 :             return new SvFileObject;
     361             :         case OBJECT_INTERN:
     362           5 :             return new SvxInternalLink;
     363             :         case OBJECT_CLIENT_DDE:
     364           0 :             return new SvDDEObject;
     365             :         default:
     366           0 :             return SvLinkSourceRef();
     367             :        }
     368             : }
     369             : 
     370           6 : bool LinkManager::InsertServer( SvLinkSource* pObj )
     371             : {
     372             :     // no duplicate inserts
     373           6 :     if( !pObj )
     374           0 :         return false;
     375             : 
     376           6 :     return aServerTbl.insert( pObj ).second;
     377             : }
     378             : 
     379             : 
     380           5 : void LinkManager::RemoveServer( SvLinkSource* pObj )
     381             : {
     382           5 :     aServerTbl.erase( pObj );
     383           5 : }
     384             : 
     385             : 
     386           3 : void MakeLnkName( OUString& rName, const OUString* pType, const OUString& rFile,
     387             :                     const OUString& rLink, const OUString* pFilter )
     388             : {
     389           3 :     if( pType )
     390             :     {
     391           3 :         rName = comphelper::string::strip(*pType, ' ');
     392           3 :         rName += OUString(cTokenSeparator);
     393             :     }
     394           0 :     else if( !rName.isEmpty() )
     395           0 :         rName.clear();
     396             : 
     397           3 :     rName += rFile;
     398             : 
     399           3 :     rName = comphelper::string::strip(rName, ' ');
     400           3 :     rName += OUString(cTokenSeparator);
     401           3 :     rName = comphelper::string::strip(rName, ' ');
     402           3 :     rName += rLink;
     403           3 :     if( pFilter )
     404             :     {
     405           0 :         rName += OUString(cTokenSeparator);
     406           0 :         rName += *pFilter;
     407           0 :         rName = comphelper::string::strip(rName, ' ');
     408             :     }
     409           3 : }
     410             : 
     411         760 : void LinkManager::ReconnectDdeLink(SfxObjectShell& rServer)
     412             : {
     413         760 :     SfxMedium* pMed = rServer.GetMedium();
     414         760 :     if (!pMed)
     415         760 :         return;
     416             : 
     417         760 :     const ::sfx2::SvBaseLinks& rLinks = GetLinks();
     418         760 :     size_t n = rLinks.size();
     419             : 
     420         765 :     for (size_t i = 0; i < n; ++i)
     421             :     {
     422           5 :         ::sfx2::SvBaseLink* p = *rLinks[i];
     423           5 :         OUString aType, aFile, aLink, aFilter;
     424           5 :         if (!GetDisplayNames(p, &aType, &aFile, &aLink, &aFilter))
     425           0 :             continue;
     426             : 
     427           5 :         if (aType != "soffice")
     428             :             // DDE connections between OOo apps are always named 'soffice'.
     429           5 :             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)
     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 :             SfxLinkUpdateMode::ONCALL == rLink.GetUpdateMode() ? ADVISEMODE_ONLYONCE : 0);
     458             :     }
     459           0 : }
     460             : 
     461          62 : bool LinkManager::InsertFileLink(
     462             :     sfx2::SvBaseLink& rLink, sal_uInt16 nFileType, const OUString& rFileNm,
     463             :     const OUString* pFilterNm, const OUString* pRange)
     464             : {
     465          62 :     if (!(OBJECT_CLIENT_SO & rLink.GetObjType()))
     466           0 :         return false;
     467             : 
     468          62 :     OUStringBuffer aBuf;
     469          62 :     aBuf.append(rFileNm);
     470          62 :     aBuf.append(sfx2::cTokenSeparator);
     471             : 
     472          62 :     if (pRange)
     473          18 :         aBuf.append(*pRange);
     474             : 
     475          62 :     if (pFilterNm)
     476             :     {
     477          48 :         aBuf.append(sfx2::cTokenSeparator);
     478          48 :         aBuf.append(*pFilterNm);
     479             :     }
     480             : 
     481         124 :     OUString aCmd = aBuf.makeStringAndClear();
     482         124 :     return InsertLink(&rLink, nFileType, SfxLinkUpdateMode::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        2699 : void LinkManager::CancelTransfers()
     488             : {
     489             :     SvFileObject* pFileObj;
     490             :     sfx2::SvBaseLink* pLnk;
     491             : 
     492        2699 :     const sfx2::SvBaseLinks& rLnks = GetLinks();
     493        5412 :     for( size_t n = rLnks.size(); n; )
     494          42 :         if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
     495          42 :             OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
     496             :             0 != ( pFileObj = static_cast<SvFileObject*>(pLnk->GetObj()) ) )
     497          14 :             pFileObj->CancelTransfers();
     498        2699 : }
     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          52 : SotClipboardFormatId LinkManager::RegisterStatusInfoId()
     505             : {
     506             :     static SotClipboardFormatId nFormat = SotClipboardFormatId::NONE;
     507             : 
     508          52 :     if( nFormat == SotClipboardFormatId::NONE )
     509             :     {
     510             :         nFormat = SotExchange::RegisterFormatName(
     511           4 :                     OUString("StatusInfo from SvxInternalLink"));
     512             :     }
     513          52 :     return nFormat;
     514             : }
     515             : 
     516             : 
     517             : 
     518          37 : bool LinkManager::GetGraphicFromAny( const OUString& rMimeType,
     519             :                                 const ::com::sun::star::uno::Any & rValue,
     520             :                                 Graphic& rGrf )
     521             : {
     522          37 :     bool bRet = false;
     523          37 :     ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
     524          37 :     if( rValue.hasValue() && ( rValue >>= aSeq ) )
     525             :     {
     526          48 :         SvMemoryStream aMemStm( const_cast<sal_Int8 *>(aSeq.getConstArray()), aSeq.getLength(),
     527          48 :                                 StreamMode::READ );
     528          24 :         aMemStm.Seek( 0 );
     529             : 
     530          24 :         switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
     531             :         {
     532             :         case SotClipboardFormatId::SVXB:
     533             :             {
     534          24 :                 ReadGraphic( aMemStm, rGrf );
     535          24 :                 bRet = true;
     536             :             }
     537          24 :             break;
     538             :         case SotClipboardFormatId::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 SotClipboardFormatId::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           0 :         default: break;
     555          24 :         }
     556             :     }
     557          37 :     return bRet;
     558             : }
     559             : 
     560             : 
     561             : 
     562          20 : OUString lcl_DDE_RelToAbs( const OUString& rTopic, const OUString& rBaseURL )
     563             : {
     564          20 :     OUString sRet;
     565          40 :     INetURLObject aURL( rTopic );
     566          20 :     if( INetProtocol::NotValid == aURL.GetProtocol() )
     567          20 :         utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
     568          20 :     if( sRet.isEmpty() )
     569          20 :         sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
     570          40 :     return sRet;
     571             : }
     572             : 
     573           5 : bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
     574             : {
     575           5 :     SfxObjectShell* pFndShell = 0;
     576           5 :     sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
     577          10 :     OUString sTopic, sItem, sReferer;
     578           5 :     LinkManager* pLinkMgr = pLink->GetLinkManager();
     579           5 :     if (pLinkMgr && sfx2::LinkManager::GetDisplayNames(pLink, 0, &sTopic, &sItem) && !sTopic.isEmpty())
     580             :     {
     581             :         // first only loop over the DocumentShells the shells and find those
     582             :         // with the name:
     583           5 :         CharClass aCC( LanguageTag( LANGUAGE_SYSTEM) );
     584             : 
     585           5 :         TypeId aType( TYPE(SfxObjectShell) );
     586             : 
     587           5 :         bool bFirst = true;
     588           5 :         SfxObjectShell* pShell = pLinkMgr->GetPersist();
     589           5 :         if( pShell && pShell->GetMedium() )
     590             :         {
     591           5 :             sReferer = pShell->GetMedium()->GetBaseURL();
     592           5 :             SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, false );
     593           5 :             if ( pItem )
     594           5 :                 nUpdateMode = pItem->GetValue();
     595             :         }
     596             : 
     597          10 :         OUString sNmURL(aCC.lowercase(lcl_DDE_RelToAbs(sTopic, sReferer)));
     598             : 
     599           5 :         if ( !pShell )
     600             :         {
     601           0 :             bFirst = false;
     602           0 :             pShell = SfxObjectShell::GetFirst( &aType, false );
     603             :         }
     604             : 
     605          10 :         OUString sTmp;
     606          20 :         while( pShell )
     607             :         {
     608          15 :             if( sTmp.isEmpty() )
     609             :             {
     610          15 :                 sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
     611          15 :                 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
     612             :             }
     613             : 
     614             : 
     615          15 :             sTmp = aCC.lowercase( sTmp );
     616          15 :             if( sTmp == sNmURL )  // we want these
     617             :             {
     618           5 :                 pFndShell = pShell;
     619           5 :                 break;
     620             :             }
     621             : 
     622          10 :             if( bFirst )
     623             :             {
     624           5 :                 bFirst = false;
     625           5 :                 pShell = SfxObjectShell::GetFirst( &aType, false );
     626             :             }
     627             :             else
     628           5 :                 pShell = SfxObjectShell::GetNext( *pShell, &aType, false );
     629             : 
     630          10 :             sTmp.clear();
     631           5 :         }
     632             :     }
     633             : 
     634             :     // empty topics are not allowed - which document is it
     635           5 :     if( sTopic.isEmpty() )
     636           0 :         return false;
     637             : 
     638           5 :     if (pFndShell)
     639             :     {
     640           5 :         sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
     641           5 :         if( pNewSrc )
     642             :         {
     643           5 :             ::com::sun::star::datatransfer::DataFlavor aFl;
     644           5 :             SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
     645             : 
     646           5 :             pLink->SetObj( pNewSrc );
     647             :             pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
     648           5 :                                 SfxLinkUpdateMode::ONCALL == pLink->GetUpdateMode()
     649             :                                     ? ADVISEMODE_ONLYONCE
     650           5 :                                     : 0 );
     651           5 :             return true;
     652             :         }
     653             :     }
     654             :     else
     655             :     {
     656             :         // then try to download the file:
     657           0 :         INetURLObject aURL( sTopic );
     658           0 :         INetProtocol eOld = aURL.GetProtocol();
     659           0 :         aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
     660           0 :         if( INetProtocol::NotValid != eOld ||
     661           0 :             INetProtocol::Http != aURL.GetProtocol() )
     662             :         {
     663           0 :             SfxStringItem aName( SID_FILE_NAME, sTopic );
     664           0 :             SfxBoolItem aMinimized(SID_MINIMIZED, true);
     665           0 :             SfxBoolItem aHidden(SID_HIDDEN, true);
     666           0 :             SfxStringItem aTarget( SID_TARGETNAME, OUString("_blank") );
     667           0 :             SfxStringItem aReferer( SID_REFERER, sReferer );
     668           0 :             SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
     669           0 :             SfxBoolItem aReadOnly(SID_DOC_READONLY, false);
     670             : 
     671             :             // Disable automatic re-connection to avoid this link instance
     672             :             // being destroyed at re-connection.
     673           0 :             SfxBoolItem aDdeConnect(SID_DDE_RECONNECT_ONLOAD, false);
     674             : 
     675             :             // #i14200# (DDE-link crashes wordprocessor)
     676           0 :             SfxAllItemSet aArgs( SfxGetpApp()->GetPool() );
     677           0 :             aArgs.Put(aReferer);
     678           0 :             aArgs.Put(aTarget);
     679           0 :             aArgs.Put(aHidden);
     680           0 :             aArgs.Put(aMinimized);
     681           0 :             aArgs.Put(aName);
     682           0 :             aArgs.Put(aUpdate);
     683           0 :             aArgs.Put(aReadOnly);
     684           0 :             aArgs.Put(aDdeConnect);
     685           0 :             Reference<XComponent> xComp = SfxObjectShell::CreateAndLoadComponent(aArgs);
     686           0 :             pFndShell = SfxObjectShell::GetShellFromComponent(xComp);
     687           0 :             if (xComp.is() && pFndShell)
     688             :             {
     689           0 :                 pLinkMgr->InsertCachedComp(xComp);
     690           0 :                 sfx2::LinkManager::LinkServerShell(sItem, *pFndShell, *pLink);
     691           0 :                 return true;
     692           0 :             }
     693           0 :         }
     694             :     }
     695             : 
     696           5 :     return false;
     697             : }
     698             : 
     699             : 
     700             : }
     701             : 
     702             : 
     703             : 
     704             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11