Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / sfx2 / source / appl / linkmgr2.cxx
blobdaec440c0c5af65a9e8915a493960c9d47795b40
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <sfx2/linkmgr.hxx>
30 #include <com/sun/star/document/UpdateDocMode.hpp>
31 #include <sfx2/objsh.hxx>
32 #include <svl/urihelper.hxx>
33 #include <sot/formats.hxx>
34 #include <tools/urlobj.hxx>
35 #include <sot/exchange.hxx>
36 #include <tools/debug.hxx>
37 #include <vcl/msgbox.hxx>
38 #include <sfx2/lnkbase.hxx>
39 #include <sfx2/app.hxx>
40 #include <vcl/graph.hxx>
41 #include <svl/stritem.hxx>
42 #include <svl/eitem.hxx>
43 #include <svl/intitem.hxx>
44 #include <unotools/localfilehelper.hxx>
45 #include <i18npool/mslangid.hxx>
46 #include <sfx2/request.hxx>
48 #include "fileobj.hxx"
49 #include "impldde.hxx"
50 #include "app.hrc"
51 #include "sfx2/sfxresid.hxx"
52 #include <svl/svstdarr.hxx>
54 #include <com/sun/star/lang/XComponent.hpp>
55 #include <com/sun/star/util/XCloseable.hpp>
57 using ::com::sun::star::uno::UNO_QUERY;
58 using ::com::sun::star::uno::Reference;
59 using ::com::sun::star::lang::XComponent;
60 using ::com::sun::star::util::XCloseable;
61 using ::rtl::OUString;
62 using ::rtl::OUStringBuffer;
64 namespace sfx2
67 class SvxInternalLink : public sfx2::SvLinkSource
69 public:
70 SvxInternalLink() {}
72 virtual sal_Bool Connect( sfx2::SvBaseLink* );
76 SV_IMPL_PTRARR( SvBaseLinks, SvBaseLinkRefPtr )
78 LinkManager::LinkManager(SfxObjectShell* p)
79 : pPersist( p )
84 LinkManager::~LinkManager()
86 SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
87 for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
89 if( (*ppRef)->Is() )
91 (*(*ppRef))->Disconnect();
92 (*(*ppRef))->SetLinkManager( NULL );
94 delete *ppRef;
98 void LinkManager::InsertCachedComp(const Reference<XComponent>& xComp)
100 maCachedComps.push_back(xComp);
103 void LinkManager::CloseCachedComps()
105 CompVector::iterator itr = maCachedComps.begin(), itrEnd = maCachedComps.end();
106 for (; itr != itrEnd; ++itr)
108 Reference<XCloseable> xCloseable(*itr, UNO_QUERY);
109 if (!xCloseable.is())
110 continue;
112 xCloseable->close(true);
114 maCachedComps.clear();
117 //--------------------------------------------------------------------------
119 void LinkManager::Remove( SvBaseLink *pLink )
121 // No duplicate links inserted
122 int bFound = sal_False;
123 SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
124 for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
126 if( pLink == *(*ppRef) )
128 (*(*ppRef))->Disconnect();
129 (*(*ppRef))->SetLinkManager( NULL );
130 (*(*ppRef)).Clear();
131 bFound = sal_True;
134 // Remove emty ones if they exist
135 if( !(*ppRef)->Is() )
137 delete *ppRef;
138 aLinkTbl.Remove( aLinkTbl.Count() - n, 1 );
139 if( bFound )
140 return ;
141 --ppRef;
147 void LinkManager::Remove( sal_uInt16 nPos, sal_uInt16 nCnt )
149 if( nCnt && nPos < aLinkTbl.Count() )
151 if( nPos + nCnt > aLinkTbl.Count() )
152 nCnt = aLinkTbl.Count() - nPos;
154 SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData() + nPos;
155 for( sal_uInt16 n = nCnt; n; --n, ++ppRef )
157 if( (*ppRef)->Is() )
159 (*(*ppRef))->Disconnect();
160 (*(*ppRef))->SetLinkManager( NULL );
162 delete *ppRef;
164 aLinkTbl.Remove( nPos, nCnt );
169 sal_Bool LinkManager::Insert( SvBaseLink* pLink )
171 // No duplicate links inserted
172 for( sal_uInt16 n = 0; n < aLinkTbl.Count(); ++n )
174 SvBaseLinkRef* pTmp = aLinkTbl[ n ];
175 if( !pTmp->Is() )
176 aLinkTbl.DeleteAndDestroy( n-- );
178 if( pLink == *pTmp )
179 return sal_False;
182 SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
183 pLink->SetLinkManager( this );
184 aLinkTbl.Insert( pTmp, aLinkTbl.Count() );
185 return sal_True;
189 sal_Bool LinkManager::InsertLink( SvBaseLink * pLink,
190 sal_uInt16 nObjType,
191 sal_uInt16 nUpdateMode,
192 const String* pName )
194 // This First
195 pLink->SetObjType( nObjType );
196 if( pName )
197 pLink->SetName( *pName );
198 pLink->SetUpdateMode( nUpdateMode );
199 return Insert( pLink );
203 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink,
204 const String& rServer,
205 const String& rTopic,
206 const String& rItem )
208 if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
209 return sal_False;
211 String sCmd;
212 ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
214 pLink->SetObjType( OBJECT_CLIENT_DDE );
215 pLink->SetName( sCmd );
216 return Insert( pLink );
220 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink )
222 DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
223 if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
224 return sal_False;
226 if( pLink->GetObjType() == OBJECT_CLIENT_SO )
227 pLink->SetObjType( OBJECT_CLIENT_DDE );
229 return Insert( pLink );
233 // Obtain the string for the dialog
234 bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
235 String* pType,
236 String* pFile,
237 String* pLinkStr,
238 String* pFilter ) const
240 bool bRet = false;
241 const String sLNm( pLink->GetLinkSourceName() );
242 if( sLNm.Len() )
244 switch( pLink->GetObjType() )
246 case OBJECT_CLIENT_FILE:
247 case OBJECT_CLIENT_GRF:
248 case OBJECT_CLIENT_OLE:
250 sal_uInt16 nPos = 0;
251 String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
252 String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
254 if( pFile )
255 *pFile = sFile;
256 if( pLinkStr )
257 *pLinkStr = sRange;
258 if( pFilter )
259 *pFilter = sLNm.Copy( nPos );
261 if( pType )
263 sal_uInt16 nObjType = pLink->GetObjType();
264 *pType = String( SfxResId(
265 ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
266 ? RID_SVXSTR_FILELINK
267 : RID_SVXSTR_GRAFIKLINK ));
269 bRet = true;
271 break;
272 case OBJECT_CLIENT_DDE:
274 sal_uInt16 nTmp = 0;
275 String sCmd( sLNm );
276 String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
277 String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
279 if( pType )
280 *pType = sServer;
281 if( pFile )
282 *pFile = sTopic;
283 if( pLinkStr )
284 *pLinkStr = sCmd.Copy( nTmp );
285 bRet = true;
287 break;
288 default:
289 break;
293 return bRet;
296 bool LinkManager::GetDisplayNames(
297 const SvBaseLink* pLink, rtl::OUString* pType, rtl::OUString* pFile,
298 rtl::OUString* pLinkStr, rtl::OUString* pFilter) const
300 String aType, aFile, aLinkStr, aFilter;
301 bool bRet = GetDisplayNames(pLink, &aType, &aFile, &aLinkStr, &aFilter);
302 if (pType)
303 *pType = aType;
304 if (pFile)
305 *pFile = aFile;
306 if (pLinkStr)
307 *pLinkStr = aLinkStr;
308 if (pFilter)
309 *pFilter = aFilter;
310 return bRet;
313 void LinkManager::UpdateAllLinks(
314 sal_Bool bAskUpdate,
315 sal_Bool /*bCallErrHdl*/,
316 sal_Bool bUpdateGrfLinks,
317 Window* pParentWin )
319 // First make a copy of the array in order to update links
320 // links in ... no contact between them!
321 SvPtrarr aTmpArr( 255 );
322 sal_uInt16 n;
323 for( n = 0; n < aLinkTbl.Count(); ++n )
325 SvBaseLink* pLink = *aLinkTbl[ n ];
326 if( !pLink )
328 Remove( n-- );
329 continue;
331 aTmpArr.Insert( pLink, aTmpArr.Count() );
334 for( n = 0; n < aTmpArr.Count(); ++n )
336 SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ];
338 // search first in the array after the entry
339 sal_uInt16 nFndPos = USHRT_MAX;
340 for( sal_uInt16 i = 0; i < aLinkTbl.Count(); ++i )
341 if( pLink == *aLinkTbl[ i ] )
343 nFndPos = i;
344 break;
347 if( USHRT_MAX == nFndPos )
348 continue; // was not available!
350 // Graphic-Links not to update yet
351 if( !pLink->IsVisible() ||
352 ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
353 continue;
355 if( bAskUpdate )
357 int nRet = QueryBox( pParentWin, WB_YES_NO | WB_DEF_YES, SfxResId( STR_QUERY_UPDATE_LINKS ) ).Execute();
358 if( RET_YES != nRet )
359 return ; // nothing should be updated
360 bAskUpdate = sal_False; // once is enough
363 pLink->Update();
365 CloseCachedComps();
368 //--------------------------------------------------------------------------
370 SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
372 switch( pLink->GetObjType() )
374 case OBJECT_CLIENT_FILE:
375 case OBJECT_CLIENT_GRF:
376 case OBJECT_CLIENT_OLE:
377 return new SvFileObject;
378 case OBJECT_INTERN:
379 return new SvxInternalLink;
380 case OBJECT_CLIENT_DDE:
381 return new SvDDEObject;
382 default:
383 return SvLinkSourceRef();
387 sal_Bool LinkManager::InsertServer( SvLinkSource* pObj )
389 // no duplicate inserts
390 if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) )
391 return sal_False;
393 aServerTbl.Insert( pObj, aServerTbl.Count() );
394 return sal_True;
398 void LinkManager::RemoveServer( SvLinkSource* pObj )
400 sal_uInt16 nPos = aServerTbl.GetPos( pObj );
401 if( USHRT_MAX != nPos )
402 aServerTbl.Remove( nPos, 1 );
406 void MakeLnkName( String& rName, const String* pType, const String& rFile,
407 const String& rLink, const String* pFilter )
409 if( pType )
410 (rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator;
411 else if( rName.Len() )
412 rName.Erase();
414 ((rName += rFile).EraseLeadingChars().EraseTrailingChars() +=
415 cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink;
416 if( pFilter )
417 ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars();
420 void LinkManager::ReconnectDdeLink(SfxObjectShell& rServer)
422 SfxMedium* pMed = rServer.GetMedium();
423 if (!pMed)
424 return;
426 const ::sfx2::SvBaseLinks& rLinks = GetLinks();
427 sal_uInt16 n = rLinks.Count();
429 for (sal_uInt16 i = 0; i < n; ++i)
431 ::sfx2::SvBaseLink* p = *rLinks[i];
432 String aType, aFile, aLink, aFilter;
433 if (!GetDisplayNames(p, &aType, &aFile, &aLink, &aFilter))
434 continue;
436 if (!aType.EqualsAscii("soffice"))
437 // DDE connections between OOo apps are always named 'soffice'.
438 continue;
440 rtl::OUString aTmp;
441 OUString aURL = aFile;
442 if (utl::LocalFileHelper::ConvertPhysicalNameToURL(aFile, aTmp))
443 aURL = aTmp;
445 if (!aURL.equalsIgnoreAsciiCase(pMed->GetName()))
446 // This DDE link is not associated with this server shell... Skip it.
447 continue;
449 if (!aLink.Len())
450 continue;
452 LinkServerShell(aLink, rServer, *p);
456 void LinkManager::LinkServerShell(const OUString& rPath, SfxObjectShell& rServer, ::sfx2::SvBaseLink& rLink) const
458 ::sfx2::SvLinkSource* pSrvSrc = rServer.DdeCreateLinkSource(rPath);
459 if (pSrvSrc)
461 ::com::sun::star::datatransfer::DataFlavor aFl;
462 SotExchange::GetFormatDataFlavor(rLink.GetContentType(), aFl);
463 rLink.SetObj(pSrvSrc);
464 pSrvSrc->AddDataAdvise(
465 &rLink, aFl.MimeType,
466 sfx2::LINKUPDATE_ONCALL == rLink.GetUpdateMode() ? ADVISEMODE_ONLYONCE : 0);
470 bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink,
471 sal_uInt16 nFileType,
472 const String& rFileNm,
473 const String* pFilterNm,
474 const String* pRange )
476 if( !( OBJECT_CLIENT_SO & rLink.GetObjType() ))
477 return false;
479 String sCmd( rFileNm );
480 sCmd += ::sfx2::cTokenSeperator;
481 if( pRange )
482 sCmd += *pRange;
483 if( pFilterNm )
484 ( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm;
486 return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd );
489 bool LinkManager::InsertFileLink(
490 sfx2::SvBaseLink& rLink, sal_uInt16 nFileType, const rtl::OUString& rFileNm,
491 const rtl::OUString* pFilterNm, const rtl::OUString* pRange)
493 if (!(OBJECT_CLIENT_SO & rLink.GetObjType()))
494 return false;
496 rtl::OUStringBuffer aBuf;
497 aBuf.append(rFileNm);
498 aBuf.append(sfx2::cTokenSeperator);
500 if (pRange)
501 aBuf.append(*pRange);
503 if (pFilterNm)
505 aBuf.append(sfx2::cTokenSeperator);
506 aBuf.append(*pFilterNm);
509 String aCmd = aBuf.makeStringAndClear();
510 return InsertLink(&rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &aCmd);
513 // A transfer is aborted, so cancel all download media
514 // (for now this is only of interest for the file links!)
515 void LinkManager::CancelTransfers()
517 SvFileObject* pFileObj;
518 sfx2::SvBaseLink* pLnk;
520 const sfx2::SvBaseLinks& rLnks = GetLinks();
521 for( sal_uInt16 n = rLnks.Count(); n; )
522 if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
523 OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
524 0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) )
525 pFileObj->CancelTransfers();
527 // For the purpose of sending Status information from the file object to
528 // the base link, there exist a dedicated ClipBoardId. The SvData-object
529 // gets the appropriate information as a string
530 // For now this is required for file object in conjunction with JavaScript
531 // - needs information about Load/Abort/Error
532 sal_uIntPtr LinkManager::RegisterStatusInfoId()
534 static sal_uIntPtr nFormat = 0;
536 if( !nFormat )
538 nFormat = SotExchange::RegisterFormatName(
539 String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
540 "StatusInfo from SvxInternalLink" )));
542 return nFormat;
545 // ----------------------------------------------------------------------
547 sal_Bool LinkManager::GetGraphicFromAny( const String& rMimeType,
548 const ::com::sun::star::uno::Any & rValue,
549 Graphic& rGrf )
551 sal_Bool bRet = sal_False;
552 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
553 if( rValue.hasValue() && ( rValue >>= aSeq ) )
555 SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
556 STREAM_READ );
557 aMemStm.Seek( 0 );
559 switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
561 case SOT_FORMATSTR_ID_SVXB:
563 aMemStm >> rGrf;
564 bRet = sal_True;
566 break;
567 case FORMAT_GDIMETAFILE:
569 GDIMetaFile aMtf;
570 aMtf.Read( aMemStm );
571 rGrf = aMtf;
572 bRet = sal_True;
574 break;
575 case FORMAT_BITMAP:
577 Bitmap aBmp;
578 aMemStm >> aBmp;
579 rGrf = aBmp;
580 bRet = sal_True;
582 break;
585 return bRet;
589 // ----------------------------------------------------------------------
590 String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL )
592 String sRet;
593 INetURLObject aURL( rTopic );
594 if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
595 utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
596 if( !sRet.Len() )
597 sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
598 return sRet;
601 sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
603 SfxObjectShell* pFndShell = 0;
604 sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
605 String sTopic, sItem, sReferer;
606 LinkManager* pLinkMgr = pLink->GetLinkManager();
607 if (pLinkMgr && pLinkMgr->GetDisplayNames(pLink, 0, &sTopic, &sItem) && sTopic.Len())
609 // first only loop over the DocumentShells the shells and find those
610 // with the name:
611 com::sun::star::lang::Locale aLocale;
612 MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale );
613 CharClass aCC( aLocale );
615 TypeId aType( TYPE(SfxObjectShell) );
617 sal_Bool bFirst = sal_True;
618 SfxObjectShell* pShell = pLinkMgr->GetPersist();
619 if( pShell && pShell->GetMedium() )
621 sReferer = pShell->GetMedium()->GetBaseURL();
622 SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False );
623 if ( pItem )
624 nUpdateMode = pItem->GetValue();
627 String sNmURL(aCC.lowercase(lcl_DDE_RelToAbs(sTopic, sReferer)));
629 if ( !pShell )
631 bFirst = sal_False;
632 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
635 String sTmp;
636 while( pShell )
638 if( !sTmp.Len() )
640 sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
641 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
645 sTmp = aCC.lowercase( sTmp );
646 if( sTmp == sNmURL ) // we want these
648 pFndShell = pShell;
649 break;
652 if( bFirst )
654 bFirst = sal_False;
655 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
657 else
658 pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False );
660 sTmp.Erase();
664 // empty topics are not allowed - which document is it
665 if( !sTopic.Len() )
666 return sal_False;
668 if (pFndShell)
670 sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
671 if( pNewSrc )
673 ::com::sun::star::datatransfer::DataFlavor aFl;
674 SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
676 pLink->SetObj( pNewSrc );
677 pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
678 sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
679 ? ADVISEMODE_ONLYONCE
680 : 0 );
681 return true;
684 else
686 // then try to download the file:
687 INetURLObject aURL( sTopic );
688 INetProtocol eOld = aURL.GetProtocol();
689 aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
690 if( INET_PROT_NOT_VALID != eOld ||
691 INET_PROT_HTTP != aURL.GetProtocol() )
693 SfxStringItem aName( SID_FILE_NAME, sTopic );
694 SfxBoolItem aMinimized(SID_MINIMIZED, sal_True);
695 SfxBoolItem aHidden(SID_HIDDEN, sal_True);
696 SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
697 SfxStringItem aReferer( SID_REFERER, sReferer );
698 SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
699 SfxBoolItem aReadOnly(SID_DOC_READONLY, false);
701 // Disable automatic re-connection to avoid this link instance
702 // being destroyed at re-connection.
703 SfxBoolItem aDdeConnect(SID_DDE_RECONNECT_ONLOAD, false);
705 // #i14200# (DDE-link crashes wordprocessor)
706 SfxAllItemSet aArgs( SFX_APP()->GetPool() );
707 aArgs.Put(aReferer);
708 aArgs.Put(aTarget);
709 aArgs.Put(aHidden);
710 aArgs.Put(aMinimized);
711 aArgs.Put(aName);
712 aArgs.Put(aUpdate);
713 aArgs.Put(aReadOnly);
714 aArgs.Put(aDdeConnect);
715 Reference<XComponent> xComp = SfxObjectShell::CreateAndLoadComponent(aArgs);
716 pFndShell = SfxObjectShell::GetShellFromComponent(xComp);
717 if (xComp.is() && pFndShell)
719 pLinkMgr->InsertCachedComp(xComp);
720 pLinkMgr->LinkServerShell(sItem, *pFndShell, *pLink);
721 return true;
726 return false;
734 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */