xref: /trunk/main/sfx2/source/appl/appdde.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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