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