xref: /aoo41x/main/sfx2/source/appl/linkmgr2.cxx (revision 611fcdab)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_sfx2.hxx"
24 
25 #include <sfx2/linkmgr.hxx>
26 #include <com/sun/star/document/UpdateDocMode.hpp>
27 #include <sfx2/objsh.hxx>
28 #include <svl/urihelper.hxx>
29 #include <sot/formats.hxx>
30 #include <tools/urlobj.hxx>
31 #include <sot/exchange.hxx>
32 #include <tools/debug.hxx>
33 #include <vcl/msgbox.hxx>
34 #include <sfx2/lnkbase.hxx>
35 #include <sfx2/app.hxx>
36 #include <vcl/graph.hxx>
37 #include <svl/stritem.hxx>
38 #include <svl/eitem.hxx>
39 #include <svl/intitem.hxx>
40 #include <unotools/localfilehelper.hxx>
41 #include <i18npool/mslangid.hxx>
42 #include <sfx2/request.hxx>
43 #include <vcl/dibtools.hxx>
44 
45 #include "fileobj.hxx"
46 #include "impldde.hxx"
47 #include "app.hrc"
48 #include "sfx2/sfxresid.hxx"
49 
50 #define _SVSTDARR_STRINGSDTOR
51 #include <svl/svstdarr.hxx>
52 
53 namespace sfx2
54 {
55 
56 class SvxInternalLink : public sfx2::SvLinkSource
57 {
58 public:
59 	SvxInternalLink() {}
60 
61     virtual sal_Bool Connect( sfx2::SvBaseLink* );
62 };
63 
64 
65 SV_IMPL_PTRARR( SvBaseLinks, SvBaseLinkRefPtr )
66 
67 LinkManager::LinkManager(SfxObjectShell* p)
68 	: pPersist(p),
69 	mUpdateAsked(sal_False),
70 	mAutoAskUpdateAllLinks(sal_False)
71 {
72 }
73 
74 LinkManager::~LinkManager()
75 {
76 	SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
77 	for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
78 	{
79 		if( (*ppRef)->Is() )
80 		{
81 			(*(*ppRef))->Disconnect();
82             (*(*ppRef))->SetLinkManager( NULL );
83 		}
84 		delete *ppRef;
85 	}
86 }
87 
88 
89 /************************************************************************
90 |*    LinkManager::Remove()
91 |*
92 |*    Beschreibung
93 *************************************************************************/
94 
95 void LinkManager::Remove( SvBaseLink *pLink )
96 {
97 	// keine Links doppelt einfuegen
98 	int bFound = sal_False;
99 	SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData();
100 	for( sal_uInt16 n = aLinkTbl.Count(); n; --n, ++ppRef )
101 	{
102 		if( pLink == *(*ppRef) )
103 		{
104 			(*(*ppRef))->Disconnect();
105             (*(*ppRef))->SetLinkManager( NULL );
106 			(*(*ppRef)).Clear();
107 			bFound = sal_True;
108 		}
109 
110 		// falls noch leere rum stehen sollten, weg damit
111 		if( !(*ppRef)->Is() )
112 		{
113 			delete *ppRef;
114 			aLinkTbl.Remove( aLinkTbl.Count() - n, 1 );
115 			if( bFound )
116 				return ;
117 			--ppRef;
118 		}
119 	}
120 }
121 
122 
123 void LinkManager::Remove( sal_uInt16 nPos, sal_uInt16 nCnt )
124 {
125 	if( nCnt && nPos < aLinkTbl.Count() )
126 	{
127 		if( nPos + nCnt > aLinkTbl.Count() )
128 			nCnt = aLinkTbl.Count() - nPos;
129 
130 		SvBaseLinkRef** ppRef = (SvBaseLinkRef**)aLinkTbl.GetData() + nPos;
131 		for( sal_uInt16 n = nCnt; n; --n, ++ppRef )
132 		{
133 			if( (*ppRef)->Is() )
134 			{
135 				(*(*ppRef))->Disconnect();
136                 (*(*ppRef))->SetLinkManager( NULL );
137 			}
138 			delete *ppRef;
139 		}
140 		aLinkTbl.Remove( nPos, nCnt );
141 	}
142 }
143 
144 
145 sal_Bool LinkManager::Insert( SvBaseLink* pLink )
146 {
147 	// keine Links doppelt einfuegen
148 	for( sal_uInt16 n = 0; n < aLinkTbl.Count(); ++n )
149 	{
150 		SvBaseLinkRef* pTmp = aLinkTbl[ n ];
151 		if( !pTmp->Is() )
152 			aLinkTbl.DeleteAndDestroy( n-- );
153 
154 		if( pLink == *pTmp )
155 			return sal_False;
156 	}
157 
158 	SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
159     pLink->SetLinkManager( this );
160 	aLinkTbl.Insert( pTmp, aLinkTbl.Count() );
161 	Window *parent = GetPersist()->GetDialogParent();
162 	if (mAutoAskUpdateAllLinks)
163 	{
164 		SetUserAllowsLinkUpdate(pLink, GetUserAllowsLinkUpdate(parent));
165 	}
166 
167 	return sal_True;
168 }
169 
170 
171 sal_Bool LinkManager::InsertLink( SvBaseLink * pLink,
172 								sal_uInt16 nObjType,
173 								sal_uInt16 nUpdateMode,
174 								const String* pName )
175 {
176 	// unbedingt zuerst
177 	pLink->SetObjType( nObjType );
178 	if( pName )
179 		pLink->SetName( *pName );
180 	pLink->SetUpdateMode( nUpdateMode );
181 	return Insert( pLink );
182 }
183 
184 
185 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink,
186 									const String& rServer,
187 									const String& rTopic,
188 									const String& rItem )
189 {
190 	if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
191 		return sal_False;
192 
193 	String sCmd;
194 	::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
195 
196 	pLink->SetObjType( OBJECT_CLIENT_DDE );
197 	pLink->SetName( sCmd );
198 	return Insert( pLink );
199 }
200 
201 
202 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink )
203 {
204 	DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
205 	if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
206 		return sal_False;
207 
208 	if( pLink->GetObjType() == OBJECT_CLIENT_SO )
209 		pLink->SetObjType( OBJECT_CLIENT_DDE );
210 
211 	return Insert( pLink );
212 }
213 
214 
215 // erfrage die Strings fuer den Dialog
216 sal_Bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
217 										String* pType,
218 										String* pFile,
219 										String* pLinkStr,
220 										String* pFilter ) const
221 {
222 	sal_Bool bRet = sal_False;
223 	const String sLNm( pLink->GetLinkSourceName() );
224 	if( sLNm.Len() )
225 	{
226 		switch( pLink->GetObjType() )
227 		{
228 		    case OBJECT_CLIENT_FILE:
229 		    case OBJECT_CLIENT_GRF:
230 		    case OBJECT_CLIENT_OLE:
231 			    {
232 				    sal_uInt16 nPos = 0;
233 				    String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
234 				    String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
235 
236 				    if( pFile )
237 					    *pFile = sFile;
238 				    if( pLinkStr )
239 					    *pLinkStr = sRange;
240 				    if( pFilter )
241 					    *pFilter = sLNm.Copy( nPos );
242 
243 				    if( pType )
244 				    {
245 					    sal_uInt16 nObjType = pLink->GetObjType();
246 					    *pType = String( SfxResId(
247 								    ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
248 										    ? RID_SVXSTR_FILELINK
249 										    : RID_SVXSTR_GRAFIKLINK ));
250 				    }
251 				    bRet = sal_True;
252 			    }
253 			    break;
254 		    case OBJECT_CLIENT_DDE:
255 	            {
256 		            sal_uInt16 nTmp = 0;
257 		            String sCmd( sLNm );
258 		            String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
259 		            String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
260 
261 		            if( pType )
262 			            *pType = sServer;
263 		            if( pFile )
264 			            *pFile = sTopic;
265 		            if( pLinkStr )
266 			            *pLinkStr = sCmd.Copy( nTmp );
267 		            bRet = sal_True;
268 		        }
269 		        break;
270 	        default:
271 	            break;
272 	    }
273 	}
274 
275 	return bRet;
276 }
277 
278 void LinkManager::SetAutoAskUpdateAllLinks()
279 {
280 	mAutoAskUpdateAllLinks = sal_True;
281 }
282 
283 sal_Bool LinkManager::GetUserAllowsLinkUpdate(Window *pParentWin)
284 {
285 	if (!mUpdateAsked)
286 	{
287 		if (QueryBox(pParentWin, WB_YES_NO | WB_DEF_NO, SfxResId(STR_QUERY_UPDATE_LINKS)).Execute() == RET_YES)
288 			mAllowUpdate = sal_True;
289 		else
290 			mAllowUpdate = sal_False;
291 		mUpdateAsked = sal_True;
292 	}
293 	return mAllowUpdate;
294 }
295 
296 void LinkManager::SetUserAllowsLinkUpdate(SvBaseLink *pLink, sal_Bool allows)
297 {
298 	SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
299 
300 	if (pShell)
301 	{
302 		comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = pShell->getEmbeddedObjectContainer();
303 		rEmbeddedObjectContainer.setUserAllowsLinkUpdate(allows);
304 	}
305 }
306 
307 
308 void LinkManager::UpdateAllLinks(
309     sal_Bool bAskUpdate,
310     sal_Bool /*bCallErrHdl*/,
311     sal_Bool bUpdateGrfLinks,
312     Window* pParentWin )
313 {
314 	SvStringsDtor aApps, aTopics, aItems;
315 	String sApp, sTopic, sItem;
316 
317 	// erstmal eine Kopie vom Array machen, damit sich updatende Links in
318 	// Links in ... nicht dazwischen funken!!
319 	SvPtrarr aTmpArr( 255, 50 );
320 	sal_uInt16 n;
321 	for( n = 0; n < aLinkTbl.Count(); ++n )
322 	{
323 		SvBaseLink* pLink = *aLinkTbl[ n ];
324 		if( !pLink )
325 		{
326 			Remove( n-- );
327 			continue;
328 		}
329 		aTmpArr.Insert( pLink, aTmpArr.Count() );
330 	}
331 
332 	for( n = 0; n < aTmpArr.Count(); ++n )
333 	{
334 		SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ];
335 
336 		// suche erstmal im Array nach dem Eintrag
337 		sal_uInt16 nFndPos = USHRT_MAX;
338 		for( sal_uInt16 i = 0; i < aLinkTbl.Count(); ++i )
339 			if( pLink == *aLinkTbl[ i ] )
340 			{
341 				nFndPos = i;
342 				break;
343 			}
344 
345 		if( USHRT_MAX == nFndPos )
346 			continue;					// war noch nicht vorhanden!
347 
348 		// do not update graphic links yet
349 		if( !pLink->IsVisible() ||
350 			( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
351 			continue;
352 
353 		sal_Bool allows = sal_False;
354 
355 		if (bAskUpdate)
356 		{
357 			allows = GetUserAllowsLinkUpdate(pParentWin);
358 		}
359 
360 		SetUserAllowsLinkUpdate(pLink, allows);
361 	    bAskUpdate = sal_False;		// one time is OK
362 
363 		if (allows)
364 			pLink->Update();
365 
366 	}
367 }
368 
369 /************************************************************************
370 |*    SvBaseLink::CreateObject()
371 |*
372 |*    Beschreibung
373 *************************************************************************/
374 
375 SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
376 {
377 	switch( pLink->GetObjType() )
378 	{
379 	    case OBJECT_CLIENT_FILE:
380 	    case OBJECT_CLIENT_GRF:
381 	    case OBJECT_CLIENT_OLE:
382 		    return new SvFileObject;
383 	    case OBJECT_INTERN:
384 		    return new SvxInternalLink;
385         case OBJECT_CLIENT_DDE:
386 		    return new SvDDEObject;
387 	    default:
388         	return SvLinkSourceRef();
389    	}
390 }
391 
392 sal_Bool LinkManager::InsertServer( SvLinkSource* pObj )
393 {
394 	// keine doppelt einfuegen
395 	if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) )
396 		return sal_False;
397 
398 	aServerTbl.Insert( pObj, aServerTbl.Count() );
399 	return sal_True;
400 }
401 
402 
403 void LinkManager::RemoveServer( SvLinkSource* pObj )
404 {
405 	sal_uInt16 nPos = aServerTbl.GetPos( pObj );
406 	if( USHRT_MAX != nPos )
407 		aServerTbl.Remove( nPos, 1 );
408 }
409 
410 
411 void MakeLnkName( String& rName, const String* pType, const String& rFile,
412 					const String& rLink, const String* pFilter )
413 {
414 	if( pType )
415 		(rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator;
416 	else if( rName.Len() )
417 		rName.Erase();
418 
419 	((rName += rFile).EraseLeadingChars().EraseTrailingChars() +=
420 		cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink;
421 	if( pFilter )
422 		((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars();
423 }
424 
425 sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink,
426 									sal_uInt16 nFileType,
427 									const String& rFileNm,
428 									const String* pFilterNm,
429 									const String* pRange )
430 {
431 	if( !( OBJECT_CLIENT_SO & rLink.GetObjType() ))
432 		return sal_False;
433 
434 	String sCmd( rFileNm );
435 	sCmd += ::sfx2::cTokenSeperator;
436 	if( pRange )
437 		sCmd += *pRange;
438 	if( pFilterNm )
439 		( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm;
440 
441 	return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd );
442 }
443 
444 sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink )
445 {
446 	if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() ))
447 		return InsertLink( &rLink, rLink.GetObjType(), sfx2::LINKUPDATE_ONCALL );
448 	return sal_False;
449 }
450 
451 // eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln
452 // (ist zur Zeit nur fuer die FileLinks interressant!)
453 void LinkManager::CancelTransfers()
454 {
455 	SvFileObject* pFileObj;
456 	sfx2::SvBaseLink* pLnk;
457 
458 	const sfx2::SvBaseLinks& rLnks = GetLinks();
459 	for( sal_uInt16 n = rLnks.Count(); n; )
460 		if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
461 			OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
462 			0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) )
463 //			0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()->
464 //									CastAndAddRef( pLnk->GetObj() )) )
465 			pFileObj->CancelTransfers();
466 }
467 
468 	// um Status Informationen aus dem FileObject an den BaseLink zu
469 	// senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat
470 	// dann die entsprechenden Informationen als String.
471 	// Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt
472 	// - das braucht Informationen ueber Load/Abort/Error
473 sal_uIntPtr LinkManager::RegisterStatusInfoId()
474 {
475 	static sal_uIntPtr nFormat = 0;
476 
477 	if( !nFormat )
478 	{
479 // wie sieht die neue Schnittstelle aus?
480 //		nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" );
481 		nFormat = SotExchange::RegisterFormatName(
482 					String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
483 								"StatusInfo vom SvxInternalLink" )));
484 	}
485 	return nFormat;
486 }
487 
488 // ----------------------------------------------------------------------
489 
490 sal_Bool LinkManager::GetGraphicFromAny( const String& rMimeType,
491 								const ::com::sun::star::uno::Any & rValue,
492 								Graphic& rGrf )
493 {
494 	sal_Bool bRet = sal_False;
495 	::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
496 	if( rValue.hasValue() && ( rValue >>= aSeq ) )
497 	{
498 		SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
499 								STREAM_READ );
500 		aMemStm.Seek( 0 );
501 
502 		switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
503 		{
504 		case SOT_FORMATSTR_ID_SVXB:
505 			{
506 				aMemStm >> rGrf;
507 				bRet = sal_True;
508 			}
509 			break;
510 		case FORMAT_GDIMETAFILE:
511 			{
512 				GDIMetaFile aMtf;
513 				aMtf.Read( aMemStm );
514 				rGrf = aMtf;
515 				bRet = sal_True;
516 			}
517 			break;
518 		case FORMAT_BITMAP:
519 			{
520 				Bitmap aBmp;
521                 ReadDIB(aBmp, aMemStm, true);
522 				rGrf = aBmp;
523 				bRet = sal_True;
524 			}
525 			break;
526 		}
527 	}
528 	return bRet;
529 }
530 
531 
532 // ----------------------------------------------------------------------
533 String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL )
534 {
535 	String sRet;
536 	INetURLObject aURL( rTopic );
537 	if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
538         utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
539 	if( !sRet.Len() )
540         sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
541 	return sRet;
542 }
543 
544 sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
545 {
546 	SfxObjectShell* pFndShell = 0;
547 	sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
548 	String sTopic, sItem, sReferer;
549 	if( pLink->GetLinkManager() &&
550 		pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem )
551 		&& sTopic.Len() )
552 	{
553 		// erstmal nur ueber die DocumentShells laufen und die mit dem
554 		// Namen heraussuchen:
555 
556 	    com::sun::star::lang::Locale aLocale;
557 	    MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale );
558 		CharClass aCC( aLocale );
559 
560         String sNm( sTopic ), sTmp;
561 		aCC.toLower( sNm );
562 
563 		TypeId aType( TYPE(SfxObjectShell) );
564 
565 		sal_Bool bFirst = sal_True;
566         SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
567         if( pShell && pShell->GetMedium() )
568 		{
569             sReferer = pShell->GetMedium()->GetBaseURL();
570 			SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False );
571 			if ( pItem )
572 				nUpdateMode = pItem->GetValue();
573 		}
574 
575         String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) );
576 		aCC.toLower( sNmURL );
577 
578 		if ( !pShell )
579 		{
580 			bFirst = sal_False;
581             pShell = SfxObjectShell::GetFirst( &aType, sal_False );
582 		}
583 
584 		while( pShell )
585 		{
586 			if( !sTmp.Len() )
587 			{
588 				sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
589                 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
590 			}
591 
592 
593 			aCC.toLower( sTmp );
594 			if( sTmp == sNmURL )		// die wollen wir haben
595 			{
596 				pFndShell = pShell;
597 				break;
598 			}
599 
600 			if( bFirst )
601 			{
602 				bFirst = sal_False;
603                 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
604 			}
605 			else
606                 pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False );
607 
608 			sTmp.Erase();
609 		}
610 	}
611 
612 	// empty topics are not allowed - which document is it
613 	if( !sTopic.Len() )
614 		return sal_False;
615 
616 	if( !pFndShell )
617 	{
618 		// dann versuche die Datei zu laden:
619 		INetURLObject aURL( sTopic );
620 		INetProtocol eOld = aURL.GetProtocol();
621         aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
622 		if( INET_PROT_NOT_VALID != eOld ||
623 			INET_PROT_HTTP != aURL.GetProtocol() )
624 		{
625 			SfxStringItem aName( SID_FILE_NAME, sTopic );
626             SfxBoolItem aMinimized(SID_MINIMIZED, sal_True);
627             SfxBoolItem aHidden(SID_HIDDEN, sal_True);
628             SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
629 			SfxStringItem aReferer( SID_REFERER, sReferer );
630 			SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
631             SfxBoolItem aReadOnly(SID_DOC_READONLY, sal_True);
632 
633             // #i14200# (DDE-link crashes wordprocessor)
634             SfxAllItemSet aArgs( SFX_APP()->GetPool() );
635             aArgs.Put(aReferer);
636             aArgs.Put(aTarget);
637             aArgs.Put(aHidden);
638             aArgs.Put(aMinimized);
639             aArgs.Put(aName);
640 			aArgs.Put(aUpdate);
641 			aArgs.Put(aReadOnly);
642             pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs );
643 		}
644 	}
645 
646 	sal_Bool bRet = sal_False;
647 	if( pFndShell )
648 	{
649 		sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
650 		if( pNewSrc )
651 		{
652 			bRet = sal_True;
653 
654 			::com::sun::star::datatransfer::DataFlavor aFl;
655 			SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
656 
657 			pLink->SetObj( pNewSrc );
658 			pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
659 								sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
660 									? ADVISEMODE_ONLYONCE
661 									: 0 );
662 		}
663 	}
664 	return bRet;
665 }
666 
667 
668 }
669 
670 
671 
672