Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <vcl/wrkwin.hxx>
21 : #include <svl/rectitem.hxx>
22 : #include <svl/eitem.hxx>
23 : #include <svl/intitem.hxx>
24 : #include <basic/sbstar.hxx>
25 : #include <svl/stritem.hxx>
26 : #include <svl/svdde.hxx>
27 : #include <sfx2/lnkbase.hxx>
28 : #include <sfx2/linkmgr.hxx>
29 :
30 : #include <tools/urlobj.hxx>
31 : #include <tools/diagnose_ex.h>
32 : #include <unotools/pathoptions.hxx>
33 :
34 : #include <sfx2/app.hxx>
35 : #include "appdata.hxx"
36 : #include <sfx2/objsh.hxx>
37 : #include <sfx2/viewfrm.hxx>
38 : #include <sfx2/dispatch.hxx>
39 : #include "sfxtypes.hxx"
40 : #include <sfx2/sfxsids.hrc>
41 : #include "helper.hxx"
42 : #include <sfx2/docfile.hxx>
43 : #include <comphelper/processfactory.hxx>
44 : #include <comphelper/string.hxx>
45 : #include <com/sun/star/ucb/IllegalIdentifierException.hpp>
46 :
47 : //========================================================================
48 :
49 0 : String SfxDdeServiceName_Impl( const String& sIn )
50 : {
51 0 : String sReturn;
52 :
53 0 : for ( sal_uInt16 n = sIn.Len(); n; --n )
54 : {
55 0 : sal_Unicode cChar = sIn.GetChar(n-1);
56 0 : if (comphelper::string::isalnumAscii(cChar))
57 0 : sReturn += cChar;
58 : }
59 :
60 0 : return sReturn;
61 : }
62 :
63 : #if defined( WNT )
64 : class ImplDdeService : public DdeService
65 : {
66 : public:
67 : ImplDdeService( const String& rNm )
68 : : DdeService( rNm )
69 : {}
70 : virtual sal_Bool MakeTopic( const rtl::OUString& );
71 :
72 : virtual String Topics();
73 :
74 : virtual sal_Bool SysTopicExecute( const String* pStr );
75 : };
76 :
77 : //--------------------------------------------------------------------
78 : namespace
79 : {
80 : sal_Bool lcl_IsDocument( const String& rContent )
81 : {
82 : using namespace com::sun::star;
83 :
84 : sal_Bool bRet = sal_False;
85 : INetURLObject aObj( rContent );
86 : DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
87 :
88 : try
89 : {
90 : ::ucbhelper::Content aCnt( aObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext() );
91 : bRet = aCnt.isDocument();
92 : }
93 : catch( const ucb::CommandAbortedException& )
94 : {
95 : DBG_WARNING( "CommandAbortedException" );
96 : }
97 : catch( const ucb::IllegalIdentifierException& )
98 : {
99 : DBG_WARNING( "IllegalIdentifierException" );
100 : }
101 : catch( const ucb::ContentCreationException& )
102 : {
103 : DBG_WARNING( "IllegalIdentifierException" );
104 : }
105 : catch( const uno::Exception& )
106 : {
107 : SAL_WARN( "sfx2.appl", "Any other exception" );
108 : }
109 :
110 : return bRet;
111 : }
112 : }
113 :
114 : sal_Bool ImplDdeService::MakeTopic( const rtl::OUString& rNm )
115 : {
116 : // Workaround for Event after Main() under OS/2
117 : // happens when exiting starts the App again
118 : if ( !Application::IsInExecute() )
119 : return sal_False;
120 :
121 : // The Topic rNm is sought, do we have it?
122 : // First only loop over the ObjectShells to find those
123 : // with the specific name:
124 : sal_Bool bRet = sal_False;
125 : String sNm( rNm );
126 : sNm.ToLowerAscii();
127 : TypeId aType( TYPE(SfxObjectShell) );
128 : SfxObjectShell* pShell = SfxObjectShell::GetFirst( &aType );
129 : while( pShell )
130 : {
131 : String sTmp( pShell->GetTitle(SFX_TITLE_FULLNAME) );
132 : sTmp.ToLowerAscii();
133 : if( sTmp == sNm )
134 : {
135 : SFX_APP()->AddDdeTopic( pShell );
136 : bRet = sal_True;
137 : break;
138 : }
139 : pShell = SfxObjectShell::GetNext( *pShell, &aType );
140 : }
141 :
142 : if( !bRet )
143 : {
144 : INetURLObject aWorkPath( SvtPathOptions().GetWorkPath() );
145 : INetURLObject aFile;
146 : if ( aWorkPath.GetNewAbsURL( rNm, &aFile ) &&
147 : lcl_IsDocument( aFile.GetMainURL( INetURLObject::NO_DECODE ) ) )
148 : {
149 : // File exists? then try to load it:
150 : SfxStringItem aName( SID_FILE_NAME, aFile.GetMainURL( INetURLObject::NO_DECODE ) );
151 : SfxBoolItem aNewView(SID_OPEN_NEW_VIEW, sal_True);
152 :
153 : SfxBoolItem aSilent(SID_SILENT, sal_True);
154 : SfxDispatcher* pDispatcher = SFX_APP()->GetDispatcher_Impl();
155 : const SfxPoolItem* pRet = pDispatcher->Execute( SID_OPENDOC,
156 : SFX_CALLMODE_SYNCHRON,
157 : &aName, &aNewView,
158 : &aSilent, 0L );
159 :
160 : if( pRet && pRet->ISA( SfxViewFrameItem ) &&
161 : ((SfxViewFrameItem*)pRet)->GetFrame() &&
162 : 0 != ( pShell = ((SfxViewFrameItem*)pRet)
163 : ->GetFrame()->GetObjectShell() ) )
164 : {
165 : SFX_APP()->AddDdeTopic( pShell );
166 : bRet = sal_True;
167 : }
168 : }
169 : }
170 : return bRet;
171 : }
172 :
173 : String ImplDdeService::Topics()
174 : {
175 : String sRet;
176 : if( GetSysTopic() )
177 : sRet += GetSysTopic()->GetName();
178 :
179 : TypeId aType( TYPE(SfxObjectShell) );
180 : SfxObjectShell* pShell = SfxObjectShell::GetFirst( &aType );
181 : while( pShell )
182 : {
183 : if( SfxViewFrame::GetFirst( pShell ) )
184 : {
185 : if( sRet.Len() )
186 : sRet += '\t';
187 : sRet += pShell->GetTitle(SFX_TITLE_FULLNAME);
188 : }
189 : pShell = SfxObjectShell::GetNext( *pShell, &aType );
190 : }
191 : if( sRet.Len() )
192 : sRet += DEFINE_CONST_UNICODE("\r\n");
193 : return sRet;
194 : }
195 :
196 : sal_Bool ImplDdeService::SysTopicExecute( const String* pStr )
197 : {
198 : return (sal_Bool)SFX_APP()->DdeExecute( *pStr );
199 : }
200 : #endif
201 :
202 0 : class SfxDdeTriggerTopic_Impl : public DdeTopic
203 : {
204 : public:
205 : SfxDdeTriggerTopic_Impl()
206 : : DdeTopic( DEFINE_CONST_UNICODE("TRIGGER") )
207 : {}
208 :
209 : virtual sal_Bool Execute( const String* );
210 : };
211 :
212 0 : class SfxDdeDocTopic_Impl : public DdeTopic
213 : {
214 : public:
215 : SfxObjectShell* pSh;
216 : DdeData aData;
217 : ::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
218 :
219 : SfxDdeDocTopic_Impl( SfxObjectShell* pShell )
220 : : DdeTopic( pShell->GetTitle(SFX_TITLE_FULLNAME) ), pSh( pShell )
221 : {}
222 :
223 : virtual DdeData* Get( sal_uIntPtr );
224 : virtual sal_Bool Put( const DdeData* );
225 : virtual sal_Bool Execute( const String* );
226 : virtual sal_Bool StartAdviseLoop();
227 : virtual sal_Bool MakeItem( const rtl::OUString& rItem );
228 : };
229 :
230 :
231 0 : class SfxDdeDocTopics_Impl : public std::vector<SfxDdeDocTopic_Impl*> {};
232 :
233 : //========================================================================
234 :
235 0 : sal_Bool SfxAppEvent_Impl( ApplicationEvent &rAppEvent,
236 : const String &rCmd, const String &rEvent,
237 : ApplicationEvent::Type eType )
238 :
239 : /* [Description]
240 :
241 : Checks if 'rCmd' of the event 'rEvent' is (without '(') and then assemble
242 : this data into a <ApplicationEvent>, which can be excecuted through
243 : <Application::AppEvent()>. If 'rCmd' is the given event 'rEvent', then
244 : TRUE is returned, otherwise FALSE.
245 :
246 : [Example]
247 :
248 : rCmd = "Open(\"d:\doc\doc.sdw\")"
249 : rEvent = "Open"
250 : */
251 :
252 : {
253 0 : String aEvent( rEvent );
254 0 : aEvent += '(';
255 0 : if ( rCmd.CompareIgnoreCaseToAscii( aEvent, aEvent.Len() ) == COMPARE_EQUAL )
256 : {
257 0 : ::rtl::OUStringBuffer aData( rCmd );
258 0 : aData.remove( 0, aEvent.Len() );
259 0 : if ( aData.getLength() > 2 )
260 : {
261 : // Transform into the ApplicationEvent Format
262 0 : aData.remove( aData.getLength() - 1, 1 );
263 0 : for ( sal_Int32 n = 0; n < aData.getLength(); )
264 : {
265 0 : switch ( aData[n] )
266 : {
267 : case '"':
268 0 : aData.remove( n, 1 );
269 0 : while ( n < aData.getLength() && aData[n] != '"' )
270 0 : ++n;
271 0 : if ( n < aData.getLength() )
272 0 : aData.remove( n, 1 );
273 0 : break;
274 : case ' ':
275 0 : aData[n++] = '\n';
276 0 : break;
277 : default:
278 0 : ++n;
279 0 : break;
280 : }
281 : }
282 :
283 0 : rAppEvent = ApplicationEvent(eType, aData.makeStringAndClear());
284 0 : return sal_True;
285 0 : }
286 : }
287 :
288 0 : return sal_False;
289 : }
290 :
291 : #if defined( WNT )
292 : long SfxApplication::DdeExecute
293 : (
294 : const String& rCmd // Expressed in our BASIC-Syntax
295 : )
296 :
297 : /* Description]
298 :
299 : This method can be overloaded by application developers, to receive
300 : DDE-commands directed to thier SfxApplication subclass.
301 :
302 : The base implementation understands the API functionality of the
303 : relevant SfxApplication subclass in BASIC syntax. Return values can
304 : not be transferred, unfortunately.
305 : */
306 :
307 : {
308 : // Print or Open-Event?
309 : ApplicationEvent aAppEvent;
310 : if ( SfxAppEvent_Impl( aAppEvent, rCmd, DEFINE_CONST_UNICODE("Print"), ApplicationEvent::TYPE_PRINT ) ||
311 : SfxAppEvent_Impl( aAppEvent, rCmd, DEFINE_CONST_UNICODE("Open"), ApplicationEvent::TYPE_OPEN ) )
312 : GetpApp()->AppEvent( aAppEvent );
313 : else
314 : {
315 : // all others are BASIC
316 : StarBASIC* pBasic = GetBasic();
317 : DBG_ASSERT( pBasic, "Where is the Basic???" );
318 : SbxVariable* pRet = pBasic->Execute( rCmd );
319 : if( !pRet )
320 : {
321 : SbxBase::ResetError();
322 : return 0;
323 : }
324 : }
325 : return 1;
326 : }
327 : #endif
328 :
329 0 : long SfxObjectShell::DdeExecute
330 : (
331 : const String& rCmd // Expressed in our BASIC-Syntax
332 : )
333 :
334 : /* [Description]
335 :
336 : This method can be overloaded by application developers, to receive
337 : DDE-commands directed to the thier SfxApplication subclass.
338 :
339 : The base implementation does nothing and returns 0.
340 : */
341 :
342 : {
343 : #ifdef DISABLE_SCRIPTING
344 : (void) rCmd;
345 : #else
346 0 : StarBASIC* pBasic = GetBasic();
347 : DBG_ASSERT( pBasic, "Where is the Basic???" ) ;
348 0 : SbxVariable* pRet = pBasic->Execute( rCmd );
349 0 : if( !pRet )
350 : {
351 0 : SbxBase::ResetError();
352 0 : return 0;
353 : }
354 : #endif
355 0 : return 1;
356 : }
357 :
358 : //--------------------------------------------------------------------
359 :
360 0 : long SfxObjectShell::DdeGetData
361 : (
362 : const String&, // the Item to be addressed
363 : const String&, // in: Format
364 : ::com::sun::star::uno::Any& // out: requested data
365 : )
366 :
367 : /* [Description]
368 :
369 : This method can be overloaded by application developers, to receive
370 : DDE-data-requests directed to thier SfxApplication subclass.
371 :
372 : The base implementation provides no data and returns 0.
373 : */
374 :
375 : {
376 0 : return 0;
377 : }
378 :
379 : //--------------------------------------------------------------------
380 :
381 0 : long SfxObjectShell::DdeSetData
382 : (
383 : const String&, // the Item to be addressed
384 : const String&, // in: Format
385 : const ::com::sun::star::uno::Any& // out: requested data
386 : )
387 :
388 : /* [Description]
389 :
390 : This method can be overloaded by application developers, to receive
391 : DDE-data directed to thier SfxApplication subclass.
392 :
393 : The base implementation is not receiving any data and returns 0.
394 : */
395 :
396 : {
397 0 : return 0;
398 : }
399 :
400 : //--------------------------------------------------------------------
401 0 : ::sfx2::SvLinkSource* SfxObjectShell::DdeCreateLinkSource
402 : (
403 : const String& // the Item to be addressed
404 : )
405 :
406 : /* [Description]
407 :
408 : This method can be overloaded by application developers, to establish
409 : a DDE-hotlink to thier SfxApplication subclass.
410 :
411 : The base implementation is not generate a link and returns 0.
412 : */
413 :
414 : {
415 0 : return 0;
416 : }
417 :
418 1274 : void SfxObjectShell::ReconnectDdeLink(SfxObjectShell& /*rServer*/)
419 : {
420 1274 : }
421 :
422 336 : void SfxObjectShell::ReconnectDdeLinks(SfxObjectShell& rServer)
423 : {
424 336 : TypeId aType = TYPE(SfxObjectShell);
425 336 : SfxObjectShell* p = GetFirst(&aType, false);
426 7067 : while (p)
427 : {
428 6395 : if (&rServer != p)
429 6059 : p->ReconnectDdeLink(rServer);
430 :
431 6395 : p = GetNext(*p, &aType, false);
432 : }
433 336 : }
434 :
435 : //========================================================================
436 :
437 0 : long SfxViewFrame::DdeExecute
438 : (
439 : const String& rCmd // Expressed in our BASIC-Syntax
440 : )
441 :
442 : /* [Description]
443 :
444 : This method can be overloaded by application developers, to receive
445 : DDE-commands directed to the thier SfxApplication subclass.
446 :
447 : The base implementation understands the API functionality of the
448 : relevant SfxViewFrame, which is shown and the relevant SfxViewShell
449 : and the relevant SfxApplication subclass in BASIC syntax. Return
450 : values can not be transferred, unfortunately.
451 : */
452 :
453 : {
454 0 : if ( GetObjectShell() )
455 0 : return GetObjectShell()->DdeExecute( rCmd );
456 :
457 0 : return 0;
458 : }
459 :
460 : //--------------------------------------------------------------------
461 :
462 0 : long SfxViewFrame::DdeGetData
463 : (
464 : const String&, // the Item to be addressed
465 : const String&, // in: Format
466 : ::com::sun::star::uno::Any& // out: requested data
467 : )
468 :
469 : /* [Description]
470 :
471 : This method can be overloaded by application developers, to receive
472 : DDE-data-requests directed to thier SfxApplication subclass.
473 :
474 : The base implementation provides no data and returns 0.
475 : */
476 :
477 : {
478 0 : return 0;
479 : }
480 :
481 : //--------------------------------------------------------------------
482 :
483 0 : long SfxViewFrame::DdeSetData
484 : (
485 : const String&, // the Item to be addressed
486 : const String&, // in: Format
487 : const ::com::sun::star::uno::Any& // out: requested data
488 : )
489 :
490 : /* [Description]
491 :
492 : This method can be overloaded by application developers, to receive
493 : DDE-data directed to thier SfxApplication subclass.
494 :
495 : The base implementation is not receiving any data and returns 0.
496 : */
497 :
498 : {
499 0 : return 0;
500 : }
501 :
502 : //--------------------------------------------------------------------
503 :
504 0 : ::sfx2::SvLinkSource* SfxViewFrame::DdeCreateLinkSource
505 : (
506 : const String& // the Item to be addressed
507 : )
508 :
509 : /* [Description]
510 :
511 : This method can be overloaded by application developers, to establish
512 : a DDE-hotlink to thier SfxApplication subclass.
513 :
514 : The base implementation is not generate a link and returns 0.
515 : */
516 :
517 : {
518 0 : return 0;
519 : }
520 :
521 : //========================================================================
522 :
523 19 : sal_Bool SfxApplication::InitializeDde()
524 : {
525 19 : int nError = 0;
526 : #if defined( WNT )
527 : DBG_ASSERT( !pAppData_Impl->pDdeService,
528 : "Dde can not be initialized multiple times" );
529 :
530 : pAppData_Impl->pDdeService = new ImplDdeService( Application::GetAppName() );
531 : nError = pAppData_Impl->pDdeService->GetError();
532 : if( !nError )
533 : {
534 : pAppData_Impl->pDocTopics = new SfxDdeDocTopics_Impl;
535 :
536 : // we certainly want to support RTF!
537 : pAppData_Impl->pDdeService->AddFormat( FORMAT_RTF );
538 :
539 : // Config path as a topic becauseof multiple starts
540 : INetURLObject aOfficeLockFile( SvtPathOptions().GetUserConfigPath() );
541 : aOfficeLockFile.insertName( DEFINE_CONST_UNICODE( "soffice.lck" ) );
542 : String aService( SfxDdeServiceName_Impl(
543 : aOfficeLockFile.GetMainURL(INetURLObject::DECODE_TO_IURI) ) );
544 : aService.ToUpperAscii();
545 : pAppData_Impl->pDdeService2 = new ImplDdeService( aService );
546 : pAppData_Impl->pTriggerTopic = new SfxDdeTriggerTopic_Impl;
547 : pAppData_Impl->pDdeService2->AddTopic( *pAppData_Impl->pTriggerTopic );
548 : }
549 : #endif
550 19 : return !nError;
551 : }
552 :
553 0 : void SfxAppData_Impl::DeInitDDE()
554 : {
555 0 : DELETEZ( pTriggerTopic );
556 0 : DELETEZ( pDdeService2 );
557 0 : DELETEZ( pDocTopics );
558 0 : DELETEZ( pDdeService );
559 0 : }
560 :
561 : #if defined( WNT )
562 : void SfxApplication::AddDdeTopic( SfxObjectShell* pSh )
563 : {
564 : DBG_ASSERT( pAppData_Impl->pDocTopics, "There is no Dde-Service" );
565 : //OV: DDE is disconnected in server mode!
566 : if( !pAppData_Impl->pDocTopics )
567 : return;
568 :
569 : // prevent double submit
570 : String sShellNm;
571 : sal_Bool bFnd = sal_False;
572 : for (size_t n = pAppData_Impl->pDocTopics->size(); n;)
573 : {
574 : if( (*pAppData_Impl->pDocTopics)[ --n ]->pSh == pSh )
575 : {
576 : // If the document is untitled, is still a new Topic is created!
577 : if( !bFnd )
578 : {
579 : bFnd = sal_True;
580 : (sShellNm = pSh->GetTitle(SFX_TITLE_FULLNAME)).ToLowerAscii();
581 : }
582 : String sNm( (*pAppData_Impl->pDocTopics)[ n ]->GetName() );
583 : if( sShellNm == sNm.ToLowerAscii() )
584 : return ;
585 : }
586 : }
587 :
588 : SfxDdeDocTopic_Impl *const pTopic = new SfxDdeDocTopic_Impl(pSh);
589 : pAppData_Impl->pDocTopics->push_back(pTopic);
590 : pAppData_Impl->pDdeService->AddTopic( *pTopic );
591 : }
592 : #endif
593 :
594 0 : void SfxApplication::RemoveDdeTopic( SfxObjectShell* pSh )
595 : {
596 : DBG_ASSERT( pAppData_Impl->pDocTopics, "There is no Dde-Service" );
597 : //OV: DDE is disconnected in server mode!
598 0 : if( !pAppData_Impl->pDocTopics )
599 0 : return;
600 :
601 0 : for (size_t n = pAppData_Impl->pDocTopics->size(); n; )
602 : {
603 0 : SfxDdeDocTopic_Impl *const pTopic = (*pAppData_Impl->pDocTopics)[ --n ];
604 0 : if (pTopic->pSh == pSh)
605 : {
606 0 : pAppData_Impl->pDdeService->RemoveTopic( *pTopic );
607 0 : delete pTopic;
608 0 : pAppData_Impl->pDocTopics->erase( pAppData_Impl->pDocTopics->begin() + n );
609 : }
610 : }
611 : }
612 :
613 0 : const DdeService* SfxApplication::GetDdeService() const
614 : {
615 0 : return pAppData_Impl->pDdeService;
616 : }
617 :
618 430 : DdeService* SfxApplication::GetDdeService()
619 : {
620 430 : return pAppData_Impl->pDdeService;
621 : }
622 :
623 : //--------------------------------------------------------------------
624 :
625 0 : sal_Bool SfxDdeTriggerTopic_Impl::Execute( const String* )
626 : {
627 0 : return sal_True;
628 : }
629 :
630 : //--------------------------------------------------------------------
631 0 : DdeData* SfxDdeDocTopic_Impl::Get( sal_uIntPtr nFormat )
632 : {
633 0 : String sMimeType( SotExchange::GetFormatMimeType( nFormat ));
634 0 : ::com::sun::star::uno::Any aValue;
635 0 : long nRet = pSh->DdeGetData( GetCurItem(), sMimeType, aValue );
636 0 : if( nRet && aValue.hasValue() && ( aValue >>= aSeq ) )
637 : {
638 0 : aData = DdeData( aSeq.getConstArray(), aSeq.getLength(), nFormat );
639 0 : return &aData;
640 : }
641 0 : aSeq.realloc( 0 );
642 0 : return 0;
643 : }
644 :
645 0 : sal_Bool SfxDdeDocTopic_Impl::Put( const DdeData* pData )
646 : {
647 : aSeq = ::com::sun::star::uno::Sequence< sal_Int8 >(
648 0 : (sal_Int8*)(const void*)*pData, (long)*pData );
649 : sal_Bool bRet;
650 0 : if( aSeq.getLength() )
651 : {
652 0 : ::com::sun::star::uno::Any aValue;
653 0 : aValue <<= aSeq;
654 0 : String sMimeType( SotExchange::GetFormatMimeType( pData->GetFormat() ));
655 0 : bRet = 0 != pSh->DdeSetData( GetCurItem(), sMimeType, aValue );
656 : }
657 : else
658 0 : bRet = sal_False;
659 0 : return bRet;
660 : }
661 :
662 0 : sal_Bool SfxDdeDocTopic_Impl::Execute( const String* pStr )
663 : {
664 0 : long nRet = pStr ? pSh->DdeExecute( *pStr ) : 0;
665 0 : return 0 != nRet;
666 : }
667 :
668 0 : sal_Bool SfxDdeDocTopic_Impl::MakeItem( const rtl::OUString& rItem )
669 : {
670 0 : AddItem( DdeItem( rItem ) );
671 0 : return sal_True;
672 : }
673 :
674 0 : sal_Bool SfxDdeDocTopic_Impl::StartAdviseLoop()
675 : {
676 0 : sal_Bool bRet = sal_False;
677 0 : ::sfx2::SvLinkSource* pNewObj = pSh->DdeCreateLinkSource( GetCurItem() );
678 0 : if( pNewObj )
679 : {
680 : // then we also establish a corresponding SvBaseLink
681 0 : String sNm, sTmp( Application::GetAppName() );
682 0 : ::sfx2::MakeLnkName( sNm, &sTmp, pSh->GetTitle(SFX_TITLE_FULLNAME), GetCurItem() );
683 0 : new ::sfx2::SvBaseLink( sNm, OBJECT_DDE_EXTERN, pNewObj );
684 0 : bRet = sal_True;
685 : }
686 0 : return bRet;
687 : }
688 :
689 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|