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 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 #include <vcl/wrkwin.hxx> 27 #include <svl/rectitem.hxx> 28 #include <svl/eitem.hxx> 29 #include <svl/intitem.hxx> 30 #include <basic/sbstar.hxx> 31 #include <svl/stritem.hxx> 32 #include <svl/svdde.hxx> 33 #include <sfx2/lnkbase.hxx> 34 #include <sfx2/linkmgr.hxx> 35 36 #include <tools/urlobj.hxx> 37 #include <tools/diagnose_ex.h> 38 #include <unotools/pathoptions.hxx> 39 #ifndef GCC 40 #endif 41 42 #include <sfx2/app.hxx> 43 #include "appdata.hxx" 44 #include <sfx2/objsh.hxx> 45 #include <sfx2/viewfrm.hxx> 46 #include <sfx2/viewfrm.hxx> 47 #include <sfx2/dispatch.hxx> 48 #include "sfxtypes.hxx" 49 #include <sfx2/sfxsids.hrc> 50 #include "helper.hxx" 51 #include <sfx2/docfile.hxx> 52 53 //======================================================================== 54 55 String SfxDdeServiceName_Impl( const String& sIn ) 56 { 57 ByteString sTemp = U2S( sIn ); 58 ByteString sReturn; 59 60 for ( sal_uInt16 n = sTemp.Len(); n; --n ) 61 if ( sTemp.Copy( n-1, 1 ).IsAlphaNumericAscii() ) 62 sReturn += sTemp.GetChar(n-1); 63 64 return S2U( sReturn ); 65 } 66 67 68 class ImplDdeService : public DdeService 69 { 70 public: 71 ImplDdeService( const String& rNm ) 72 : DdeService( rNm ) 73 {} 74 virtual sal_Bool MakeTopic( const String& ); 75 76 virtual String Topics(); 77 // virtual String Formats(); 78 // virtual String SysItems(); 79 // virtual String Status(); 80 81 virtual sal_Bool SysTopicExecute( const String* pStr ); 82 }; 83 84 class SfxDdeTriggerTopic_Impl : public DdeTopic 85 { 86 public: 87 SfxDdeTriggerTopic_Impl() 88 : DdeTopic( DEFINE_CONST_UNICODE("TRIGGER") ) 89 {} 90 91 virtual sal_Bool Execute( const String* ); 92 }; 93 94 class SfxDdeDocTopic_Impl : public DdeTopic 95 { 96 public: 97 SfxObjectShell* pSh; 98 DdeData aData; 99 ::com::sun::star::uno::Sequence< sal_Int8 > aSeq; 100 101 SfxDdeDocTopic_Impl( SfxObjectShell* pShell ) 102 : DdeTopic( pShell->GetTitle(SFX_TITLE_FULLNAME) ), pSh( pShell ) 103 {} 104 105 virtual DdeData* Get( sal_uIntPtr ); 106 virtual sal_Bool Put( const DdeData* ); 107 virtual sal_Bool Execute( const String* ); 108 virtual sal_Bool StartAdviseLoop(); 109 virtual sal_Bool MakeItem( const String& rItem ); 110 111 // wird benoetigt? 112 // virtual void Connect( long n ); 113 // virtual void Disconnect( long n ); 114 // virtual void StopAdviseLoop(); 115 116 }; 117 118 119 SV_DECL_PTRARR( SfxDdeDocTopics_Impl, SfxDdeDocTopic_Impl *, 4, 4 ) 120 SV_IMPL_PTRARR( SfxDdeDocTopics_Impl, SfxDdeDocTopic_Impl *) 121 122 //======================================================================== 123 124 sal_Bool SfxAppEvent_Impl( ApplicationEvent &rAppEvent, 125 const String &rCmd, const String &rEvent ) 126 127 /* [Beschreibung] 128 129 Pr"uft, ob 'rCmd' das Event 'rEvent' ist (ohne '(') und baut 130 aus diesem dann ein <ApplicationEvent> zusammen, das per 131 <Application::AppEvent()> ausgef"uhrt werden kann. Ist 'rCmd' das 132 angegegeben Event 'rEvent', dann wird TRUE zur"uckgegeben, sonst FALSE. 133 134 135 [Beispiel] 136 137 rCmd = "Open(\"d:\doc\doc.sdw\")" 138 rEvent = "Open" 139 */ 140 141 { 142 String aEvent( rEvent ); 143 aEvent += '('; 144 if ( rCmd.CompareIgnoreCaseToAscii( aEvent, aEvent.Len() ) == COMPARE_EQUAL ) 145 { 146 String aData( rCmd ); 147 aData.Erase( 0, aEvent.Len() ); 148 if ( aData.Len() > 2 ) 149 { 150 // in das ApplicationEvent-Format wandeln 151 aData.Erase( aData.Len()-1, 1 ); 152 for ( sal_uInt16 n = 0; n < aData.Len(); ++n ) 153 { 154 if ( aData.GetChar(n) == 0x0022 ) // " = 22h 155 for ( ; aData.GetChar(++n) != 0x0022 ; ) 156 /* empty loop */ ; 157 else if ( aData.GetChar(n) == 0x0020 ) // SPACE = 20h 158 aData.SetChar(n, '\n'); 159 } 160 aData.EraseAllChars( 0x0022 ); 161 ApplicationAddress aAddr; 162 rAppEvent = ApplicationEvent( String(), aAddr, U2S(rEvent), aData ); 163 return sal_True; 164 } 165 } 166 167 return sal_False; 168 } 169 170 //------------------------------------------------------------------------- 171 172 long SfxApplication::DdeExecute 173 ( 174 const String& rCmd // in unserer BASIC-Syntax formuliert 175 ) 176 177 /* [Beschreibung] 178 179 Diese Methode kann vom Applikationsentwickler "uberladen werden, 180 um an seine SfxApplication-Subklasse gerichtete DDE-Kommandos 181 zu empfangen. 182 183 Die Basisimplementierung versteht die API-Funktionalit"at der 184 betreffenden SfxApplication-Subklasse in BASIC-Syntax. R"uckgabewerte 185 k"onnen dabei leider nicht "ubertragen werden. 186 */ 187 188 { 189 // Print oder Open-Event? 190 ApplicationEvent aAppEvent; 191 if ( SfxAppEvent_Impl( aAppEvent, rCmd, DEFINE_CONST_UNICODE("Print") ) || 192 SfxAppEvent_Impl( aAppEvent, rCmd, DEFINE_CONST_UNICODE("Open") ) ) 193 GetpApp()->AppEvent( aAppEvent ); 194 else 195 { 196 // alle anderen per BASIC 197 StarBASIC* pBasic = GetBasic(); 198 ENSURE_OR_RETURN( pBasic, "where's my basic?", 0 ); 199 SbxVariable* pRet = pBasic->Execute( rCmd ); 200 if( !pRet ) 201 { 202 SbxBase::ResetError(); 203 return 0; 204 } 205 } 206 return 1; 207 } 208 209 //-------------------------------------------------------------------- 210 211 long SfxApplication::DdeGetData 212 ( 213 const String&, // das anzusprechende Item 214 const String&, // in: Format 215 ::com::sun::star::uno::Any& // out: angeforderte Daten 216 ) 217 218 /* [Beschreibung] 219 220 Diese Methode kann vom Applikationsentwickler "uberladen werden, 221 um an seine SfxApplication-Subklasse gerichtete DDE-Daten-Anforderungen 222 zu empfangen. 223 224 Die Basisimplementierung liefert keine Daten und gibt 0 zur"uck. 225 */ 226 227 { 228 return 0; 229 } 230 231 //-------------------------------------------------------------------- 232 233 long SfxApplication::DdeSetData 234 ( 235 const String&, // das anzusprechende Item 236 const String&, // in: Format 237 const ::com::sun::star::uno::Any& // out: angeforderte Daten 238 ) 239 240 /* [Beschreibung] 241 242 Diese Methode kann vom Applikationsentwickler "uberladen werden, 243 um an seine SfxApplication-Subklasse gerichtete DDE-Daten 244 zu empfangen. 245 246 Die Basisimplementierung nimmt keine Daten entgegen und liefert 0 zur"uck. 247 */ 248 249 { 250 return 0; 251 } 252 253 //-------------------------------------------------------------------- 254 255 ::sfx2::SvLinkSource* SfxApplication::DdeCreateLinkSource 256 ( 257 const String& // das zu erzeugende Item 258 ) 259 260 /* [Beschreibung] 261 262 Diese Methode kann vom Applikationsentwickler "uberladen werden, 263 um an seiner SfxApplication-Subklasse einen DDE-Hotlink einzurichten 264 265 Die Basisimplementierung erzeugt keinen und liefert 0 zur"uck. 266 */ 267 268 { 269 return 0; 270 } 271 272 //======================================================================== 273 274 long SfxObjectShell::DdeExecute 275 ( 276 const String& rCmd // in unserer BASIC-Syntax formuliert 277 ) 278 279 /* [Beschreibung] 280 281 Diese Methode kann vom Applikationsentwickler "uberladen werden, 282 um an seine SfxObjectShell-Subklasse gerichtete DDE-Kommandos 283 zu empfangen. 284 285 Die Basisimplementierung f"uhrt nichts aus und liefert 0 zur"uck. 286 */ 287 288 { 289 StarBASIC* pBasic = GetBasic(); 290 DBG_ASSERT( pBasic, "Wo ist mein Basic???" ) ; 291 SbxVariable* pRet = pBasic->Execute( rCmd ); 292 if( !pRet ) 293 { 294 SbxBase::ResetError(); 295 return 0; 296 } 297 298 return 1; 299 } 300 301 //-------------------------------------------------------------------- 302 303 long SfxObjectShell::DdeGetData 304 ( 305 const String&, // das anzusprechende Item 306 const String&, // in: Format 307 ::com::sun::star::uno::Any& // out: angeforderte Daten 308 ) 309 310 /* [Beschreibung] 311 312 Diese Methode kann vom Applikationsentwickler "uberladen werden, 313 um an seine SfxObjectShell-Subklasse gerichtete DDE-Daten-Anforderungen 314 zu empfangen. 315 316 Die Basisimplementierung liefert keine Daten und gibt 0 zur"uck. 317 */ 318 319 { 320 return 0; 321 } 322 323 //-------------------------------------------------------------------- 324 325 long SfxObjectShell::DdeSetData 326 ( 327 const String&, // das anzusprechende Item 328 const String&, // in: Format 329 const ::com::sun::star::uno::Any& // out: angeforderte Daten 330 ) 331 332 /* [Beschreibung] 333 334 Diese Methode kann vom Applikationsentwickler "uberladen werden, 335 um an seine SfxObjectShell-Subklasse gerichtete DDE-Daten 336 zu empfangen. 337 338 Die Basisimplementierung nimmt keine Daten entgegen und liefert 0 zur"uck. 339 */ 340 341 { 342 return 0; 343 } 344 345 //-------------------------------------------------------------------- 346 ::sfx2::SvLinkSource* SfxObjectShell::DdeCreateLinkSource 347 ( 348 const String& // das zu erzeugende Item 349 ) 350 351 /* [Beschreibung] 352 353 Diese Methode kann vom Applikationsentwickler "uberladen werden, 354 um an seiner SfxObjectShell-Subklasse einen DDE-Hotlink einzurichten 355 356 Die Basisimplementierung erzeugt keinen und liefert 0 zur"uck. 357 */ 358 359 { 360 return 0; 361 } 362 363 //======================================================================== 364 365 long SfxViewFrame::DdeExecute 366 ( 367 const String& rCmd // in unserer BASIC-Syntax formuliert 368 ) 369 370 /* [Beschreibung] 371 372 Diese Methode kann vom Applikationsentwickler "uberladen werden, 373 um an seine SfxViewFrame-Subklasse gerichtete DDE-Kommandos 374 zu empfangen. 375 376 Die Basisimplementierung versteht die API-Funktionalit"at des 377 betreffenden SfxViewFrame, der darin dargestellten SfxViewShell und 378 der betreffenden SfxObjectShell-Subklasse in BASIC-Syntax. 379 R"uckgabewerte k"onnen dabei leider nicht "ubertragen werden. 380 */ 381 382 { 383 if ( GetObjectShell() ) 384 return GetObjectShell()->DdeExecute( rCmd ); 385 386 return 0; 387 } 388 389 //-------------------------------------------------------------------- 390 391 long SfxViewFrame::DdeGetData 392 ( 393 const String&, // das anzusprechende Item 394 const String&, // in: Format 395 ::com::sun::star::uno::Any& // out: angeforderte Daten 396 ) 397 398 /* [Beschreibung] 399 400 Diese Methode kann vom Applikationsentwickler "uberladen werden, 401 um an seine SfxViewFrame-Subklasse gerichtete DDE-Daten-Anforderungen 402 zu empfangen. 403 404 Die Basisimplementierung liefert keine Daten und gibt 0 zur"uck. 405 */ 406 407 { 408 return 0; 409 } 410 411 //-------------------------------------------------------------------- 412 413 long SfxViewFrame::DdeSetData 414 ( 415 const String& , // das anzusprechende Item 416 const String& , // in: Format 417 const ::com::sun::star::uno::Any& // out: angeforderte Daten 418 ) 419 420 /* [Beschreibung] 421 422 Diese Methode kann vom Applikationsentwickler "uberladen werden, 423 um an seine SfxViewFrame-Subklasse gerichtete DDE-Daten 424 zu empfangen. 425 426 Die Basisimplementierung nimmt keine Daten entgegen und liefert 0 zur"uck. 427 */ 428 429 { 430 return 0; 431 } 432 433 //-------------------------------------------------------------------- 434 435 ::sfx2::SvLinkSource* SfxViewFrame::DdeCreateLinkSource 436 ( 437 const String& // das zu erzeugende Item 438 ) 439 440 /* [Beschreibung] 441 442 Diese Methode kann vom Applikationsentwickler "uberladen werden, 443 um an seiner SfxViewFrame-Subklasse einen DDE-Hotlink einzurichten 444 445 Die Basisimplementierung erzeugt keinen und liefert 0 zur"uck. 446 */ 447 448 { 449 return 0; 450 } 451 452 //======================================================================== 453 454 sal_Bool SfxApplication::InitializeDde() 455 { 456 DBG_ASSERT( !pAppData_Impl->pDdeService, 457 "Dde kann nicht mehrfach initialisiert werden" ); 458 459 pAppData_Impl->pDdeService = new ImplDdeService( Application::GetAppName() ); 460 int nError = pAppData_Impl->pDdeService->GetError(); 461 if( !nError ) 462 { 463 pAppData_Impl->pDocTopics = new SfxDdeDocTopics_Impl; 464 465 // wir wollen auf jedenfall RTF unterstuetzen! 466 pAppData_Impl->pDdeService->AddFormat( FORMAT_RTF ); 467 468 // Config-Pfad als Topic wegen Mehrfachstart 469 INetURLObject aOfficeLockFile( SvtPathOptions().GetUserConfigPath() ); 470 aOfficeLockFile.insertName( DEFINE_CONST_UNICODE( "soffice.lck" ) ); 471 String aService( SfxDdeServiceName_Impl( 472 aOfficeLockFile.GetMainURL(INetURLObject::DECODE_TO_IURI) ) ); 473 aService.ToUpperAscii(); 474 pAppData_Impl->pDdeService2 = new ImplDdeService( aService ); 475 pAppData_Impl->pTriggerTopic = new SfxDdeTriggerTopic_Impl; 476 pAppData_Impl->pDdeService2->AddTopic( *pAppData_Impl->pTriggerTopic ); 477 } 478 return !nError; 479 } 480 481 void SfxAppData_Impl::DeInitDDE() 482 { 483 DELETEZ( pTriggerTopic ); 484 DELETEZ( pDdeService2 ); 485 DELETEZ( pDocTopics ); 486 DELETEZ( pDdeService ); 487 } 488 489 //-------------------------------------------------------------------- 490 491 void SfxApplication::AddDdeTopic( SfxObjectShell* pSh ) 492 { 493 DBG_ASSERT( pAppData_Impl->pDocTopics, "es gibt gar keinen Dde-Service" ); 494 //OV: Im Serverbetrieb ist DDE abgeklemmt! 495 if( !pAppData_Impl->pDocTopics ) 496 return; 497 498 // doppeltes Eintragen verhindern 499 String sShellNm; 500 sal_Bool bFnd = sal_False; 501 for( sal_uInt16 n = pAppData_Impl->pDocTopics->Count(); n; ) 502 if( (*pAppData_Impl->pDocTopics)[ --n ]->pSh == pSh ) 503 { 504 // JP 18.03.96 - Bug 26470 505 // falls das Document unbenannt wurde, ist trotzdem ein 506 // neues Topics anzulegen! 507 if( !bFnd ) 508 { 509 bFnd = sal_True; 510 (sShellNm = pSh->GetTitle(SFX_TITLE_FULLNAME)).ToLowerAscii(); 511 } 512 String sNm( (*pAppData_Impl->pDocTopics)[ n ]->GetName() ); 513 if( sShellNm == sNm.ToLowerAscii() ) 514 return ; 515 } 516 517 const SfxDdeDocTopic_Impl* pTopic = new SfxDdeDocTopic_Impl( pSh ); 518 pAppData_Impl->pDocTopics->Insert( pTopic, 519 pAppData_Impl->pDocTopics->Count() ); 520 pAppData_Impl->pDdeService->AddTopic( *pTopic ); 521 } 522 523 void SfxApplication::RemoveDdeTopic( SfxObjectShell* pSh ) 524 { 525 DBG_ASSERT( pAppData_Impl->pDocTopics, "es gibt gar keinen Dde-Service" ); 526 //OV: Im Serverbetrieb ist DDE abgeklemmt! 527 if( !pAppData_Impl->pDocTopics ) 528 return; 529 530 SfxDdeDocTopic_Impl* pTopic; 531 for( sal_uInt16 n = pAppData_Impl->pDocTopics->Count(); n; ) 532 if( ( pTopic = (*pAppData_Impl->pDocTopics)[ --n ])->pSh == pSh ) 533 { 534 pAppData_Impl->pDdeService->RemoveTopic( *pTopic ); 535 pAppData_Impl->pDocTopics->DeleteAndDestroy( n ); 536 } 537 } 538 539 const DdeService* SfxApplication::GetDdeService() const 540 { 541 return pAppData_Impl->pDdeService; 542 } 543 544 DdeService* SfxApplication::GetDdeService() 545 { 546 return pAppData_Impl->pDdeService; 547 } 548 549 //-------------------------------------------------------------------- 550 551 sal_Bool ImplDdeService::MakeTopic( const String& rNm ) 552 { 553 // Workaround gegen Event nach unserem Main() unter OS/2 554 // passierte wenn man beim Beenden aus dem OffMgr die App neu startet 555 if ( !Application::IsInExecute() ) 556 return sal_False; 557 558 // das Topic rNm wird gesucht, haben wir es ? 559 // erstmal nur ueber die ObjectShells laufen und die mit dem 560 // Namen heraussuchen: 561 sal_Bool bRet = sal_False; 562 String sNm( rNm ); 563 sNm.ToLowerAscii(); 564 TypeId aType( TYPE(SfxObjectShell) ); 565 SfxObjectShell* pShell = SfxObjectShell::GetFirst( &aType ); 566 while( pShell ) 567 { 568 String sTmp( pShell->GetTitle(SFX_TITLE_FULLNAME) ); 569 sTmp.ToLowerAscii(); 570 if( sTmp == sNm ) // die wollen wir haben 571 { 572 SFX_APP()->AddDdeTopic( pShell ); 573 bRet = sal_True; 574 break; 575 } 576 pShell = SfxObjectShell::GetNext( *pShell, &aType ); 577 } 578 579 if( !bRet ) 580 { 581 INetURLObject aWorkPath( SvtPathOptions().GetWorkPath() ); 582 INetURLObject aFile; 583 if ( aWorkPath.GetNewAbsURL( rNm, &aFile ) && 584 SfxContentHelper::IsDocument( aFile.GetMainURL( INetURLObject::NO_DECODE ) ) ) 585 { 586 // File vorhanden 587 588 // dann versuche die Datei zu laden: 589 SfxStringItem aName( SID_FILE_NAME, aFile.GetMainURL( INetURLObject::NO_DECODE ) ); 590 SfxBoolItem aNewView(SID_OPEN_NEW_VIEW, sal_True); 591 592 SfxBoolItem aSilent(SID_SILENT, sal_True); 593 SfxDispatcher* pDispatcher = SFX_APP()->GetDispatcher_Impl(); 594 const SfxPoolItem* pRet = pDispatcher->Execute( SID_OPENDOC, 595 SFX_CALLMODE_SYNCHRON, 596 &aName, &aNewView, 597 &aSilent, 0L ); 598 599 if( pRet && pRet->ISA( SfxViewFrameItem ) && 600 ((SfxViewFrameItem*)pRet)->GetFrame() && 601 0 != ( pShell = ((SfxViewFrameItem*)pRet) 602 ->GetFrame()->GetObjectShell() ) ) 603 { 604 SFX_APP()->AddDdeTopic( pShell ); 605 bRet = sal_True; 606 } 607 } 608 } 609 return bRet; 610 } 611 612 String ImplDdeService::Topics() 613 { 614 String sRet; 615 if( GetSysTopic() ) 616 sRet += GetSysTopic()->GetName(); 617 618 TypeId aType( TYPE(SfxObjectShell) ); 619 SfxObjectShell* pShell = SfxObjectShell::GetFirst( &aType ); 620 while( pShell ) 621 { 622 if( SfxViewFrame::GetFirst( pShell ) ) 623 { 624 if( sRet.Len() ) 625 sRet += '\t'; 626 sRet += pShell->GetTitle(SFX_TITLE_FULLNAME); 627 } 628 pShell = SfxObjectShell::GetNext( *pShell, &aType ); 629 } 630 if( sRet.Len() ) 631 sRet += DEFINE_CONST_UNICODE("\r\n"); 632 return sRet; 633 } 634 635 sal_Bool ImplDdeService::SysTopicExecute( const String* pStr ) 636 { 637 return (sal_Bool)SFX_APP()->DdeExecute( *pStr ); 638 } 639 640 //-------------------------------------------------------------------- 641 642 sal_Bool SfxDdeTriggerTopic_Impl::Execute( const String* ) 643 { 644 return sal_True; 645 } 646 647 //-------------------------------------------------------------------- 648 DdeData* SfxDdeDocTopic_Impl::Get( sal_uIntPtr nFormat ) 649 { 650 String sMimeType( SotExchange::GetFormatMimeType( nFormat )); 651 ::com::sun::star::uno::Any aValue; 652 long nRet = pSh->DdeGetData( GetCurItem(), sMimeType, aValue ); 653 if( nRet && aValue.hasValue() && ( aValue >>= aSeq ) ) 654 { 655 aData = DdeData( aSeq.getConstArray(), aSeq.getLength(), nFormat ); 656 return &aData; 657 } 658 aSeq.realloc( 0 ); 659 return 0; 660 } 661 662 sal_Bool SfxDdeDocTopic_Impl::Put( const DdeData* pData ) 663 { 664 aSeq = ::com::sun::star::uno::Sequence< sal_Int8 >( 665 (sal_Int8*)(const void*)*pData, (long)*pData ); 666 sal_Bool bRet; 667 if( aSeq.getLength() ) 668 { 669 ::com::sun::star::uno::Any aValue; 670 aValue <<= aSeq; 671 String sMimeType( SotExchange::GetFormatMimeType( pData->GetFormat() )); 672 bRet = 0 != pSh->DdeSetData( GetCurItem(), sMimeType, aValue ); 673 } 674 else 675 bRet = sal_False; 676 return bRet; 677 } 678 679 sal_Bool SfxDdeDocTopic_Impl::Execute( const String* pStr ) 680 { 681 long nRet = pStr ? pSh->DdeExecute( *pStr ) : 0; 682 return 0 != nRet; 683 } 684 685 sal_Bool SfxDdeDocTopic_Impl::MakeItem( const String& rItem ) 686 { 687 AddItem( DdeItem( rItem ) ); 688 return sal_True; 689 } 690 691 sal_Bool SfxDdeDocTopic_Impl::StartAdviseLoop() 692 { 693 sal_Bool bRet = sal_False; 694 ::sfx2::SvLinkSource* pNewObj = pSh->DdeCreateLinkSource( GetCurItem() ); 695 if( pNewObj ) 696 { 697 // dann richten wir auch einen entsprechenden SvBaseLink ein 698 String sNm, sTmp( Application::GetAppName() ); 699 ::sfx2::MakeLnkName( sNm, &sTmp, pSh->GetTitle(SFX_TITLE_FULLNAME), GetCurItem() ); 700 new ::sfx2::SvBaseLink( sNm, OBJECT_DDE_EXTERN, pNewObj ); 701 bRet = sal_True; 702 } 703 return bRet; 704 } 705 706