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 mUpdateAsked(sal_False),
70 mAutoAskUpdateAllLinks(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 |* Beschreibung
93 *************************************************************************/
94
Remove(SvBaseLink * pLink)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
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 // 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 if (mAutoAskUpdateAllLinks)
162 {
163 Window *parent = NULL;
164 SfxObjectShell* persist = GetPersist();
165 if (persist != NULL)
166 parent = GetPersist()->GetDialogParent();
167
168 SetUserAllowsLinkUpdate(pLink, GetUserAllowsLinkUpdate(parent));
169 }
170
171 return sal_True;
172 }
173
174
InsertLink(SvBaseLink * pLink,sal_uInt16 nObjType,sal_uInt16 nUpdateMode,const String * pName)175 sal_Bool LinkManager::InsertLink( SvBaseLink * pLink,
176 sal_uInt16 nObjType,
177 sal_uInt16 nUpdateMode,
178 const String* pName )
179 {
180 // unbedingt zuerst
181 pLink->SetObjType( nObjType );
182 if( pName )
183 pLink->SetName( *pName );
184 pLink->SetUpdateMode( nUpdateMode );
185 return Insert( pLink );
186 }
187
188
InsertDDELink(SvBaseLink * pLink,const String & rServer,const String & rTopic,const String & rItem)189 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink,
190 const String& rServer,
191 const String& rTopic,
192 const String& rItem )
193 {
194 if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
195 return sal_False;
196
197 String sCmd;
198 ::sfx2::MakeLnkName( sCmd, &rServer, rTopic, rItem );
199
200 pLink->SetObjType( OBJECT_CLIENT_DDE );
201 pLink->SetName( sCmd );
202 return Insert( pLink );
203 }
204
205
InsertDDELink(SvBaseLink * pLink)206 sal_Bool LinkManager::InsertDDELink( SvBaseLink * pLink )
207 {
208 DBG_ASSERT( OBJECT_CLIENT_SO & pLink->GetObjType(), "no OBJECT_CLIENT_SO" );
209 if( !( OBJECT_CLIENT_SO & pLink->GetObjType() ) )
210 return sal_False;
211
212 if( pLink->GetObjType() == OBJECT_CLIENT_SO )
213 pLink->SetObjType( OBJECT_CLIENT_DDE );
214
215 return Insert( pLink );
216 }
217
218
219 // erfrage die Strings fuer den Dialog
GetDisplayNames(const SvBaseLink * pLink,String * pType,String * pFile,String * pLinkStr,String * pFilter) const220 sal_Bool LinkManager::GetDisplayNames( const SvBaseLink * pLink,
221 String* pType,
222 String* pFile,
223 String* pLinkStr,
224 String* pFilter ) const
225 {
226 sal_Bool bRet = sal_False;
227 const String sLNm( pLink->GetLinkSourceName() );
228 if( sLNm.Len() )
229 {
230 switch( pLink->GetObjType() )
231 {
232 case OBJECT_CLIENT_FILE:
233 case OBJECT_CLIENT_GRF:
234 case OBJECT_CLIENT_OLE:
235 {
236 sal_uInt16 nPos = 0;
237 String sFile( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
238 String sRange( sLNm.GetToken( 0, ::sfx2::cTokenSeperator, nPos ) );
239
240 if( pFile )
241 *pFile = sFile;
242 if( pLinkStr )
243 *pLinkStr = sRange;
244 if( pFilter )
245 *pFilter = sLNm.Copy( nPos );
246
247 if( pType )
248 {
249 sal_uInt16 nObjType = pLink->GetObjType();
250 *pType = String( SfxResId(
251 ( OBJECT_CLIENT_FILE == nObjType || OBJECT_CLIENT_OLE == nObjType )
252 ? RID_SVXSTR_FILELINK
253 : RID_SVXSTR_GRAFIKLINK ));
254 }
255 bRet = sal_True;
256 }
257 break;
258 case OBJECT_CLIENT_DDE:
259 {
260 sal_uInt16 nTmp = 0;
261 String sCmd( sLNm );
262 String sServer( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
263 String sTopic( sCmd.GetToken( 0, cTokenSeperator, nTmp ) );
264
265 if( pType )
266 *pType = sServer;
267 if( pFile )
268 *pFile = sTopic;
269 if( pLinkStr )
270 *pLinkStr = sCmd.Copy( nTmp );
271 bRet = sal_True;
272 }
273 break;
274 default:
275 break;
276 }
277 }
278
279 return bRet;
280 }
281
SetAutoAskUpdateAllLinks()282 void LinkManager::SetAutoAskUpdateAllLinks()
283 {
284 mAutoAskUpdateAllLinks = sal_True;
285 }
286
GetUserAllowsLinkUpdate(Window * pParentWin)287 sal_Bool LinkManager::GetUserAllowsLinkUpdate(Window *pParentWin)
288 {
289 if (!mUpdateAsked)
290 {
291 if (QueryBox(pParentWin, WB_YES_NO | WB_DEF_NO, SfxResId(STR_QUERY_UPDATE_LINKS)).Execute() == RET_YES)
292 mAllowUpdate = sal_True;
293 else
294 mAllowUpdate = sal_False;
295 mUpdateAsked = sal_True;
296 }
297 return mAllowUpdate;
298 }
299
SetUserAllowsLinkUpdate(SvBaseLink * pLink,sal_Bool allows)300 void LinkManager::SetUserAllowsLinkUpdate(SvBaseLink *pLink, sal_Bool allows)
301 {
302 SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
303
304 if (pShell)
305 {
306 comphelper::EmbeddedObjectContainer& rEmbeddedObjectContainer = pShell->getEmbeddedObjectContainer();
307 rEmbeddedObjectContainer.setUserAllowsLinkUpdate(allows);
308 }
309 }
310
311
UpdateAllLinks(sal_Bool bAskUpdate,sal_Bool,sal_Bool bUpdateGrfLinks,Window * pParentWin)312 void LinkManager::UpdateAllLinks(
313 sal_Bool bAskUpdate,
314 sal_Bool /*bCallErrHdl*/,
315 sal_Bool bUpdateGrfLinks,
316 Window* pParentWin )
317 {
318 SvStringsDtor aApps, aTopics, aItems;
319 String sApp, sTopic, sItem;
320
321 // erstmal eine Kopie vom Array machen, damit sich updatende Links in
322 // Links in ... nicht dazwischen funken!!
323 SvPtrarr aTmpArr( 255, 50 );
324 sal_uInt16 n;
325 for( n = 0; n < aLinkTbl.Count(); ++n )
326 {
327 SvBaseLink* pLink = *aLinkTbl[ n ];
328 if( !pLink )
329 {
330 Remove( n-- );
331 continue;
332 }
333 aTmpArr.Insert( pLink, aTmpArr.Count() );
334 }
335
336 for( n = 0; n < aTmpArr.Count(); ++n )
337 {
338 SvBaseLink* pLink = (SvBaseLink*)aTmpArr[ n ];
339
340 // suche erstmal im Array nach dem Eintrag
341 sal_uInt16 nFndPos = USHRT_MAX;
342 for( sal_uInt16 i = 0; i < aLinkTbl.Count(); ++i )
343 if( pLink == *aLinkTbl[ i ] )
344 {
345 nFndPos = i;
346 break;
347 }
348
349 if( USHRT_MAX == nFndPos )
350 continue; // war noch nicht vorhanden!
351
352 // do not update graphic links yet
353 if( !pLink->IsVisible() ||
354 ( !bUpdateGrfLinks && OBJECT_CLIENT_GRF == pLink->GetObjType() ))
355 continue;
356
357 sal_Bool allows = sal_True;
358
359 if (bAskUpdate)
360 {
361 allows = GetUserAllowsLinkUpdate(pParentWin);
362 }
363
364 SetUserAllowsLinkUpdate(pLink, allows);
365 bAskUpdate = sal_False; // one time is OK
366
367 if (allows)
368 pLink->Update();
369
370 }
371 }
372
373 /************************************************************************
374 |* SvBaseLink::CreateObject()
375 |*
376 |* Beschreibung
377 *************************************************************************/
378
CreateObj(SvBaseLink * pLink)379 SvLinkSourceRef LinkManager::CreateObj( SvBaseLink * pLink )
380 {
381 switch( pLink->GetObjType() )
382 {
383 case OBJECT_CLIENT_FILE:
384 case OBJECT_CLIENT_GRF:
385 case OBJECT_CLIENT_OLE:
386 return new SvFileObject;
387 case OBJECT_INTERN:
388 return new SvxInternalLink;
389 case OBJECT_CLIENT_DDE:
390 return new SvDDEObject;
391 default:
392 return SvLinkSourceRef();
393 }
394 }
395
InsertServer(SvLinkSource * pObj)396 sal_Bool LinkManager::InsertServer( SvLinkSource* pObj )
397 {
398 // keine doppelt einfuegen
399 if( !pObj || USHRT_MAX != aServerTbl.GetPos( pObj ) )
400 return sal_False;
401
402 aServerTbl.Insert( pObj, aServerTbl.Count() );
403 return sal_True;
404 }
405
406
RemoveServer(SvLinkSource * pObj)407 void LinkManager::RemoveServer( SvLinkSource* pObj )
408 {
409 sal_uInt16 nPos = aServerTbl.GetPos( pObj );
410 if( USHRT_MAX != nPos )
411 aServerTbl.Remove( nPos, 1 );
412 }
413
414
MakeLnkName(String & rName,const String * pType,const String & rFile,const String & rLink,const String * pFilter)415 void MakeLnkName( String& rName, const String* pType, const String& rFile,
416 const String& rLink, const String* pFilter )
417 {
418 if( pType )
419 (rName = *pType).EraseLeadingChars().EraseTrailingChars() += cTokenSeperator;
420 else if( rName.Len() )
421 rName.Erase();
422
423 ((rName += rFile).EraseLeadingChars().EraseTrailingChars() +=
424 cTokenSeperator ).EraseLeadingChars().EraseTrailingChars() += rLink;
425 if( pFilter )
426 ((rName += cTokenSeperator ) += *pFilter).EraseLeadingChars().EraseTrailingChars();
427 }
428
InsertFileLink(sfx2::SvBaseLink & rLink,sal_uInt16 nFileType,const String & rFileNm,const String * pFilterNm,const String * pRange)429 sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink,
430 sal_uInt16 nFileType,
431 const String& rFileNm,
432 const String* pFilterNm,
433 const String* pRange )
434 {
435 if( !( OBJECT_CLIENT_SO & rLink.GetObjType() ))
436 return sal_False;
437
438 String sCmd( rFileNm );
439 sCmd += ::sfx2::cTokenSeperator;
440 if( pRange )
441 sCmd += *pRange;
442 if( pFilterNm )
443 ( sCmd += ::sfx2::cTokenSeperator ) += *pFilterNm;
444
445 return InsertLink( &rLink, nFileType, sfx2::LINKUPDATE_ONCALL, &sCmd );
446 }
447
InsertFileLink(sfx2::SvBaseLink & rLink)448 sal_Bool LinkManager::InsertFileLink( sfx2::SvBaseLink& rLink )
449 {
450 if( OBJECT_CLIENT_FILE == ( OBJECT_CLIENT_FILE & rLink.GetObjType() ))
451 return InsertLink( &rLink, rLink.GetObjType(), sfx2::LINKUPDATE_ONCALL );
452 return sal_False;
453 }
454
455 // eine Uebertragung wird abgebrochen, also alle DownloadMedien canceln
456 // (ist zur Zeit nur fuer die FileLinks interressant!)
CancelTransfers()457 void LinkManager::CancelTransfers()
458 {
459 SvFileObject* pFileObj;
460 sfx2::SvBaseLink* pLnk;
461
462 const sfx2::SvBaseLinks& rLnks = GetLinks();
463 for( sal_uInt16 n = rLnks.Count(); n; )
464 if( 0 != ( pLnk = &(*rLnks[ --n ])) &&
465 OBJECT_CLIENT_FILE == (OBJECT_CLIENT_FILE & pLnk->GetObjType()) &&
466 0 != ( pFileObj = (SvFileObject*)pLnk->GetObj() ) )
467 // 0 != ( pFileObj = (SvFileObject*)SvFileObject::ClassFactory()->
468 // CastAndAddRef( pLnk->GetObj() )) )
469 pFileObj->CancelTransfers();
470 }
471
472 // um Status Informationen aus dem FileObject an den BaseLink zu
473 // senden, gibt es eine eigene ClipBoardId. Das SvData-Object hat
474 // dann die entsprechenden Informationen als String.
475 // Wird zur Zeit fuer FileObject in Verbindung mit JavaScript benoetigt
476 // - das braucht Informationen ueber Load/Abort/Error
RegisterStatusInfoId()477 sal_uIntPtr LinkManager::RegisterStatusInfoId()
478 {
479 static sal_uIntPtr nFormat = 0;
480
481 if( !nFormat )
482 {
483 // wie sieht die neue Schnittstelle aus?
484 // nFormat = Exchange::RegisterFormatName( "StatusInfo vom SvxInternalLink" );
485 nFormat = SotExchange::RegisterFormatName(
486 String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM(
487 "StatusInfo vom SvxInternalLink" )));
488 }
489 return nFormat;
490 }
491
492 // ----------------------------------------------------------------------
493
GetGraphicFromAny(const String & rMimeType,const::com::sun::star::uno::Any & rValue,Graphic & rGrf)494 sal_Bool LinkManager::GetGraphicFromAny( const String& rMimeType,
495 const ::com::sun::star::uno::Any & rValue,
496 Graphic& rGrf )
497 {
498 sal_Bool bRet = sal_False;
499 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
500 if( rValue.hasValue() && ( rValue >>= aSeq ) )
501 {
502 SvMemoryStream aMemStm( (void*)aSeq.getConstArray(), aSeq.getLength(),
503 STREAM_READ );
504 aMemStm.Seek( 0 );
505
506 switch( SotExchange::GetFormatIdFromMimeType( rMimeType ) )
507 {
508 case SOT_FORMATSTR_ID_SVXB:
509 {
510 aMemStm >> rGrf;
511 bRet = sal_True;
512 }
513 break;
514 case FORMAT_GDIMETAFILE:
515 {
516 GDIMetaFile aMtf;
517 aMtf.Read( aMemStm );
518 rGrf = aMtf;
519 bRet = sal_True;
520 }
521 break;
522 case FORMAT_BITMAP:
523 {
524 Bitmap aBmp;
525 ReadDIB(aBmp, aMemStm, true);
526 rGrf = aBmp;
527 bRet = sal_True;
528 }
529 break;
530 }
531 }
532 return bRet;
533 }
534
535
536 // ----------------------------------------------------------------------
lcl_DDE_RelToAbs(const String & rTopic,const String & rBaseURL)537 String lcl_DDE_RelToAbs( const String& rTopic, const String& rBaseURL )
538 {
539 String sRet;
540 INetURLObject aURL( rTopic );
541 if( INET_PROT_NOT_VALID == aURL.GetProtocol() )
542 utl::LocalFileHelper::ConvertSystemPathToURL( rTopic, rBaseURL, sRet );
543 if( !sRet.Len() )
544 sRet = URIHelper::SmartRel2Abs( INetURLObject(rBaseURL), rTopic, URIHelper::GetMaybeFileHdl(), true );
545 return sRet;
546 }
547
Connect(sfx2::SvBaseLink * pLink)548 sal_Bool SvxInternalLink::Connect( sfx2::SvBaseLink* pLink )
549 {
550 SfxObjectShell* pFndShell = 0;
551 sal_uInt16 nUpdateMode = com::sun::star::document::UpdateDocMode::NO_UPDATE;
552 String sTopic, sItem, sReferer;
553 if( pLink->GetLinkManager() &&
554 pLink->GetLinkManager()->GetDisplayNames( pLink, 0, &sTopic, &sItem )
555 && sTopic.Len() )
556 {
557 // erstmal nur ueber die DocumentShells laufen und die mit dem
558 // Namen heraussuchen:
559
560 com::sun::star::lang::Locale aLocale;
561 MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aLocale );
562 CharClass aCC( aLocale );
563
564 String sNm( sTopic ), sTmp;
565 aCC.toLower( sNm );
566
567 TypeId aType( TYPE(SfxObjectShell) );
568
569 sal_Bool bFirst = sal_True;
570 SfxObjectShell* pShell = pLink->GetLinkManager()->GetPersist();
571 if( pShell && pShell->GetMedium() )
572 {
573 sReferer = pShell->GetMedium()->GetBaseURL();
574 SFX_ITEMSET_ARG( pShell->GetMedium()->GetItemSet(), pItem, SfxUInt16Item, SID_UPDATEDOCMODE, sal_False );
575 if ( pItem )
576 nUpdateMode = pItem->GetValue();
577 }
578
579 String sNmURL( lcl_DDE_RelToAbs( sTopic, sReferer ) );
580 aCC.toLower( sNmURL );
581
582 if ( !pShell )
583 {
584 bFirst = sal_False;
585 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
586 }
587
588 while( pShell )
589 {
590 if( !sTmp.Len() )
591 {
592 sTmp = pShell->GetTitle( SFX_TITLE_FULLNAME );
593 sTmp = lcl_DDE_RelToAbs(sTmp, sReferer );
594 }
595
596
597 aCC.toLower( sTmp );
598 if( sTmp == sNmURL ) // die wollen wir haben
599 {
600 pFndShell = pShell;
601 break;
602 }
603
604 if( bFirst )
605 {
606 bFirst = sal_False;
607 pShell = SfxObjectShell::GetFirst( &aType, sal_False );
608 }
609 else
610 pShell = SfxObjectShell::GetNext( *pShell, &aType, sal_False );
611
612 sTmp.Erase();
613 }
614 }
615
616 // empty topics are not allowed - which document is it
617 if( !sTopic.Len() )
618 return sal_False;
619
620 if( !pFndShell )
621 {
622 // dann versuche die Datei zu laden:
623 INetURLObject aURL( sTopic );
624 INetProtocol eOld = aURL.GetProtocol();
625 aURL.SetURL( sTopic = lcl_DDE_RelToAbs( sTopic, sReferer ) );
626 if( INET_PROT_NOT_VALID != eOld ||
627 INET_PROT_HTTP != aURL.GetProtocol() )
628 {
629 SfxStringItem aName( SID_FILE_NAME, sTopic );
630 SfxBoolItem aMinimized(SID_MINIMIZED, sal_True);
631 SfxBoolItem aHidden(SID_HIDDEN, sal_True);
632 SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
633 SfxStringItem aReferer( SID_REFERER, sReferer );
634 SfxUInt16Item aUpdate( SID_UPDATEDOCMODE, nUpdateMode );
635 SfxBoolItem aReadOnly(SID_DOC_READONLY, sal_True);
636
637 // #i14200# (DDE-link crashes wordprocessor)
638 SfxAllItemSet aArgs( SFX_APP()->GetPool() );
639 aArgs.Put(aReferer);
640 aArgs.Put(aTarget);
641 aArgs.Put(aHidden);
642 aArgs.Put(aMinimized);
643 aArgs.Put(aName);
644 aArgs.Put(aUpdate);
645 aArgs.Put(aReadOnly);
646 pFndShell = SfxObjectShell::CreateAndLoadObject( aArgs );
647 }
648 }
649
650 sal_Bool bRet = sal_False;
651 if( pFndShell )
652 {
653 sfx2::SvLinkSource* pNewSrc = pFndShell->DdeCreateLinkSource( sItem );
654 if( pNewSrc )
655 {
656 bRet = sal_True;
657
658 ::com::sun::star::datatransfer::DataFlavor aFl;
659 SotExchange::GetFormatDataFlavor( pLink->GetContentType(), aFl );
660
661 pLink->SetObj( pNewSrc );
662 pNewSrc->AddDataAdvise( pLink, aFl.MimeType,
663 sfx2::LINKUPDATE_ONCALL == pLink->GetUpdateMode()
664 ? ADVISEMODE_ONLYONCE
665 : 0 );
666 }
667 }
668 return bRet;
669 }
670
671
672 }
673
674
675
676