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:
SvxInternalLink()59 SvxInternalLink() {}
60
61 virtual sal_Bool Connect( sfx2::SvBaseLink* );
62 };
63
64
SV_IMPL_PTRARR(SvBaseLinks,SvBaseLinkRefPtr)65 SV_IMPL_PTRARR( SvBaseLinks, SvBaseLinkRefPtr )
66
67 LinkManager::LinkManager(SfxObjectShell* p)
68 : pPersist(p),
69 mAutoAskUpdateAllLinks(sal_False),
70 mUpdateAsked(sal_False)
71 {
72 }
73
~LinkManager()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 |* Description
93 *************************************************************************/
94
Remove(SvBaseLink * pLink)95 void LinkManager::Remove( SvBaseLink *pLink )
96 {
97 // do not insert links double
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 // if there are still some empty ones, get rid of them
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
Remove(sal_uInt16 nPos,sal_uInt16 nCnt)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
Insert(SvBaseLink * pLink)145 sal_Bool LinkManager::Insert( SvBaseLink* pLink )
146 {
147
148 // do not insert links double
149 for( sal_uInt16 n = 0; n < aLinkTbl.Count(); ++n )
150 {
151 SvBaseLinkRef* pTmp = aLinkTbl[ n ];
152 if( !pTmp->Is() )
153 aLinkTbl.DeleteAndDestroy( n-- );
154
155 if( pLink == *pTmp )
156 return sal_False;
157 }
158
159 SvBaseLinkRef* pTmp = new SvBaseLinkRef( pLink );
160 pLink->SetLinkManager( this );
161 aLinkTbl.Insert( pTmp, aLinkTbl.Count() );
162 if (mAutoAskUpdateAllLinks)
163 {
164 Window *parent = NULL;
165 SfxObjectShell* persist = GetPersist();
166 if (persist != NULL)
167 parent = GetPersist()->GetDialogParent();
168
169 SetUserAllowsLinkUpdate(pLink, GetUserAllowsLinkUpdate(parent));
170 }
171
172 return sal_True;
173 }
174
175
InsertLink(SvBaseLink * pLink,sal_uInt16 nObjType,sal_uInt16 nUpdateMode,const String * pName)176 sal_Bool LinkManager::InsertLink( SvBaseLink * pLink,
177 sal_uInt16 nObjType,
178 sal_uInt16 nUpdateMode,
179 const String* pName )
180 {
181 // in any case: do this first
182 pLink->SetObjType( nObjType );
183 if( pName )
184 pLink->SetName( *pName );
185 pLink->SetUpdateMode( nUpdateMode );
186 return Insert( pLink );
187 }
188
189
InsertDDELink(SvBaseLink * pLink,const String & rServer,const String & rTopic,const String & rItem)190 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink,
191 const String& rServer,
192 const String& rTopic,
193 const String& rItem )
194 {
195 if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
196 return sal_False;
197
198 String sCmd;
199 ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
200
201 pLink->SetObjType( OBJECT_CLIENT_DDE );
202 pLink->SetName( sCmd );
203 return Insert( pLink );
204 }
205
206
InsertDDELink(SvBaseLink * pLink)207 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink )
208 {
209 DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
210 if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
211 return sal_False;
212
213 if( pLink->GetObjType() == OBJECT_CLIENT_SO )
214 pLink->SetObjType( OBJECT_CLIENT_DDE );
215
216 return Insert( pLink );
217 }
218
219
220 // ask for the strings to be used in the dialog
GetDisplayNames(const SvBaseLink * pLink,String * pType,String * pFile,String * pLinkStr,String * pFilter) const221 sal_Bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
222 String* pType,
223 String* pFile,
224 String* pLinkStr,
225 String* pFilter ) const
226 {
227 sal_Bool bRet = sal_False;
228 const String sLNm( pLink->GetLinkSourceName() );
229 if( sLNm.Len() )
230 {
231 switch( pLink->GetObjType() )
232 {
233 case OBJECT_CLIENT_FILE:
234 case OBJECT_CLIENT_GRF:
235 case OBJECT_CLIENT_OLE:
236 {
237 sal_uInt16 nPos = 0;
238 String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
239 String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
240
241 if( pFile )
242 *pFile = sFile;
243 if( pLinkStr )
244 *pLinkStr = sRange;
245 if( pFilter )
246 *pFilter = sLNm.Copy( nPos );
247
248 if( pType )
249 {
250 sal_uInt16 nObjType = pLink->GetObjType();
251 *pType = String( SfxResId(
252 ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
253 ? RID_SVXSTR_FILELINK
254 : RID_SVXSTR_GRAFIKLINK ));
255 }
256 bRet = sal_True;
257 }
258 break;
259 case OBJECT_CLIENT_DDE:
260 {
261 sal_uInt16 nTmp = 0;
262 String sCmd( sLNm );
263 String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
264 String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
265
266 if( pType )
267 *pType = sServer;
268 if( pFile )
269 *pFile = sTopic;
270 if( pLinkStr )
271 *pLinkStr = sCmd.Copy( nTmp );
272 bRet = sal_True;
273 }
274 break;
275 default:
276 break;
277 }
278 }
279
280 return bRet;
281 }
282
SetAutoAskUpdateAllLinks()283 void LinkManager::SetAutoAskUpdateAllLinks()
284 {
285 mAutoAskUpdateAllLinks = sal_True;
286 mUpdateAsked = sal_False;
287 }
288
SetNeverAskUpdateAllLinks()289 void LinkManager::SetNeverAskUpdateAllLinks()
290 {
291 mAutoAskUpdateAllLinks = sal_False;
292 mAllowUpdate = sal_True;
293 mUpdateAsked = sal_True;
294 }
295
GetUserAllowsLinkUpdate(Window * pParentWin)296 sal_Bool LinkManager::GetUserAllowsLinkUpdate(Window *pParentWin)
297 {
298 if (!mUpdateAsked)
299 {
300 if (QueryBox(pParentWin, WB_YES_NO | WB_DEF_NO, SfxResId(STR_QUERY_UPDATE_LINKS)).Execute() == RET_YES)
301 mAllowUpdate = sal_True;
302 else
303 mAllowUpdate = sal_False;
304 mUpdateAsked = sal_True;
305 }
306 return mAllowUpdate;
307 }
308
SetUserAllowsLinkUpdate(SvBaseLink * pLink,sal_Bool allows)309 void LinkManager::SetUserAllowsLinkUpdate(SvBaseLink *pLink, sal_Bool allows)
310 {
311 SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
312
313 if (pShell)
314 {
315 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = pShell->getEmbeddedObjectContainer();
316 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(allows);
317 }
318 }
319
320
UpdateAllLinks(sal_Bool bAskUpdate,sal_Bool,sal_Bool bUpdateGrfLinks,Window * pParentWin)321 void LinkManager::UpdateAllLinks(
322 sal_Bool bAskUpdate,
323 sal_Bool /*bCallErrHdl*/,
324 sal_Bool bUpdateGrfLinks,
325 Window* pParentWin )
326 {
327 SvStringsDtor aApps, aTopics, aItems;
328 String sApp, sTopic, sItem;
329
330 // first create a copy of the array, so that updated links to not interfere with ... in between!!
331 SvPtrarr aTmpArr( 255, 50 );
332 sal_uInt16 n;
333 for( n = 0; n < aLinkTbl.Count(); ++n )
334 {
335 SvBaseLink* pLink = *aLinkTbl[ n ];
336 if( !pLink )
337 {
338 Remove( n-- );
339 continue;
340 }
341 aTmpArr.Insert( pLink, aTmpArr.Count() );
342 }
343
344 for( n = 0; n < aTmpArr.Count(); ++n )
345 {
346 SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ];
347
348 // first search the entry in the array
349 sal_uInt16 nFndPos = USHRT_MAX;
350 for( sal_uInt16 i = 0; i < aLinkTbl.Count(); ++i )
351 if( pLink == *aLinkTbl[ i ] )
352 {
353 nFndPos = i;
354 break;
355 }
356
357 if( USHRT_MAX == nFndPos )
358 continue; // was not already existing!
359
360 // do not update graphic links yet
361 if( !pLink->IsVisible() ||
362 ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
363 continue;
364
365 sal_Bool allows = sal_True;
366
367 if (bAskUpdate)
368 {
369 allows = GetUserAllowsLinkUpdate(pParentWin);
370 }
371
372 SetUserAllowsLinkUpdate(pLink, allows);
373 bAskUpdate = sal_False; // one time is OK
374
375 if (allows)
376 pLink->Update();
377 }
378 }
379
380 /************************************************************************
381 |* SvBaseLink::CreateObject()
382 |*
383 |* Description
384 *************************************************************************/
385
CreateObj(SvBaseLink * pLink)386 SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
387 {
388 switch( pLink->GetObjType() )
389 {
390 case OBJECT_CLIENT_FILE:
391 case OBJECT_CLIENT_GRF:
392 case OBJECT_CLIENT_OLE:
393 return new SvFileObject;
394 case OBJECT_INTERN:
395 return new SvxInternalLink;
396 case OBJECT_CLIENT_DDE:
397 return new SvDDEObject;
398 default:
399 return SvLinkSourceRef();
400 }
401 }
402
InsertServer(SvLinkSource * pObj)403 sal_Bool LinkManager::InsertServer( SvLinkSource* pObj )
404 {
405 // do not insert double
406 if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) )
407 return sal_False;
408
409 aServerTbl.Insert( pObj, aServerTbl.Count() );
410 return sal_True;
411 }
412
413
RemoveServer(SvLinkSource * pObj)414 void LinkManager::RemoveServer( SvLinkSource* pObj )
415 {
416 sal_uInt16 nPos = aServerTbl.GetPos( pObj );
417 if( USHRT_MAX != nPos )
418 aServerTbl.Remove( nPos, 1 );
419 }
420
421
MakeLnkName(String & rName,const String * pType,const String & rFile,const String & rLink,const String * pFilter)422 void MakeLnkName( String& rName, const String* pType, const String& rFile,
423 const String& rLink, const String* pFilter )
424 {
425 if( pType )
426 (rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator;
427 else if( rName.Len() )
428 rName.Erase();
429
430 ((rName += rFile).EraseLeadingChars().EraseTrailingChars() +=
431 cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink;
432 if( pFilter )
433 ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars();
434 }
435
InsertFileLink(sfx2::SvBaseLink & rLink,sal_uInt16 nFileType,const String & rFileNm,const String * pFilterNm,const String * pRange)436 sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink,
437 sal_uInt16 nFileType,
438 const String& rFileNm,
439 const String* pFilterNm,
440 const String* pRange )
441 {
442 if( !( OBJECT_CLIENT_SO & rLink.GetObjType() ))
443 return sal_False;
444
445 String sCmd( rFileNm );
446 sCmd += ::sfx2::cTokenSeperator;
447 if( pRange )
448 sCmd += *pRange;
449 if( pFilterNm )
450 ( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm;
451
452 return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd );
453 }
454
InsertFileLink(sfx2::SvBaseLink & rLink)455 sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink )
456 {
457 if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() ))
458 return InsertLink( &rLink, rLink.GetObjType(), sfx2::LINKUPDATE_ONCALL );
459 return sal_False;
460 }
461
462 // a transfer will be discontinued, therefore cancel all DownloadMedia
463 // (at the moment only interesting for the FileLinks!)
CancelTransfers()464 void LinkManager::CancelTransfers()
465 {
466 SvFileObject* pFileObj;
467 sfx2::SvBaseLink* pLnk;
468
469 const sfx2::SvBaseLinks& rLnks = GetLinks();
470 for( sal_uInt16 n = rLnks.Count(); n; )
471 if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
472 OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
473 0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) )
474 // 0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()->
475 // CastAndAddRef( pLnk->GetObj() )) )
476 pFileObj->CancelTransfers();
477 }
478
479 // to send status information from the FileObject to the BaseLink, there is an own ClipboardId.
480 // The SvData object has then the respective information as string.
481 // Currently this will be used for FileObject in connection with JavaScript
482 // - that needs information about Load/Abort/Error
RegisterStatusInfoId()483 sal_uIntPtr LinkManager::RegisterStatusInfoId()
484 {
485 static sal_uIntPtr nFormat = 0;
486
487 if( !nFormat )
488 {
489 // how does the new interface look like?
490 // nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" );
491 nFormat = SotExchange::RegisterFormatName(
492 String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
493 "StatusInfo vom SvxInternalLink" )));
494 }
495 return nFormat;
496 }
497
498 // ----------------------------------------------------------------------
499
GetGraphicFromAny(const String & rMimeType,const::com::sun::star::uno::Any & rValue,Graphic & rGrf)500 sal_Bool LinkManager::GetGraphicFromAny( const String& rMimeType,
501 const ::com::sun::star::uno::Any & rValue,
502 Graphic& rGrf )
503 {
504 sal_Bool bRet = sal_False;
505 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
506 if( rValue.hasValue() && ( rValue >>= aSeq ) )
507 {
508 SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
509 STREAM_READ );
510 aMemStm.Seek( 0 );
511
512 switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
513 {
514 case SOT_FORMATSTR_ID_SVXB:
515 {
516 aMemStm >> rGrf;
517 bRet = sal_True;
518 }
519 break;
520 case FORMAT_GDIMETAFILE:
521 {
522 GDIMetaFile aMtf;
523 aMtf.Read( aMemStm );
524 rGrf = aMtf;
525 bRet = sal_True;
526 }
527 break;
528 case FORMAT_BITMAP:
529 {
530 Bitmap aBmp;
531 ReadDIB(aBmp, aMemStm, true);
532 rGrf = aBmp;
533 bRet = sal_True;
534 }
535 break;
536 }
537 }
538 return bRet;
539 }
540
541
542 // ----------------------------------------------------------------------
lcl_DDE_RelToAbs(const String & rTopic,const String & rBaseURL)543 String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL )
544 {
545 String sRet;
546 INetURLObject aURL( rTopic );
547 if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
548 utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
549 if( !sRet.Len() )
550 sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
551 return sRet;
552 }
553
Connect(sfx2::SvBaseLink * pLink)554 sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
555 {
556 SfxObjectShell* pFndShell = 0;
557 sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
558 String sTopic, sItem, sReferer;
559 if( pLink->GetLinkManager() &&
560 pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem )
561 && sTopic.Len() )
562 {
563 // for the moment run through the DocumentShells and search for the ones with names:
564
565 com::sun::star::lang::Locale aLocale;
566 MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale );
567 CharClass aCC( aLocale );
568
569 String sNm( sTopic ), sTmp;
570 aCC.toLower( sNm );
571
572 TypeId aType( TYPE(SfxObjectShell) );
573
574 sal_Bool bFirst = sal_True;
575 SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
576 if( pShell && pShell->GetMedium() )
577 {
578 sReferer = pShell->GetMedium()->GetBaseURL();
579 SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False );
580 if ( pItem )
581 nUpdateMode = pItem->GetValue();
582 }
583
584 String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) );
585 aCC.toLower( sNmURL );
586
587 if ( !pShell )
588 {
589 bFirst = sal_False;
590 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
591 }
592
593 while( pShell )
594 {
595 if( !sTmp.Len() )
596 {
597 sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
598 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
599 }
600
601
602 aCC.toLower( sTmp );
603 if( sTmp == sNmURL ) // these we want to have
604 {
605 pFndShell = pShell;
606 break;
607 }
608
609 if( bFirst )
610 {
611 bFirst = sal_False;
612 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
613 }
614 else
615 pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False );
616
617 sTmp.Erase();
618 }
619 }
620
621 // empty topics are not allowed - which document is it
622 if( !sTopic.Len() )
623 return sal_False;
624
625 if( !pFndShell )
626 {
627 // try to load the file:
628 INetURLObject aURL( sTopic );
629 INetProtocol eOld = aURL.GetProtocol();
630 aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
631 if( INET_PROT_NOT_VALID != eOld ||
632 INET_PROT_HTTP != aURL.GetProtocol() )
633 {
634 SfxStringItem aName( SID_FILE_NAME, sTopic );
635 SfxBoolItem aMinimized(SID_MINIMIZED, sal_True);
636 SfxBoolItem aHidden(SID_HIDDEN, sal_True);
637 SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
638 SfxStringItem aReferer( SID_REFERER, sReferer );
639 SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
640 SfxBoolItem aReadOnly(SID_DOC_READONLY, sal_True);
641
642 // #i14200# (DDE-link crashes wordprocessor)
643 SfxAllItemSet aArgs( SFX_APP()->GetPool() );
644 aArgs.Put(aReferer);
645 aArgs.Put(aTarget);
646 aArgs.Put(aHidden);
647 aArgs.Put(aMinimized);
648 aArgs.Put(aName);
649 aArgs.Put(aUpdate);
650 aArgs.Put(aReadOnly);
651 pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs );
652 }
653 }
654
655 sal_Bool bRet = sal_False;
656 if( pFndShell )
657 {
658 sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
659 if( pNewSrc )
660 {
661 bRet = sal_True;
662
663 ::com::sun::star::datatransfer::DataFlavor aFl;
664 SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
665
666 pLink->SetObj( pNewSrc );
667 pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
668 sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
669 ? ADVISEMODE_ONLYONCE
670 : 0 );
671 }
672 }
673 return bRet;
674 }
675
676
677 }
678
679