xref: /aoo41x/main/sfx2/source/appl/lnkbase2.cxx (revision eb494517)
1d119d52dSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3d119d52dSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4d119d52dSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5d119d52dSAndrew Rist  * distributed with this work for additional information
6d119d52dSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7d119d52dSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8d119d52dSAndrew Rist  * "License"); you may not use this file except in compliance
9d119d52dSAndrew Rist  * with the License.  You may obtain a copy of the License at
10d119d52dSAndrew Rist  *
11d119d52dSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12d119d52dSAndrew Rist  *
13d119d52dSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14d119d52dSAndrew Rist  * software distributed under the License is distributed on an
15d119d52dSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16d119d52dSAndrew Rist  * KIND, either express or implied.  See the License for the
17d119d52dSAndrew Rist  * specific language governing permissions and limitations
18d119d52dSAndrew Rist  * under the License.
19d119d52dSAndrew Rist  *
20d119d52dSAndrew Rist  *************************************************************/
21d119d52dSAndrew Rist 
22d119d52dSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sfx2.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <sfx2/lnkbase.hxx>
29cdf0e10cSrcweir #include <sot/exchange.hxx>
30cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx>
31cdf0e10cSrcweir #include <com/sun/star/uno/Sequence.hxx>
32cdf0e10cSrcweir #include <vcl/msgbox.hxx>
33cdf0e10cSrcweir #include <sfx2/linkmgr.hxx>
34cdf0e10cSrcweir #include <vcl/svapp.hxx>
35cdf0e10cSrcweir #include "app.hrc"
36cdf0e10cSrcweir #include "sfx2/sfxresid.hxx"
37cdf0e10cSrcweir #include <sfx2/filedlghelper.hxx>
38cdf0e10cSrcweir #include <tools/debug.hxx>
39cdf0e10cSrcweir #include <svl/svdde.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir using namespace ::com::sun::star::uno;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir namespace sfx2
44cdf0e10cSrcweir {
45cdf0e10cSrcweir 
46cdf0e10cSrcweir TYPEINIT0( SvBaseLink )
47cdf0e10cSrcweir 
48cdf0e10cSrcweir static DdeTopic* FindTopic( const String &, sal_uInt16* = 0 );
49cdf0e10cSrcweir 
50cdf0e10cSrcweir class  ImplDdeItem;
51cdf0e10cSrcweir 
52cdf0e10cSrcweir struct BaseLink_Impl
53cdf0e10cSrcweir {
54cdf0e10cSrcweir     Link                m_aEndEditLink;
55cdf0e10cSrcweir     LinkManager*      m_pLinkMgr;
56cdf0e10cSrcweir     Window*             m_pParentWin;
57cdf0e10cSrcweir     FileDialogHelper*   m_pFileDlg;
58cdf0e10cSrcweir     bool                m_bIsConnect;
59cdf0e10cSrcweir 
BaseLink_Implsfx2::BaseLink_Impl60cdf0e10cSrcweir     BaseLink_Impl() :
61cdf0e10cSrcweir           m_pLinkMgr( NULL )
62cdf0e10cSrcweir         , m_pParentWin( NULL )
63cdf0e10cSrcweir         , m_pFileDlg( NULL )
64cdf0e10cSrcweir         , m_bIsConnect( false )
65cdf0e10cSrcweir         {}
66cdf0e10cSrcweir 
~BaseLink_Implsfx2::BaseLink_Impl67cdf0e10cSrcweir     ~BaseLink_Impl()
68cdf0e10cSrcweir         { delete m_pFileDlg; }
69cdf0e10cSrcweir };
70cdf0e10cSrcweir 
71cdf0e10cSrcweir // nur fuer die interne Verwaltung
72cdf0e10cSrcweir struct ImplBaseLinkData
73cdf0e10cSrcweir {
74cdf0e10cSrcweir 	struct tClientType
75cdf0e10cSrcweir 	{
76cdf0e10cSrcweir 		// gilt fuer alle Links
77cdf0e10cSrcweir 		sal_uIntPtr				nCntntType; // Update Format
78cdf0e10cSrcweir 		// nicht Ole-Links
79cdf0e10cSrcweir 		sal_Bool 			bIntrnlLnk; // ist es ein interner Link
80cdf0e10cSrcweir 		sal_uInt16 			nUpdateMode;// UpdateMode
81cdf0e10cSrcweir 	};
82cdf0e10cSrcweir 
83cdf0e10cSrcweir 	struct tDDEType
84cdf0e10cSrcweir 	{
85cdf0e10cSrcweir 		ImplDdeItem* pItem;
86cdf0e10cSrcweir 	};
87cdf0e10cSrcweir 
88cdf0e10cSrcweir 	union {
89cdf0e10cSrcweir 		tClientType ClientType;
90cdf0e10cSrcweir 		tDDEType DDEType;
91cdf0e10cSrcweir 	};
ImplBaseLinkDatasfx2::ImplBaseLinkData92cdf0e10cSrcweir 	ImplBaseLinkData()
93cdf0e10cSrcweir 	{
94cdf0e10cSrcweir 		ClientType.nCntntType = 0;
95cdf0e10cSrcweir 		ClientType.bIntrnlLnk = sal_False;
96cdf0e10cSrcweir 		ClientType.nUpdateMode = 0;
97cdf0e10cSrcweir 		DDEType.pItem = NULL;
98cdf0e10cSrcweir 	}
99cdf0e10cSrcweir };
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 
102cdf0e10cSrcweir class ImplDdeItem : public DdeGetPutItem
103cdf0e10cSrcweir {
104cdf0e10cSrcweir 	SvBaseLink* pLink;
105cdf0e10cSrcweir 	DdeData aData;
106cdf0e10cSrcweir 	Sequence< sal_Int8 > aSeq;		    // Datacontainer for DdeData !!!
107cdf0e10cSrcweir 	sal_Bool bIsValidData : 1;
108cdf0e10cSrcweir 	sal_Bool bIsInDTOR : 1;
109cdf0e10cSrcweir public:
ImplDdeItem(SvBaseLink & rLink,const String & rStr)110cdf0e10cSrcweir 	ImplDdeItem( SvBaseLink& rLink, const String& rStr )
111cdf0e10cSrcweir 		: DdeGetPutItem( rStr ), pLink( &rLink ), bIsValidData( sal_False ),
112cdf0e10cSrcweir 		bIsInDTOR( sal_False )
113cdf0e10cSrcweir 	{}
114cdf0e10cSrcweir 	virtual ~ImplDdeItem();
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 	virtual DdeData* Get( sal_uIntPtr );
117cdf0e10cSrcweir 	virtual sal_Bool Put( const DdeData* );
118cdf0e10cSrcweir 	virtual void AdviseLoop( sal_Bool );
119cdf0e10cSrcweir 
Notify()120cdf0e10cSrcweir 	void Notify()
121cdf0e10cSrcweir 	{
122cdf0e10cSrcweir 		bIsValidData = sal_False;
123cdf0e10cSrcweir 		DdeGetPutItem::NotifyClient();
124cdf0e10cSrcweir 	}
125cdf0e10cSrcweir 
IsInDTOR() const126cdf0e10cSrcweir 	sal_Bool IsInDTOR() const { return bIsInDTOR; }
127cdf0e10cSrcweir };
128cdf0e10cSrcweir 
129cdf0e10cSrcweir 
130cdf0e10cSrcweir /************************************************************************
131cdf0e10cSrcweir |*	  SvBaseLink::SvBaseLink()
132cdf0e10cSrcweir |*
133cdf0e10cSrcweir |*	  Beschreibung
134cdf0e10cSrcweir *************************************************************************/
135cdf0e10cSrcweir 
SvBaseLink()136cdf0e10cSrcweir SvBaseLink::SvBaseLink()
137*eb494517SArmin Le Grand :   SvRefBase(),
138*eb494517SArmin Le Grand     xObj(),
139*eb494517SArmin Le Grand     aLinkName(),
140*eb494517SArmin Le Grand     pImpl(new BaseLink_Impl()),
141*eb494517SArmin Le Grand     nObjType(OBJECT_CLIENT_SO),
142*eb494517SArmin Le Grand     bVisible(sal_True),
143*eb494517SArmin Le Grand     bSynchron(sal_True),
144*eb494517SArmin Le Grand     bUseCache(sal_True),
145*eb494517SArmin Le Grand     bWasLastEditOK(sal_False),
146*eb494517SArmin Le Grand     pImplData(new ImplBaseLinkData),
147*eb494517SArmin Le Grand     m_bIsReadOnly(false),
148*eb494517SArmin Le Grand     m_xInputStreamToLoadFrom()
149cdf0e10cSrcweir {
150cdf0e10cSrcweir }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir /************************************************************************
153cdf0e10cSrcweir |*	  SvBaseLink::SvBaseLink()
154cdf0e10cSrcweir |*
155cdf0e10cSrcweir |*	  Beschreibung
156cdf0e10cSrcweir *************************************************************************/
157cdf0e10cSrcweir 
SvBaseLink(sal_uInt16 nUpdateMode,sal_uIntPtr nContentType)158cdf0e10cSrcweir SvBaseLink::SvBaseLink( sal_uInt16 nUpdateMode, sal_uIntPtr nContentType )
159*eb494517SArmin Le Grand :   SvRefBase(),
160*eb494517SArmin Le Grand     xObj(),
161*eb494517SArmin Le Grand     aLinkName(),
162*eb494517SArmin Le Grand     pImpl(new BaseLink_Impl()),
163*eb494517SArmin Le Grand     nObjType(OBJECT_CLIENT_SO),
164*eb494517SArmin Le Grand     bVisible(sal_True),
165*eb494517SArmin Le Grand     bSynchron(sal_True),
166*eb494517SArmin Le Grand     bUseCache(sal_True),
167*eb494517SArmin Le Grand     bWasLastEditOK(sal_False),
168*eb494517SArmin Le Grand     pImplData(new ImplBaseLinkData),
169*eb494517SArmin Le Grand     m_bIsReadOnly(false),
170*eb494517SArmin Le Grand     m_xInputStreamToLoadFrom()
171cdf0e10cSrcweir {
172cdf0e10cSrcweir 	// falls es ein Ole-Link wird,
173cdf0e10cSrcweir 	pImplData->ClientType.nUpdateMode = nUpdateMode;
174cdf0e10cSrcweir 	pImplData->ClientType.nCntntType = nContentType;
175cdf0e10cSrcweir 	pImplData->ClientType.bIntrnlLnk = sal_False;
176cdf0e10cSrcweir }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir /************************************************************************
179cdf0e10cSrcweir |*	  SvBaseLink::SvBaseLink()
180cdf0e10cSrcweir |*
181cdf0e10cSrcweir |*	  Beschreibung
182cdf0e10cSrcweir *************************************************************************/
183cdf0e10cSrcweir 
SvBaseLink(const String & rLinkName,sal_uInt16 nObjectType,SvLinkSource * pObj)184cdf0e10cSrcweir SvBaseLink::SvBaseLink( const String& rLinkName, sal_uInt16 nObjectType, SvLinkSource* pObj )
185*eb494517SArmin Le Grand :   SvRefBase(),
186*eb494517SArmin Le Grand     xObj(),
187*eb494517SArmin Le Grand     aLinkName(rLinkName),
188*eb494517SArmin Le Grand     pImpl(0),
189*eb494517SArmin Le Grand     nObjType(nObjectType),
190*eb494517SArmin Le Grand     bVisible(sal_True),
191*eb494517SArmin Le Grand     bSynchron(sal_True),
192*eb494517SArmin Le Grand     bUseCache(sal_True),
193*eb494517SArmin Le Grand     bWasLastEditOK(sal_False),
194*eb494517SArmin Le Grand     pImplData(new ImplBaseLinkData),
195*eb494517SArmin Le Grand     m_bIsReadOnly(false),
196*eb494517SArmin Le Grand     m_xInputStreamToLoadFrom()
197cdf0e10cSrcweir {
198cdf0e10cSrcweir 	if( !pObj )
199cdf0e10cSrcweir 	{
200cdf0e10cSrcweir 		DBG_ASSERT( pObj, "Wo ist mein zu linkendes Object" );
201cdf0e10cSrcweir 		return;
202cdf0e10cSrcweir 	}
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 	if( OBJECT_DDE_EXTERN == nObjType )
205cdf0e10cSrcweir 	{
206cdf0e10cSrcweir 		sal_uInt16 nItemStt = 0;
207cdf0e10cSrcweir 		DdeTopic* pTopic = FindTopic( aLinkName, &nItemStt );
208cdf0e10cSrcweir 		if( pTopic )
209cdf0e10cSrcweir 		{
210cdf0e10cSrcweir 			// dann haben wir alles zusammen
211cdf0e10cSrcweir 			// MM hat gefummelt ???
212cdf0e10cSrcweir 			// MM_TODO wie kriege ich den Namen
213cdf0e10cSrcweir 			String aStr = aLinkName; // xLinkName->GetDisplayName();
214cdf0e10cSrcweir 			aStr = aStr.Copy( nItemStt );
215cdf0e10cSrcweir 			pImplData->DDEType.pItem = new ImplDdeItem( *this, aStr );
216cdf0e10cSrcweir 			pTopic->InsertItem( pImplData->DDEType.pItem );
217cdf0e10cSrcweir 
218cdf0e10cSrcweir 			// dann koennen wir uns auch das Advise merken
219cdf0e10cSrcweir 			xObj = pObj;
220cdf0e10cSrcweir 		}
221cdf0e10cSrcweir 	}
222cdf0e10cSrcweir     else if( pObj->Connect( this ) )
223cdf0e10cSrcweir 		xObj = pObj;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir 
226cdf0e10cSrcweir /************************************************************************
227cdf0e10cSrcweir |*	  SvBaseLink::~SvBaseLink()
228cdf0e10cSrcweir |*
229cdf0e10cSrcweir |*	  Beschreibung
230cdf0e10cSrcweir *************************************************************************/
231cdf0e10cSrcweir 
~SvBaseLink()232cdf0e10cSrcweir SvBaseLink::~SvBaseLink()
233cdf0e10cSrcweir {
234cdf0e10cSrcweir 	Disconnect();
235cdf0e10cSrcweir 
236cdf0e10cSrcweir 	switch( nObjType )
237cdf0e10cSrcweir 	{
238cdf0e10cSrcweir 	case OBJECT_DDE_EXTERN:
239cdf0e10cSrcweir 		if( !pImplData->DDEType.pItem->IsInDTOR() )
240cdf0e10cSrcweir 			delete pImplData->DDEType.pItem;
241cdf0e10cSrcweir 		break;
242cdf0e10cSrcweir 	}
243cdf0e10cSrcweir 
244cdf0e10cSrcweir 	delete pImplData;
245*eb494517SArmin Le Grand 
246*eb494517SArmin Le Grand     if(pImpl)
247*eb494517SArmin Le Grand     {
248*eb494517SArmin Le Grand         delete pImpl;
249*eb494517SArmin Le Grand     }
250cdf0e10cSrcweir }
251cdf0e10cSrcweir 
IMPL_LINK(SvBaseLink,EndEditHdl,String *,_pNewName)252cdf0e10cSrcweir IMPL_LINK( SvBaseLink, EndEditHdl, String*, _pNewName )
253cdf0e10cSrcweir {
254*eb494517SArmin Le Grand     if(pImpl)
255*eb494517SArmin Le Grand     {
256*eb494517SArmin Le Grand         String sNewName;
257*eb494517SArmin Le Grand         if ( _pNewName )
258*eb494517SArmin Le Grand             sNewName = *_pNewName;
259*eb494517SArmin Le Grand         if ( !ExecuteEdit( sNewName ) )
260*eb494517SArmin Le Grand             sNewName.Erase();
261*eb494517SArmin Le Grand         bWasLastEditOK = ( sNewName.Len() > 0 );
262*eb494517SArmin Le Grand         if ( pImpl->m_aEndEditLink.IsSet() )
263*eb494517SArmin Le Grand             pImpl->m_aEndEditLink.Call( this );
264*eb494517SArmin Le Grand     }
265*eb494517SArmin Le Grand     else
266*eb494517SArmin Le Grand     {
267*eb494517SArmin Le Grand         OSL_ENSURE(false, "No pImpl (!)");
268*eb494517SArmin Le Grand     }
269cdf0e10cSrcweir     return 0;
270cdf0e10cSrcweir }
271cdf0e10cSrcweir 
272cdf0e10cSrcweir /************************************************************************
273cdf0e10cSrcweir |*	  SvBaseLink::SetObjType()
274cdf0e10cSrcweir |*
275cdf0e10cSrcweir |*	  Beschreibung
276cdf0e10cSrcweir *************************************************************************/
277cdf0e10cSrcweir 
SetObjType(sal_uInt16 nObjTypeP)278cdf0e10cSrcweir void SvBaseLink::SetObjType( sal_uInt16 nObjTypeP )
279cdf0e10cSrcweir {
280cdf0e10cSrcweir 	DBG_ASSERT( nObjType != OBJECT_CLIENT_DDE, "type already set" );
281cdf0e10cSrcweir 	DBG_ASSERT( !xObj.Is(), "object exist" );
282cdf0e10cSrcweir 
283cdf0e10cSrcweir 	nObjType = nObjTypeP;
284cdf0e10cSrcweir }
285cdf0e10cSrcweir 
286cdf0e10cSrcweir /************************************************************************
287cdf0e10cSrcweir |*	  SvBaseLink::SetName()
288cdf0e10cSrcweir |*
289cdf0e10cSrcweir |*	  Beschreibung
290cdf0e10cSrcweir *************************************************************************/
291cdf0e10cSrcweir 
SetName(const String & rNm)292cdf0e10cSrcweir void SvBaseLink::SetName( const String & rNm )
293cdf0e10cSrcweir {
294cdf0e10cSrcweir 	aLinkName = rNm;
295cdf0e10cSrcweir }
296cdf0e10cSrcweir 
297cdf0e10cSrcweir /************************************************************************
298cdf0e10cSrcweir |*	  SvBaseLink::GetName()
299cdf0e10cSrcweir |*
300cdf0e10cSrcweir |*	  Beschreibung
301cdf0e10cSrcweir *************************************************************************/
302cdf0e10cSrcweir 
GetName() const303cdf0e10cSrcweir String SvBaseLink::GetName() const
304cdf0e10cSrcweir {
305cdf0e10cSrcweir 	return aLinkName;
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
308cdf0e10cSrcweir /************************************************************************
309cdf0e10cSrcweir |*	  SvBaseLink::SetObj()
310cdf0e10cSrcweir |*
311cdf0e10cSrcweir |*	  Beschreibung
312cdf0e10cSrcweir *************************************************************************/
313cdf0e10cSrcweir 
SetObj(SvLinkSource * pObj)314cdf0e10cSrcweir void SvBaseLink::SetObj( SvLinkSource * pObj )
315cdf0e10cSrcweir {
316cdf0e10cSrcweir 	DBG_ASSERT( (nObjType & OBJECT_CLIENT_SO &&
317cdf0e10cSrcweir 				pImplData->ClientType.bIntrnlLnk) ||
318cdf0e10cSrcweir 				nObjType == OBJECT_CLIENT_GRF,
319cdf0e10cSrcweir 				"no intern link" );
320cdf0e10cSrcweir 	xObj = pObj;
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir /************************************************************************
324cdf0e10cSrcweir |*	  SvBaseLink::SetLinkSourceName()
325cdf0e10cSrcweir |*
326cdf0e10cSrcweir |*	  Beschreibung
327cdf0e10cSrcweir *************************************************************************/
328cdf0e10cSrcweir 
SetLinkSourceName(const String & rLnkNm)329cdf0e10cSrcweir void SvBaseLink::SetLinkSourceName( const String & rLnkNm )
330cdf0e10cSrcweir {
331cdf0e10cSrcweir 	if( aLinkName == rLnkNm )
332cdf0e10cSrcweir 		return;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 	AddNextRef(); // sollte ueberfluessig sein
335cdf0e10cSrcweir 	// Alte Verbindung weg
336cdf0e10cSrcweir 	Disconnect();
337cdf0e10cSrcweir 
338cdf0e10cSrcweir 	aLinkName = rLnkNm;
339cdf0e10cSrcweir 
340cdf0e10cSrcweir 	// Neu verbinden
341cdf0e10cSrcweir 	_GetRealObject();
342cdf0e10cSrcweir 	ReleaseRef(); // sollte ueberfluessig sein
343cdf0e10cSrcweir }
344cdf0e10cSrcweir 
345cdf0e10cSrcweir /************************************************************************
346cdf0e10cSrcweir |*	  SvBaseLink::GetLinkSourceName()
347cdf0e10cSrcweir |*
348cdf0e10cSrcweir |*	  Beschreibung
349cdf0e10cSrcweir *************************************************************************/
350cdf0e10cSrcweir 
GetLinkSourceName() const351cdf0e10cSrcweir String  SvBaseLink::GetLinkSourceName() const
352cdf0e10cSrcweir {
353cdf0e10cSrcweir 	return aLinkName;
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir 
357cdf0e10cSrcweir /************************************************************************
358cdf0e10cSrcweir |*	  SvBaseLink::SetUpdateMode()
359cdf0e10cSrcweir |*
360cdf0e10cSrcweir |*	  Beschreibung
361cdf0e10cSrcweir *************************************************************************/
362cdf0e10cSrcweir 
SetUpdateMode(sal_uInt16 nMode)363cdf0e10cSrcweir void SvBaseLink::SetUpdateMode( sal_uInt16 nMode )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir 	if( ( OBJECT_CLIENT_SO & nObjType ) &&
366cdf0e10cSrcweir 		pImplData->ClientType.nUpdateMode != nMode )
367cdf0e10cSrcweir 	{
368cdf0e10cSrcweir 		AddNextRef();
369cdf0e10cSrcweir 		Disconnect();
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 		pImplData->ClientType.nUpdateMode = nMode;
372cdf0e10cSrcweir 		_GetRealObject();
373cdf0e10cSrcweir 		ReleaseRef();
374cdf0e10cSrcweir 	}
375cdf0e10cSrcweir }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir // --> OD 2008-06-19 #i88291#
clearStreamToLoadFrom()378cdf0e10cSrcweir void SvBaseLink::clearStreamToLoadFrom()
379cdf0e10cSrcweir {
380cdf0e10cSrcweir     m_xInputStreamToLoadFrom.clear();
381cdf0e10cSrcweir     if( xObj.Is() )
382cdf0e10cSrcweir     {
383cdf0e10cSrcweir         xObj->clearStreamToLoadFrom();
384cdf0e10cSrcweir     }
385cdf0e10cSrcweir }
386cdf0e10cSrcweir // <--
387cdf0e10cSrcweir 
Update()388cdf0e10cSrcweir sal_Bool SvBaseLink::Update()
389cdf0e10cSrcweir {
390cdf0e10cSrcweir 	if( OBJECT_CLIENT_SO & nObjType )
391cdf0e10cSrcweir 	{
392cdf0e10cSrcweir 		AddNextRef();
393cdf0e10cSrcweir 		Disconnect();
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 		_GetRealObject();
396cdf0e10cSrcweir 		ReleaseRef();
397cdf0e10cSrcweir 		if( xObj.Is() )
398cdf0e10cSrcweir 		{
399cdf0e10cSrcweir             xObj->setStreamToLoadFrom(m_xInputStreamToLoadFrom,m_bIsReadOnly);
400cdf0e10cSrcweir             // m_xInputStreamToLoadFrom = 0;
401cdf0e10cSrcweir 			String sMimeType( SotExchange::GetFormatMimeType(
402cdf0e10cSrcweir 							pImplData->ClientType.nCntntType ));
403cdf0e10cSrcweir 			Any aData;
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 			if( xObj->GetData( aData, sMimeType ) )
406cdf0e10cSrcweir 			{
407cdf0e10cSrcweir 				DataChanged( sMimeType, aData );
408cdf0e10cSrcweir 				//JP 13.07.00: Bug 76817 - for manual Updates there is no
409cdf0e10cSrcweir 				//				need to hold the ServerObject
410cdf0e10cSrcweir 				if( OBJECT_CLIENT_DDE == nObjType &&
411cdf0e10cSrcweir 					LINKUPDATE_ONCALL == GetUpdateMode() && xObj.Is() )
412cdf0e10cSrcweir 					xObj->RemoveAllDataAdvise( this );
413cdf0e10cSrcweir 				return sal_True;
414cdf0e10cSrcweir 			}
415cdf0e10cSrcweir 			if( xObj.Is() )
416cdf0e10cSrcweir 			{
417cdf0e10cSrcweir 				// sollten wir asynschron sein?
418cdf0e10cSrcweir 				if( xObj->IsPending() )
419cdf0e10cSrcweir 					return sal_True;
420cdf0e10cSrcweir 
421cdf0e10cSrcweir 				// dann brauchen wir das Object auch nicht mehr
422cdf0e10cSrcweir 				AddNextRef();
423cdf0e10cSrcweir 				Disconnect();
424cdf0e10cSrcweir 				ReleaseRef();
425cdf0e10cSrcweir 			}
426cdf0e10cSrcweir 		}
427cdf0e10cSrcweir 	}
428cdf0e10cSrcweir 	return sal_False;
429cdf0e10cSrcweir }
430cdf0e10cSrcweir 
431cdf0e10cSrcweir 
GetUpdateMode() const432cdf0e10cSrcweir sal_uInt16 SvBaseLink::GetUpdateMode() const
433cdf0e10cSrcweir {
434cdf0e10cSrcweir     return ( OBJECT_CLIENT_SO & nObjType )
435cdf0e10cSrcweir 			? pImplData->ClientType.nUpdateMode
436cdf0e10cSrcweir 			: sal::static_int_cast< sal_uInt16 >( LINKUPDATE_ONCALL );
437cdf0e10cSrcweir }
438cdf0e10cSrcweir 
439cdf0e10cSrcweir 
_GetRealObject(sal_Bool bConnect)440cdf0e10cSrcweir void SvBaseLink::_GetRealObject( sal_Bool bConnect)
441cdf0e10cSrcweir {
442*eb494517SArmin Le Grand     if(pImpl)
443*eb494517SArmin Le Grand     {
444*eb494517SArmin Le Grand         if( !pImpl->m_pLinkMgr )
445*eb494517SArmin Le Grand 		    return;
446*eb494517SArmin Le Grand 
447*eb494517SArmin Le Grand 	    DBG_ASSERT( !xObj.Is(), "object already exist" );
448*eb494517SArmin Le Grand 
449*eb494517SArmin Le Grand 	    if( OBJECT_CLIENT_DDE == nObjType )
450*eb494517SArmin Le Grand 	    {
451*eb494517SArmin Le Grand 		    String sServer;
452*eb494517SArmin Le Grand             if( pImpl->m_pLinkMgr->GetDisplayNames( this, &sServer ) &&
453*eb494517SArmin Le Grand 			    sServer == GetpApp()->GetAppName() )		// interner Link !!!
454*eb494517SArmin Le Grand 		    {
455*eb494517SArmin Le Grand 			    // damit der Internal - Link erzeugt werden kann !!!
456*eb494517SArmin Le Grand 			    nObjType = OBJECT_INTERN;
457*eb494517SArmin Le Grand                 xObj = pImpl->m_pLinkMgr->CreateObj( this );
458*eb494517SArmin Le Grand 
459*eb494517SArmin Le Grand 			    pImplData->ClientType.bIntrnlLnk = sal_True;
460*eb494517SArmin Le Grand 			    nObjType = OBJECT_CLIENT_DDE;		// damit wir wissen was es mal war !!
461*eb494517SArmin Le Grand 		    }
462*eb494517SArmin Le Grand 		    else
463*eb494517SArmin Le Grand 		    {
464*eb494517SArmin Le Grand 			    pImplData->ClientType.bIntrnlLnk = sal_False;
465*eb494517SArmin Le Grand                 xObj = pImpl->m_pLinkMgr->CreateObj( this );
466*eb494517SArmin Le Grand 		    }
467*eb494517SArmin Le Grand 	    }
468*eb494517SArmin Le Grand 	    else if( OBJECT_CLIENT_SO & nObjType )
469cdf0e10cSrcweir             xObj = pImpl->m_pLinkMgr->CreateObj( this );
470cdf0e10cSrcweir 
471*eb494517SArmin Le Grand         if( bConnect && ( !xObj.Is() || !xObj->Connect( this ) ) )
472*eb494517SArmin Le Grand 		    Disconnect();
473*eb494517SArmin Le Grand     }
474*eb494517SArmin Le Grand     else
475*eb494517SArmin Le Grand     {
476*eb494517SArmin Le Grand         OSL_ENSURE(false, "No pImpl (!)");
477*eb494517SArmin Le Grand     }
478cdf0e10cSrcweir }
479cdf0e10cSrcweir 
GetContentType() const480cdf0e10cSrcweir sal_uIntPtr SvBaseLink::GetContentType() const
481cdf0e10cSrcweir {
482cdf0e10cSrcweir 	if( OBJECT_CLIENT_SO & nObjType )
483cdf0e10cSrcweir 		return pImplData->ClientType.nCntntType;
484cdf0e10cSrcweir 
485cdf0e10cSrcweir 	return 0;		// alle Formate ?
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
488cdf0e10cSrcweir 
SetContentType(sal_uIntPtr nType)489cdf0e10cSrcweir sal_Bool SvBaseLink::SetContentType( sal_uIntPtr nType )
490cdf0e10cSrcweir {
491cdf0e10cSrcweir 	if( OBJECT_CLIENT_SO & nObjType )
492cdf0e10cSrcweir 	{
493cdf0e10cSrcweir 		pImplData->ClientType.nCntntType = nType;
494cdf0e10cSrcweir 		return sal_True;
495cdf0e10cSrcweir 	}
496cdf0e10cSrcweir 	return sal_False;
497cdf0e10cSrcweir }
498cdf0e10cSrcweir 
GetLinkManager()499cdf0e10cSrcweir LinkManager* SvBaseLink::GetLinkManager()
500cdf0e10cSrcweir {
501*eb494517SArmin Le Grand     if(pImpl)
502*eb494517SArmin Le Grand     {
503*eb494517SArmin Le Grand         return pImpl->m_pLinkMgr;
504*eb494517SArmin Le Grand     }
505*eb494517SArmin Le Grand 
506*eb494517SArmin Le Grand     return 0;
507cdf0e10cSrcweir }
508cdf0e10cSrcweir 
GetLinkManager() const509cdf0e10cSrcweir const LinkManager* SvBaseLink::GetLinkManager() const
510cdf0e10cSrcweir {
511*eb494517SArmin Le Grand     if(pImpl)
512*eb494517SArmin Le Grand     {
513*eb494517SArmin Le Grand         return pImpl->m_pLinkMgr;
514*eb494517SArmin Le Grand     }
515*eb494517SArmin Le Grand 
516*eb494517SArmin Le Grand     return 0;
517cdf0e10cSrcweir }
518cdf0e10cSrcweir 
SetLinkManager(LinkManager * _pMgr)519cdf0e10cSrcweir void SvBaseLink::SetLinkManager( LinkManager* _pMgr )
520cdf0e10cSrcweir {
521*eb494517SArmin Le Grand     if(pImpl)
522*eb494517SArmin Le Grand     {
523*eb494517SArmin Le Grand         pImpl->m_pLinkMgr = _pMgr;
524*eb494517SArmin Le Grand     }
525*eb494517SArmin Le Grand     else
526*eb494517SArmin Le Grand     {
527*eb494517SArmin Le Grand         OSL_ENSURE(false, "No pImpl (!)");
528*eb494517SArmin Le Grand     }
529cdf0e10cSrcweir }
530cdf0e10cSrcweir 
Disconnect()531cdf0e10cSrcweir void SvBaseLink::Disconnect()
532cdf0e10cSrcweir {
533cdf0e10cSrcweir 	if( xObj.Is() )
534cdf0e10cSrcweir 	{
535cdf0e10cSrcweir 		xObj->RemoveAllDataAdvise( this );
536cdf0e10cSrcweir 		xObj->RemoveConnectAdvise( this );
537cdf0e10cSrcweir 		xObj.Clear();
538cdf0e10cSrcweir 	}
539cdf0e10cSrcweir }
540cdf0e10cSrcweir 
DataChanged(const String &,const::com::sun::star::uno::Any &)541cdf0e10cSrcweir void SvBaseLink::DataChanged( const String &, const ::com::sun::star::uno::Any & )
542cdf0e10cSrcweir {
543cdf0e10cSrcweir 	switch( nObjType )
544cdf0e10cSrcweir 	{
545cdf0e10cSrcweir 	case OBJECT_DDE_EXTERN:
546cdf0e10cSrcweir 		if( pImplData->DDEType.pItem )
547cdf0e10cSrcweir 			pImplData->DDEType.pItem->Notify();
548cdf0e10cSrcweir 		break;
549cdf0e10cSrcweir 	}
550cdf0e10cSrcweir }
551cdf0e10cSrcweir 
Edit(Window * pParent,const Link & rEndEditHdl)552cdf0e10cSrcweir void SvBaseLink::Edit( Window* pParent, const Link& rEndEditHdl )
553cdf0e10cSrcweir {
554*eb494517SArmin Le Grand     if(pImpl)
555cdf0e10cSrcweir     {
556*eb494517SArmin Le Grand         pImpl->m_pParentWin = pParent;
557*eb494517SArmin Le Grand         pImpl->m_aEndEditLink = rEndEditHdl;
558*eb494517SArmin Le Grand         pImpl->m_bIsConnect = ( xObj.Is() != sal_False );
559*eb494517SArmin Le Grand         if( !pImpl->m_bIsConnect )
560*eb494517SArmin Le Grand 		    _GetRealObject( xObj.Is() );
561*eb494517SArmin Le Grand 
562*eb494517SArmin Le Grand         bool bAsync = false;
563*eb494517SArmin Le Grand         Link aLink = LINK( this, SvBaseLink, EndEditHdl );
564*eb494517SArmin Le Grand 
565*eb494517SArmin Le Grand         if( OBJECT_CLIENT_SO & nObjType && pImplData->ClientType.bIntrnlLnk )
566*eb494517SArmin Le Grand 	    {
567*eb494517SArmin Le Grand             if( pImpl->m_pLinkMgr )
568*eb494517SArmin Le Grand 		    {
569*eb494517SArmin Le Grand                 SvLinkSourceRef ref = pImpl->m_pLinkMgr->CreateObj( this );
570*eb494517SArmin Le Grand 			    if( ref.Is() )
571*eb494517SArmin Le Grand                 {
572*eb494517SArmin Le Grand                     ref->Edit( pParent, this, aLink );
573*eb494517SArmin Le Grand                     bAsync = true;
574*eb494517SArmin Le Grand                 }
575*eb494517SArmin Le Grand 		    }
576*eb494517SArmin Le Grand 	    }
577*eb494517SArmin Le Grand 	    else
578*eb494517SArmin Le Grand         {
579*eb494517SArmin Le Grand             xObj->Edit( pParent, this, aLink );
580*eb494517SArmin Le Grand             bAsync = true;
581*eb494517SArmin Le Grand         }
582cdf0e10cSrcweir 
583*eb494517SArmin Le Grand         if ( !bAsync )
584*eb494517SArmin Le Grand         {
585*eb494517SArmin Le Grand             ExecuteEdit( String() );
586*eb494517SArmin Le Grand             bWasLastEditOK = sal_False;
587*eb494517SArmin Le Grand             if ( pImpl->m_aEndEditLink.IsSet() )
588*eb494517SArmin Le Grand                 pImpl->m_aEndEditLink.Call( this );
589*eb494517SArmin Le Grand         }
590*eb494517SArmin Le Grand     }
591*eb494517SArmin Le Grand     else
592cdf0e10cSrcweir     {
593*eb494517SArmin Le Grand         OSL_ENSURE(false, "No pImpl (!)");
594cdf0e10cSrcweir     }
595cdf0e10cSrcweir }
596cdf0e10cSrcweir 
ExecuteEdit(const String & _rNewName)597cdf0e10cSrcweir bool SvBaseLink::ExecuteEdit( const String& _rNewName )
598cdf0e10cSrcweir {
599*eb494517SArmin Le Grand     if(pImpl)
600cdf0e10cSrcweir     {
601*eb494517SArmin Le Grand         if( _rNewName.Len() != 0 )
602cdf0e10cSrcweir         {
603*eb494517SArmin Le Grand             SetLinkSourceName( _rNewName );
604*eb494517SArmin Le Grand             if( !Update() )
605cdf0e10cSrcweir             {
606*eb494517SArmin Le Grand                 String sApp, sTopic, sItem, sError;
607*eb494517SArmin Le Grand                 pImpl->m_pLinkMgr->GetDisplayNames( this, &sApp, &sTopic, &sItem );
608*eb494517SArmin Le Grand                 if( nObjType == OBJECT_CLIENT_DDE )
609cdf0e10cSrcweir                 {
610*eb494517SArmin Le Grand                     sError = SfxResId( STR_DDE_ERROR );
611*eb494517SArmin Le Grand 
612*eb494517SArmin Le Grand                     sal_uInt16 nFndPos = sError.Search( '%' );
613*eb494517SArmin Le Grand                     if( STRING_NOTFOUND != nFndPos )
614*eb494517SArmin Le Grand                     {
615*eb494517SArmin Le Grand                         sError.Erase( nFndPos, 1 ).Insert( sApp, nFndPos );
616*eb494517SArmin Le Grand                         nFndPos = nFndPos + sApp.Len();
617*eb494517SArmin Le Grand                     }
618*eb494517SArmin Le Grand                     if( STRING_NOTFOUND != ( nFndPos = sError.Search( '%', nFndPos )))
619*eb494517SArmin Le Grand                     {
620*eb494517SArmin Le Grand                         sError.Erase( nFndPos, 1 ).Insert( sTopic, nFndPos );
621*eb494517SArmin Le Grand                         nFndPos = nFndPos + sTopic.Len();
622*eb494517SArmin Le Grand                     }
623*eb494517SArmin Le Grand                     if( STRING_NOTFOUND != ( nFndPos = sError.Search( '%', nFndPos )))
624*eb494517SArmin Le Grand                         sError.Erase( nFndPos, 1 ).Insert( sItem, nFndPos );
625cdf0e10cSrcweir                 }
626*eb494517SArmin Le Grand                 else
627*eb494517SArmin Le Grand                     return false;
628cdf0e10cSrcweir 
629*eb494517SArmin Le Grand                 ErrorBox( pImpl->m_pParentWin, WB_OK, sError ).Execute();
630*eb494517SArmin Le Grand             }
631cdf0e10cSrcweir         }
632*eb494517SArmin Le Grand         else if( !pImpl->m_bIsConnect )
633*eb494517SArmin Le Grand             Disconnect();
634*eb494517SArmin Le Grand         pImpl->m_bIsConnect = false;
635*eb494517SArmin Le Grand         return true;
636*eb494517SArmin Le Grand     }
637*eb494517SArmin Le Grand     else
638*eb494517SArmin Le Grand     {
639*eb494517SArmin Le Grand         OSL_ENSURE(false, "No pImpl (!)");
640*eb494517SArmin Le Grand         return false;
641cdf0e10cSrcweir     }
642cdf0e10cSrcweir }
643cdf0e10cSrcweir 
Closed()644cdf0e10cSrcweir void SvBaseLink::Closed()
645cdf0e10cSrcweir {
646cdf0e10cSrcweir     if( xObj.Is() )
647cdf0e10cSrcweir         // beim Advise Abmelden
648cdf0e10cSrcweir         xObj->RemoveAllDataAdvise( this );
649cdf0e10cSrcweir }
650cdf0e10cSrcweir 
GetFileDialog(sal_uInt32 nFlags,const String & rFactory) const651cdf0e10cSrcweir FileDialogHelper* SvBaseLink::GetFileDialog( sal_uInt32 nFlags, const String& rFactory ) const
652cdf0e10cSrcweir {
653*eb494517SArmin Le Grand     if(pImpl)
654*eb494517SArmin Le Grand     {
655*eb494517SArmin Le Grand         if ( pImpl->m_pFileDlg )
656*eb494517SArmin Le Grand             delete pImpl->m_pFileDlg;
657*eb494517SArmin Le Grand         pImpl->m_pFileDlg = new FileDialogHelper( nFlags, rFactory );
658*eb494517SArmin Le Grand         return pImpl->m_pFileDlg;
659*eb494517SArmin Le Grand     }
660*eb494517SArmin Le Grand     else
661*eb494517SArmin Le Grand     {
662*eb494517SArmin Le Grand         OSL_ENSURE(false, "No pImpl (!)");
663*eb494517SArmin Le Grand         return 0;
664*eb494517SArmin Le Grand     }
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
~ImplDdeItem()667cdf0e10cSrcweir ImplDdeItem::~ImplDdeItem()
668cdf0e10cSrcweir {
669cdf0e10cSrcweir 	bIsInDTOR = sal_True;
670cdf0e10cSrcweir 	// damit im Disconnect nicht jemand auf die Idee kommt, den Pointer zu
671cdf0e10cSrcweir 	// loeschen!!
672cdf0e10cSrcweir 	SvBaseLinkRef aRef( pLink );
673cdf0e10cSrcweir 	aRef->Disconnect();
674cdf0e10cSrcweir }
675cdf0e10cSrcweir 
Get(sal_uIntPtr nFormat)676cdf0e10cSrcweir DdeData* ImplDdeItem::Get( sal_uIntPtr nFormat )
677cdf0e10cSrcweir {
678cdf0e10cSrcweir 	if( pLink->GetObj() )
679cdf0e10cSrcweir 	{
680cdf0e10cSrcweir 		// ist das noch gueltig?
681cdf0e10cSrcweir 		if( bIsValidData && nFormat == aData.GetFormat() )
682cdf0e10cSrcweir 			return &aData;
683cdf0e10cSrcweir 
684cdf0e10cSrcweir 		Any aValue;
685cdf0e10cSrcweir 		String sMimeType( SotExchange::GetFormatMimeType( nFormat ));
686cdf0e10cSrcweir 		if( pLink->GetObj()->GetData( aValue, sMimeType ) )
687cdf0e10cSrcweir 		{
688cdf0e10cSrcweir 			if( aValue >>= aSeq )
689cdf0e10cSrcweir 			{
690cdf0e10cSrcweir 				aData = DdeData( (const char *)aSeq.getConstArray(), aSeq.getLength(), nFormat );
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 				bIsValidData = sal_True;
693cdf0e10cSrcweir 				return &aData;
694cdf0e10cSrcweir 			}
695cdf0e10cSrcweir 		}
696cdf0e10cSrcweir 	}
697cdf0e10cSrcweir 	aSeq.realloc( 0 );
698cdf0e10cSrcweir 	bIsValidData = sal_False;
699cdf0e10cSrcweir 	return 0;
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
702cdf0e10cSrcweir 
Put(const DdeData *)703cdf0e10cSrcweir sal_Bool ImplDdeItem::Put( const DdeData*  )
704cdf0e10cSrcweir {
705cdf0e10cSrcweir 	DBG_ERROR( "ImplDdeItem::Put not implemented" );
706cdf0e10cSrcweir 	return sal_False;
707cdf0e10cSrcweir }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir 
AdviseLoop(sal_Bool bOpen)710cdf0e10cSrcweir void ImplDdeItem::AdviseLoop( sal_Bool bOpen )
711cdf0e10cSrcweir {
712cdf0e10cSrcweir 	// Verbindung wird geschlossen, also Link abmelden
713cdf0e10cSrcweir 	if( pLink->GetObj() )
714cdf0e10cSrcweir 	{
715cdf0e10cSrcweir 		if( bOpen )
716cdf0e10cSrcweir 		{
717cdf0e10cSrcweir 			// es wird wieder eine Verbindung hergestellt
718cdf0e10cSrcweir 			if( OBJECT_DDE_EXTERN == pLink->GetObjType() )
719cdf0e10cSrcweir 			{
720cdf0e10cSrcweir 				pLink->GetObj()->AddDataAdvise( pLink, String::CreateFromAscii( "text/plain;charset=utf-16" ),	ADVISEMODE_NODATA );
721cdf0e10cSrcweir 				pLink->GetObj()->AddConnectAdvise( pLink );
722cdf0e10cSrcweir 			}
723cdf0e10cSrcweir 		}
724cdf0e10cSrcweir 		else
725cdf0e10cSrcweir 		{
726cdf0e10cSrcweir 			// damit im Disconnect nicht jemand auf die Idee kommt,
727cdf0e10cSrcweir 			// den Pointer zu loeschen!!
728cdf0e10cSrcweir 			SvBaseLinkRef aRef( pLink );
729cdf0e10cSrcweir 			aRef->Disconnect();
730cdf0e10cSrcweir 		}
731cdf0e10cSrcweir 	}
732cdf0e10cSrcweir }
733cdf0e10cSrcweir 
734cdf0e10cSrcweir 
FindTopic(const String & rLinkName,sal_uInt16 * pItemStt)735cdf0e10cSrcweir static DdeTopic* FindTopic( const String & rLinkName, sal_uInt16* pItemStt )
736cdf0e10cSrcweir {
737cdf0e10cSrcweir 	if( 0 == rLinkName.Len() )
738cdf0e10cSrcweir 		return 0;
739cdf0e10cSrcweir 
740cdf0e10cSrcweir 	String sNm( rLinkName );
741cdf0e10cSrcweir 	sal_uInt16 nTokenPos = 0;
742cdf0e10cSrcweir 	String sService( sNm.GetToken( 0, cTokenSeperator, nTokenPos ) );
743cdf0e10cSrcweir 
744cdf0e10cSrcweir 	DdeServices& rSvc = DdeService::GetServices();
745cdf0e10cSrcweir 	for( DdeService* pService = rSvc.First(); pService;
746cdf0e10cSrcweir 												pService = rSvc.Next() )
747cdf0e10cSrcweir 		if( pService->GetName() == sService )
748cdf0e10cSrcweir 		{
749cdf0e10cSrcweir 			// dann suchen wir uns das Topic
750cdf0e10cSrcweir 			String sTopic( sNm.GetToken( 0, cTokenSeperator, nTokenPos ) );
751cdf0e10cSrcweir 			if( pItemStt )
752cdf0e10cSrcweir 				*pItemStt = nTokenPos;
753cdf0e10cSrcweir 
754cdf0e10cSrcweir 			DdeTopics& rTopics = pService->GetTopics();
755cdf0e10cSrcweir 
756cdf0e10cSrcweir 			for( int i = 0; i < 2; ++i )
757cdf0e10cSrcweir 			{
758cdf0e10cSrcweir 				for( DdeTopic* pTopic = rTopics.First(); pTopic;
759cdf0e10cSrcweir 												pTopic = rTopics.Next() )
760cdf0e10cSrcweir 					if( pTopic->GetName() == sTopic )
761cdf0e10cSrcweir 						return pTopic;
762cdf0e10cSrcweir 
763cdf0e10cSrcweir 				// Topic nicht gefunden ?
764cdf0e10cSrcweir 				// dann versuchen wir ihn mal anzulegen
765cdf0e10cSrcweir 				if( i || !pService->MakeTopic( sTopic ) )
766cdf0e10cSrcweir 					break;	// hat nicht geklappt, also raus
767cdf0e10cSrcweir 			}
768cdf0e10cSrcweir 			break;
769cdf0e10cSrcweir 		}
770cdf0e10cSrcweir 	return 0;
771cdf0e10cSrcweir }
772cdf0e10cSrcweir 
773cdf0e10cSrcweir }
774