xref: /AOO41X/main/sfx2/source/appl/appdde.cxx (revision 24c56ab9f1bd1305754aa2f564704f38ff57627e)
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 
SfxDdeServiceName_Impl(const String & sIn)55 String SfxDdeServiceName_Impl( const String& sIn )
56 {
57     ByteString sTemp( sIn, RTL_TEXTENCODING_UTF8 );
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 String( sReturn, RTL_TEXTENCODING_UTF8 );
65 }
66 
67 
68 class ImplDdeService : public DdeService
69 {
70 public:
ImplDdeService(const String & rNm)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:
SfxDdeTriggerTopic_Impl()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 
SfxDdeDocTopic_Impl(SfxObjectShell * pShell)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 )
SV_IMPL_PTRARR(SfxDdeDocTopics_Impl,SfxDdeDocTopic_Impl *)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, ByteString( rEvent, RTL_TEXTENCODING_UTF8), aData );
163             return sal_True;
164         }
165     }
166 
167     return sal_False;
168 }
169 
170 //-------------------------------------------------------------------------
171 
DdeExecute(const String & rCmd)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 
DdeGetData(const String &,const String &,::com::sun::star::uno::Any &)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 
DdeSetData(const String &,const String &,const::com::sun::star::uno::Any &)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 
DdeCreateLinkSource(const String &)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 
DdeExecute(const String & rCmd)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 
DdeGetData(const String &,const String &,::com::sun::star::uno::Any &)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 
DdeSetData(const String &,const String &,const::com::sun::star::uno::Any &)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 //--------------------------------------------------------------------
DdeCreateLinkSource(const String &)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 
DdeExecute(const String & rCmd)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 
DdeGetData(const String &,const String &,::com::sun::star::uno::Any &)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 
DdeSetData(const String &,const String &,const::com::sun::star::uno::Any &)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 
DdeCreateLinkSource(const String &)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 
InitializeDde()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 
DeInitDDE()481 void SfxAppData_Impl::DeInitDDE()
482 {
483     DELETEZ( pTriggerTopic );
484     DELETEZ( pDdeService2 );
485     DELETEZ( pDocTopics );
486     DELETEZ( pDdeService );
487 }
488 
489 //--------------------------------------------------------------------
490 
AddDdeTopic(SfxObjectShell * pSh)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 
RemoveDdeTopic(SfxObjectShell * pSh)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 
GetDdeService() const539 const DdeService* SfxApplication::GetDdeService() const
540 {
541     return pAppData_Impl->pDdeService;
542 }
543 
GetDdeService()544 DdeService* SfxApplication::GetDdeService()
545 {
546     return pAppData_Impl->pDdeService;
547 }
548 
549 //--------------------------------------------------------------------
550 
MakeTopic(const String & rNm)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 
Topics()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 
SysTopicExecute(const String * pStr)635 sal_Bool ImplDdeService::SysTopicExecute( const String* pStr )
636 {
637     return (sal_Bool)SFX_APP()->DdeExecute( *pStr );
638 }
639 
640 //--------------------------------------------------------------------
641 
Execute(const String *)642 sal_Bool SfxDdeTriggerTopic_Impl::Execute( const String* )
643 {
644     return sal_True;
645 }
646 
647 //--------------------------------------------------------------------
Get(sal_uIntPtr nFormat)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 
Put(const DdeData * pData)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 
Execute(const String * pStr)679 sal_Bool SfxDdeDocTopic_Impl::Execute( const String* pStr )
680 {
681     long nRet = pStr ? pSh->DdeExecute( *pStr ) : 0;
682     return 0 != nRet;
683 }
684 
MakeItem(const String & rItem)685 sal_Bool SfxDdeDocTopic_Impl::MakeItem( const String& rItem )
686 {
687     AddItem( DdeItem( rItem ) );
688     return sal_True;
689 }
690 
StartAdviseLoop()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