bump product version to 4.2.0.1
[LibreOffice.git] / sfx2 / source / appl / linksrc.cxx
blob7b29f37e0f739c7002ed427ce5c9d3b86a23fa55
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <sfx2/linksrc.hxx>
22 #include <sfx2/lnkbase.hxx>
23 #include <com/sun/star/uno/Any.hxx>
24 #include <com/sun/star/uno/Sequence.hxx>
26 #include <vcl/timer.hxx>
27 #include <vector>
28 #include <algorithm>
31 using namespace ::com::sun::star::uno;
33 namespace sfx2
36 TYPEINIT0( SvLinkSource )
38 class SvLinkSourceTimer : public Timer
40 SvLinkSource * pOwner;
41 virtual void Timeout();
42 public:
43 SvLinkSourceTimer( SvLinkSource * pOwn );
46 SvLinkSourceTimer::SvLinkSourceTimer( SvLinkSource * pOwn )
47 : pOwner( pOwn )
51 void SvLinkSourceTimer::Timeout()
53 // Secure against beeing destroyed in Handler
54 SvLinkSourceRef aAdv( pOwner );
55 pOwner->SendDataChanged();
58 static void StartTimer( SvLinkSourceTimer ** ppTimer, SvLinkSource * pOwner,
59 sal_uIntPtr nTimeout )
61 if( !*ppTimer )
63 *ppTimer = new SvLinkSourceTimer( pOwner );
64 (*ppTimer)->SetTimeout( nTimeout );
65 (*ppTimer)->Start();
70 struct SvLinkSource_Entry_Impl
72 SvBaseLinkRef xSink;
73 OUString aDataMimeType;
74 sal_uInt16 nAdviseModes;
75 sal_Bool bIsDataSink;
77 SvLinkSource_Entry_Impl( SvBaseLink* pLink, const OUString& rMimeType,
78 sal_uInt16 nAdvMode )
79 : xSink( pLink ), aDataMimeType( rMimeType ),
80 nAdviseModes( nAdvMode ), bIsDataSink( sal_True )
83 SvLinkSource_Entry_Impl( SvBaseLink* pLink )
84 : xSink( pLink ), nAdviseModes( 0 ), bIsDataSink( sal_False )
87 ~SvLinkSource_Entry_Impl();
90 SvLinkSource_Entry_Impl::~SvLinkSource_Entry_Impl()
94 class SvLinkSource_Array_Impl : public std::vector<SvLinkSource_Entry_Impl*>
96 public:
97 void DeleteAndDestroy(SvLinkSource_Entry_Impl* p)
99 iterator it = std::find(begin(), end(), p);
100 if (it != end())
102 erase(it);
103 delete p;
107 ~SvLinkSource_Array_Impl()
109 for(const_iterator it = begin(); it != end(); ++it)
110 delete *it;
114 class SvLinkSource_EntryIter_Impl
116 SvLinkSource_Array_Impl aArr;
117 const SvLinkSource_Array_Impl& rOrigArr;
118 sal_uInt16 nPos;
119 public:
120 SvLinkSource_EntryIter_Impl( const SvLinkSource_Array_Impl& rArr );
121 ~SvLinkSource_EntryIter_Impl();
122 SvLinkSource_Entry_Impl* Curr()
123 { return nPos < aArr.size() ? aArr[ nPos ] : 0; }
124 SvLinkSource_Entry_Impl* Next();
125 sal_Bool IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry );
128 SvLinkSource_EntryIter_Impl::SvLinkSource_EntryIter_Impl(
129 const SvLinkSource_Array_Impl& rArr )
130 : aArr( rArr ), rOrigArr( rArr ), nPos( 0 )
133 SvLinkSource_EntryIter_Impl::~SvLinkSource_EntryIter_Impl()
135 aArr.clear();
138 sal_Bool SvLinkSource_EntryIter_Impl::IsValidCurrValue( SvLinkSource_Entry_Impl* pEntry )
140 return ( nPos < aArr.size() && aArr[nPos] == pEntry
141 && std::find( rOrigArr.begin(), rOrigArr.end(), pEntry ) != rOrigArr.end() );
144 SvLinkSource_Entry_Impl* SvLinkSource_EntryIter_Impl::Next()
146 SvLinkSource_Entry_Impl* pRet = 0;
147 if( nPos + 1 < (sal_uInt16)aArr.size() )
149 ++nPos;
150 if( rOrigArr.size() == aArr.size() &&
151 rOrigArr[ nPos ] == aArr[ nPos ] )
152 pRet = aArr[ nPos ];
153 else
155 // then we must search the current (or the next) in the orig
156 do {
157 pRet = aArr[ nPos ];
158 if( std::find(rOrigArr.begin(), rOrigArr.end(), pRet ) != rOrigArr.end() )
159 break;
160 pRet = 0;
161 ++nPos;
162 } while( nPos < aArr.size() );
164 if( nPos >= aArr.size() )
165 pRet = 0;
168 return pRet;
171 struct SvLinkSource_Impl
173 SvLinkSource_Array_Impl aArr;
174 OUString aDataMimeType;
175 SvLinkSourceTimer * pTimer;
176 sal_uIntPtr nTimeout;
177 css::uno::Reference<css::io::XInputStream>
178 m_xInputStreamToLoadFrom;
179 sal_Bool m_bIsReadOnly;
181 SvLinkSource_Impl() : pTimer( 0 ), nTimeout( 3000 ) {}
182 ~SvLinkSource_Impl();
184 void Closed();
187 SvLinkSource_Impl::~SvLinkSource_Impl()
189 delete pTimer;
192 SvLinkSource::SvLinkSource()
193 : pImpl( new SvLinkSource_Impl )
197 SvLinkSource::~SvLinkSource()
199 delete pImpl;
203 SvLinkSource::StreamToLoadFrom SvLinkSource::getStreamToLoadFrom()
205 return StreamToLoadFrom(
206 pImpl->m_xInputStreamToLoadFrom,
207 pImpl->m_bIsReadOnly);
210 void SvLinkSource::setStreamToLoadFrom(const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xInputStream,sal_Bool bIsReadOnly )
212 pImpl->m_xInputStreamToLoadFrom = xInputStream;
213 pImpl->m_bIsReadOnly = bIsReadOnly;
216 // #i88291#
217 void SvLinkSource::clearStreamToLoadFrom()
219 pImpl->m_xInputStreamToLoadFrom.clear();
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 sal_uIntPtr SvLinkSource::GetUpdateTimeout() const
232 return pImpl->nTimeout;
235 void SvLinkSource::SetUpdateTimeout( sal_uIntPtr 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_Impl* p = aIter.Curr(); p; p = aIter.Next() )
247 if( p->bIsDataSink )
249 OUString sDataMimeType( pImpl->aDataMimeType );
250 if( sDataMimeType.isEmpty() )
251 sDataMimeType = p->aDataMimeType;
253 Any aVal;
254 if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
255 GetData( aVal, sDataMimeType, sal_True ) )
257 p->xSink->DataChanged( sDataMimeType, aVal );
259 if ( !aIter.IsValidCurrValue( p ) )
260 continue;
262 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
264 pImpl->aArr.DeleteAndDestroy( p );
270 if( pImpl->pTimer )
272 delete pImpl->pTimer;
273 pImpl->pTimer = NULL;
275 pImpl->aDataMimeType = "";
278 void SvLinkSource::NotifyDataChanged()
280 if( pImpl->nTimeout )
281 StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
282 else
284 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
285 for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
286 if( p->bIsDataSink )
288 Any aVal;
289 if( ( p->nAdviseModes & ADVISEMODE_NODATA ) ||
290 GetData( aVal, p->aDataMimeType, sal_True ) )
292 p->xSink->DataChanged( p->aDataMimeType, aVal );
294 if ( !aIter.IsValidCurrValue( p ) )
295 continue;
297 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
299 pImpl->aArr.DeleteAndDestroy( p );
304 if( pImpl->pTimer )
306 delete pImpl->pTimer;
307 pImpl->pTimer = NULL;
312 // notify the sink, the mime type is not
313 // a selection criterion
314 void SvLinkSource::DataChanged( const OUString & rMimeType,
315 const ::com::sun::star::uno::Any & rVal )
317 if( pImpl->nTimeout && !rVal.hasValue() )
318 { // only when no data was included
319 // fire all data to the sink, independent of the requested format
320 pImpl->aDataMimeType = rMimeType;
321 StartTimer( &pImpl->pTimer, this, pImpl->nTimeout ); // New timeout
323 else
325 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
326 for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
328 if( p->bIsDataSink )
330 p->xSink->DataChanged( rMimeType, rVal );
332 if ( !aIter.IsValidCurrValue( p ) )
333 continue;
335 if( p->nAdviseModes & ADVISEMODE_ONLYONCE )
337 pImpl->aArr.DeleteAndDestroy( p );
342 if( pImpl->pTimer )
344 delete pImpl->pTimer;
345 pImpl->pTimer = NULL;
351 // only one link is correct
352 void SvLinkSource::AddDataAdvise( SvBaseLink * pLink, const OUString& rMimeType,
353 sal_uInt16 nAdviseModes )
355 SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl(
356 pLink, rMimeType, nAdviseModes );
357 pImpl->aArr.push_back( pNew );
360 void SvLinkSource::RemoveAllDataAdvise( SvBaseLink * pLink )
362 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
363 for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
364 if( p->bIsDataSink && &p->xSink == pLink )
366 pImpl->aArr.DeleteAndDestroy( p );
370 // only one link is correct
371 void SvLinkSource::AddConnectAdvise( SvBaseLink * pLink )
373 SvLinkSource_Entry_Impl* pNew = new SvLinkSource_Entry_Impl( pLink );
374 pImpl->aArr.push_back( pNew );
377 void SvLinkSource::RemoveConnectAdvise( SvBaseLink * pLink )
379 SvLinkSource_EntryIter_Impl aIter( pImpl->aArr );
380 for( SvLinkSource_Entry_Impl* p = aIter.Curr(); p; p = aIter.Next() )
381 if( !p->bIsDataSink && &p->xSink == pLink )
383 pImpl->aArr.DeleteAndDestroy( p );
387 sal_Bool SvLinkSource::HasDataLinks( const SvBaseLink* pLink ) const
389 sal_Bool bRet = sal_False;
390 const SvLinkSource_Entry_Impl* p;
391 for( sal_uInt16 n = 0, nEnd = pImpl->aArr.size(); n < nEnd; ++n )
392 if( ( p = pImpl->aArr[ n ] )->bIsDataSink &&
393 ( !pLink || &p->xSink == pLink ) )
395 bRet = sal_True;
396 break;
398 return bRet;
401 // sal_True => waitinmg for data
402 sal_Bool SvLinkSource::IsPending() const
404 return sal_False;
407 // sal_True => data complete loaded
408 sal_Bool SvLinkSource::IsDataComplete() const
410 return sal_True;
413 sal_Bool SvLinkSource::Connect( SvBaseLink* )
415 return sal_True;
418 sal_Bool SvLinkSource::GetData( ::com::sun::star::uno::Any &, const OUString &, sal_Bool )
420 return sal_False;
423 void SvLinkSource::Edit( Window *, SvBaseLink *, const Link& )
429 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */