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