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