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