merge the formfield patch from ooo-build
[ooovba.git] / sfx2 / source / appl / linksrc.cxx
blob5892f9978170bc94d75087c192ea361ab341fbac
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: linksrc.cxx,v $
10 * $Revision: 1.12 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sfx2.hxx"
34 #include <sfx2/linksrc.hxx>
35 #include <sfx2/lnkbase.hxx>
36 //#include <sot/exchange.hxx>
37 #include <com/sun/star/uno/Any.hxx>
38 #include <com/sun/star/uno/Sequence.hxx>
40 #include <tools/debug.hxx>
41 #include <vcl/timer.hxx>
42 #include <svtools/svarray.hxx>
45 using namespace ::com::sun::star::uno;
47 namespace sfx2
50 TYPEINIT0( SvLinkSource )
52 /************** class SvLinkSourceTimer *********************************/
53 class SvLinkSourceTimer : public Timer
55 SvLinkSource * pOwner;
56 virtual void Timeout();
57 public:
58 SvLinkSourceTimer( SvLinkSource * pOwn );
61 SvLinkSourceTimer::SvLinkSourceTimer( SvLinkSource * pOwn )
62 : pOwner( pOwn )
66 void SvLinkSourceTimer::Timeout()
68 // sicher gegen zerstoeren im Handler
69 SvLinkSourceRef aAdv( pOwner );
70 pOwner->SendDataChanged();
73 static void StartTimer( SvLinkSourceTimer ** ppTimer, SvLinkSource * pOwner,
74 ULONG nTimeout )
76 if( !*ppTimer )
78 *ppTimer = new SvLinkSourceTimer( pOwner );
79 (*ppTimer)->SetTimeout( nTimeout );
80 (*ppTimer)->Start();
85 struct SvLinkSource_Entry_Impl
87 SvBaseLinkRef xSink;
88 String aDataMimeType;
89 USHORT nAdviseModes;
90 BOOL bIsDataSink;
92 SvLinkSource_Entry_Impl( SvBaseLink* pLink, const String& rMimeType,
93 USHORT nAdvMode )
94 : xSink( pLink ), aDataMimeType( rMimeType ),
95 nAdviseModes( nAdvMode ), bIsDataSink( TRUE )
98 SvLinkSource_Entry_Impl( SvBaseLink* pLink )
99 : xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( FALSE )
102 ~SvLinkSource_Entry_Impl();
105 SvLinkSource_Entry_Impl::~SvLinkSource_Entry_Impl()
109 typedef SvLinkSource_Entry_Impl* SvLinkSource_Entry_ImplPtr;
110 SV_DECL_PTRARR_DEL( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr, 4, 4 )
111 SV_IMPL_PTRARR( SvLinkSource_Array_Impl, SvLinkSource_Entry_ImplPtr );
113 class SvLinkSource_EntryIter_Impl
115 SvLinkSource_Array_Impl aArr;
116 const SvLinkSource_Array_Impl& rOrigArr;
117 USHORT nPos;
118 public:
119 SvLinkSource_EntryIter_Impl( const SvLinkSource_Array_Impl& rArr );
120 ~SvLinkSource_EntryIter_Impl();
121 SvLinkSource_Entry_Impl* Curr()
122 { return nPos < aArr.Count() ? aArr[ nPos ] : 0; }
123 SvLinkSource_Entry_Impl* Next();
124 sal_Bool IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry );
127 SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl(
128 const SvLinkSource_Array_Impl& rArr )
129 : rOrigArr( rArr ), nPos( 0 )
131 aArr.Insert( &rArr, 0 );
133 SvLinkSource_EntryIter_Impl::~SvLinkSource_EntryIter_Impl()
135 aArr.Remove( 0, aArr.Count() );
138 sal_Bool SvLinkSource_EntryIter_Impl::IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry )
140 return ( nPos < aArr.Count() && aArr[nPos] == pEntry && USHRT_MAX != rOrigArr.GetPos( pEntry ) );
143 SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next()
145 SvLinkSource_Entry_ImplPtr pRet = 0;
146 if( nPos + 1 < aArr.Count() )
148 ++nPos;
149 if( rOrigArr.Count() == aArr.Count() &&
150 rOrigArr[ nPos ] == aArr[ nPos ] )
151 pRet = aArr[ nPos ];
152 else
154 // then we must search the current (or the next) in the orig
155 do {
156 pRet = aArr[ nPos ];
157 if( USHRT_MAX != rOrigArr.GetPos( pRet ))
158 break;
159 pRet = 0;
160 ++nPos;
161 } while( nPos < aArr.Count() );
163 if( nPos >= aArr.Count() )
164 pRet = 0;
167 return pRet;
170 struct SvLinkSource_Impl
172 SvLinkSource_Array_Impl aArr;
173 String aDataMimeType;
174 SvLinkSourceTimer * pTimer;
175 ULONG nTimeout;
176 com::sun::star::uno::Reference<com::sun::star::io::XInputStream>
177 m_xInputStreamToLoadFrom;
178 sal_Bool m_bIsReadOnly;
180 SvLinkSource_Impl() : pTimer( 0 ), nTimeout( 3000 ) {}
181 ~SvLinkSource_Impl();
183 void Closed();
186 SvLinkSource_Impl::~SvLinkSource_Impl()
188 delete pTimer;
191 SvLinkSource::SvLinkSource()
192 : pImpl( new SvLinkSource_Impl )
196 SvLinkSource::~SvLinkSource()
198 delete pImpl;
202 SvLinkSource::StreamToLoadFrom SvLinkSource::getStreamToLoadFrom()
204 return StreamToLoadFrom(
205 pImpl->m_xInputStreamToLoadFrom,
206 pImpl->m_bIsReadOnly);
209 void SvLinkSource::setStreamToLoadFrom(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream,sal_Bool bIsReadOnly )
211 pImpl->m_xInputStreamToLoadFrom = xInputStream;
212 pImpl->m_bIsReadOnly = bIsReadOnly;
215 // --> OD 2008-06-18 #i88291#
216 void SvLinkSource::clearStreamToLoadFrom()
218 pImpl->m_xInputStreamToLoadFrom.clear();
220 // <--
222 void SvLinkSource::Closed()
224 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
225 for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
226 if( !p->bIsDataSink )
227 p->xSink->Closed();
230 ULONG SvLinkSource::GetUpdateTimeout() const
232 return pImpl->nTimeout;
235 void SvLinkSource::SetUpdateTimeout( ULONG nTimeout )
237 pImpl->nTimeout = nTimeout;
238 if( pImpl->pTimer )
239 pImpl->pTimer->SetTimeout( nTimeout );
242 void SvLinkSource::SendDataChanged()
244 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
245 for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
247 if( p->bIsDataSink )
249 String sDataMimeType( pImpl->aDataMimeType );
250 if( !sDataMimeType.Len() )
251 sDataMimeType = p->aDataMimeType;
253 Any aVal;
254 if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
255 GetData( aVal, sDataMimeType, TRUE ) )
257 p->xSink->DataChanged( sDataMimeType, aVal );
259 if ( !aIter.IsValidCurrValue( p ) )
260 continue;
262 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
264 USHORT nFndPos = pImpl->aArr.GetPos( p );
265 if( USHRT_MAX != nFndPos )
266 pImpl->aArr.DeleteAndDestroy( nFndPos );
272 if( pImpl->pTimer )
274 delete pImpl->pTimer;
275 pImpl->pTimer = NULL;
277 pImpl->aDataMimeType.Erase();
280 void SvLinkSource::NotifyDataChanged()
282 if( pImpl->nTimeout )
283 StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu
284 else
286 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
287 for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
288 if( p->bIsDataSink )
290 Any aVal;
291 if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
292 GetData( aVal, p->aDataMimeType, TRUE ) )
294 p->xSink->DataChanged( p->aDataMimeType, aVal );
296 if ( !aIter.IsValidCurrValue( p ) )
297 continue;
299 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
301 USHORT nFndPos = pImpl->aArr.GetPos( p );
302 if( USHRT_MAX != nFndPos )
303 pImpl->aArr.DeleteAndDestroy( nFndPos );
308 if( pImpl->pTimer )
310 delete pImpl->pTimer;
311 pImpl->pTimer = NULL;
316 // notify the sink, the mime type is not
317 // a selection criterion
318 void SvLinkSource::DataChanged( const String & rMimeType,
319 const ::com::sun::star::uno::Any & rVal )
321 if( pImpl->nTimeout && !rVal.hasValue() )
322 { // nur wenn keine Daten mitgegeben wurden
323 // fire all data to the sink, independent of the requested format
324 pImpl->aDataMimeType = rMimeType;
325 StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // Timeout neu
327 else
329 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
330 for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
332 if( p->bIsDataSink )
334 p->xSink->DataChanged( rMimeType, rVal );
336 if ( !aIter.IsValidCurrValue( p ) )
337 continue;
339 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
341 USHORT nFndPos = pImpl->aArr.GetPos( p );
342 if( USHRT_MAX != nFndPos )
343 pImpl->aArr.DeleteAndDestroy( nFndPos );
348 if( pImpl->pTimer )
350 delete pImpl->pTimer;
351 pImpl->pTimer = NULL;
357 // only one link is correct
358 void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const String& rMimeType,
359 USHORT nAdviseModes )
361 SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl(
362 pLink, rMimeType, nAdviseModes );
363 pImpl->aArr.Insert( pNew, pImpl->aArr.Count() );
366 void SvLinkSource::RemoveAllDataAdvise( SvBaseLink * pLink )
368 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
369 for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
370 if( p->bIsDataSink && &p->xSink == pLink )
372 USHORT nFndPos = pImpl->aArr.GetPos( p );
373 if( USHRT_MAX != nFndPos )
374 pImpl->aArr.DeleteAndDestroy( nFndPos );
378 // only one link is correct
379 void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink )
381 SvLinkSource_Entry_ImplPtr pNew = new SvLinkSource_Entry_Impl( pLink );
382 pImpl->aArr.Insert( pNew, pImpl->aArr.Count() );
385 void SvLinkSource::RemoveConnectAdvise( SvBaseLink * pLink )
387 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
388 for( SvLinkSource_Entry_ImplPtr p = aIter.Curr(); p; p = aIter.Next() )
389 if( !p->bIsDataSink && &p->xSink == pLink )
391 USHORT nFndPos = pImpl->aArr.GetPos( p );
392 if( USHRT_MAX != nFndPos )
393 pImpl->aArr.DeleteAndDestroy( nFndPos );
397 BOOL SvLinkSource::HasDataLinks( const SvBaseLink* pLink ) const
399 BOOL bRet = FALSE;
400 const SvLinkSource_Entry_Impl* p;
401 for( USHORT n = 0, nEnd = pImpl->aArr.Count(); n < nEnd; ++n )
402 if( ( p = pImpl->aArr[ n ] )->bIsDataSink &&
403 ( !pLink || &p->xSink == pLink ) )
405 bRet = TRUE;
406 break;
408 return bRet;
411 // TRUE => waitinmg for data
412 BOOL SvLinkSource::IsPending() const
414 return FALSE;
417 // TRUE => data complete loaded
418 BOOL SvLinkSource::IsDataComplete() const
420 return TRUE;
423 BOOL SvLinkSource::Connect( SvBaseLink* )
425 return TRUE;
428 BOOL SvLinkSource::GetData( ::com::sun::star::uno::Any &, const String &, BOOL )
430 return FALSE;
433 void SvLinkSource::Edit( Window *, SvBaseLink *, const Link& )