xref: /AOO41X/main/sc/source/core/tool/chartlis.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
1*b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b3f79822SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b3f79822SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b3f79822SAndrew Rist  * distributed with this work for additional information
6*b3f79822SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b3f79822SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b3f79822SAndrew Rist  * "License"); you may not use this file except in compliance
9*b3f79822SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*b3f79822SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*b3f79822SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b3f79822SAndrew Rist  * software distributed under the License is distributed on an
15*b3f79822SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b3f79822SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b3f79822SAndrew Rist  * specific language governing permissions and limitations
18*b3f79822SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*b3f79822SAndrew Rist  *************************************************************/
21*b3f79822SAndrew Rist 
22*b3f79822SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <vcl/svapp.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include "chartlis.hxx"
32cdf0e10cSrcweir #include "brdcst.hxx"
33cdf0e10cSrcweir #include "document.hxx"
34cdf0e10cSrcweir #include "reftokenhelper.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace com::sun::star;
37cdf0e10cSrcweir using ::std::vector;
38cdf0e10cSrcweir using ::std::list;
39cdf0e10cSrcweir using ::std::hash_set;
40cdf0e10cSrcweir using ::std::auto_ptr;
41cdf0e10cSrcweir using ::std::unary_function;
42cdf0e10cSrcweir using ::std::for_each;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir //2do: DocOption TimeOut?
45cdf0e10cSrcweir //#define SC_CHARTTIMEOUT 1000		// eine Sekunde keine Aenderung/KeyEvent
46cdf0e10cSrcweir 
47cdf0e10cSrcweir // Update chart listeners quickly, to get a similar behavior to loaded charts
48cdf0e10cSrcweir // which register UNO listeners.
49cdf0e10cSrcweir #define SC_CHARTTIMEOUT 10
50cdf0e10cSrcweir 
51cdf0e10cSrcweir 
52cdf0e10cSrcweir // ====================================================================
53cdf0e10cSrcweir 
54cdf0e10cSrcweir class ScChartUnoData
55cdf0e10cSrcweir {
56cdf0e10cSrcweir 	uno::Reference< chart::XChartDataChangeEventListener >	xListener;
57cdf0e10cSrcweir 	uno::Reference< chart::XChartData >						xSource;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir public:
ScChartUnoData(const uno::Reference<chart::XChartDataChangeEventListener> & rL,const uno::Reference<chart::XChartData> & rS)60cdf0e10cSrcweir 			ScChartUnoData( const uno::Reference< chart::XChartDataChangeEventListener >& rL,
61cdf0e10cSrcweir 							const uno::Reference< chart::XChartData >& rS ) :
62cdf0e10cSrcweir 					xListener( rL ), xSource( rS ) {}
~ScChartUnoData()63cdf0e10cSrcweir 			~ScChartUnoData() {}
64cdf0e10cSrcweir 
GetListener() const65cdf0e10cSrcweir 	const uno::Reference< chart::XChartDataChangeEventListener >& GetListener() const	{ return xListener; }
GetSource() const66cdf0e10cSrcweir 	const uno::Reference< chart::XChartData >& GetSource() const						{ return xSource; }
67cdf0e10cSrcweir };
68cdf0e10cSrcweir 
69cdf0e10cSrcweir 
70cdf0e10cSrcweir // === ScChartListener ================================================
71cdf0e10cSrcweir 
ExternalRefListener(ScChartListener & rParent,ScDocument * pDoc)72cdf0e10cSrcweir ScChartListener::ExternalRefListener::ExternalRefListener(ScChartListener& rParent, ScDocument* pDoc) :
73cdf0e10cSrcweir     mrParent(rParent), mpDoc(pDoc)
74cdf0e10cSrcweir {
75cdf0e10cSrcweir }
76cdf0e10cSrcweir 
~ExternalRefListener()77cdf0e10cSrcweir ScChartListener::ExternalRefListener::~ExternalRefListener()
78cdf0e10cSrcweir {
79cdf0e10cSrcweir     if (!mpDoc || mpDoc->IsInDtorClear())
80cdf0e10cSrcweir         // The document is being destroyed.  Do nothing.
81cdf0e10cSrcweir         return;
82cdf0e10cSrcweir 
83cdf0e10cSrcweir     // Make sure to remove all pointers to this object.
84cdf0e10cSrcweir     mpDoc->GetExternalRefManager()->removeLinkListener(this);
85cdf0e10cSrcweir }
86cdf0e10cSrcweir 
notify(sal_uInt16 nFileId,ScExternalRefManager::LinkUpdateType eType)87cdf0e10cSrcweir void ScChartListener::ExternalRefListener::notify(sal_uInt16 nFileId, ScExternalRefManager::LinkUpdateType eType)
88cdf0e10cSrcweir {
89cdf0e10cSrcweir     switch (eType)
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         case ScExternalRefManager::LINK_MODIFIED:
92cdf0e10cSrcweir         {
93cdf0e10cSrcweir             if (maFileIds.count(nFileId))
94cdf0e10cSrcweir                 // We are listening to this external document.  Send an update
95cdf0e10cSrcweir                 // requst to the chart.
96cdf0e10cSrcweir                 mrParent.SetUpdateQueue();
97cdf0e10cSrcweir         }
98cdf0e10cSrcweir         break;
99cdf0e10cSrcweir         case ScExternalRefManager::LINK_BROKEN:
100cdf0e10cSrcweir             removeFileId(nFileId);
101cdf0e10cSrcweir         break;
102cdf0e10cSrcweir     }
103cdf0e10cSrcweir }
104cdf0e10cSrcweir 
addFileId(sal_uInt16 nFileId)105cdf0e10cSrcweir void ScChartListener::ExternalRefListener::addFileId(sal_uInt16 nFileId)
106cdf0e10cSrcweir {
107cdf0e10cSrcweir     maFileIds.insert(nFileId);
108cdf0e10cSrcweir }
109cdf0e10cSrcweir 
removeFileId(sal_uInt16 nFileId)110cdf0e10cSrcweir void ScChartListener::ExternalRefListener::removeFileId(sal_uInt16 nFileId)
111cdf0e10cSrcweir {
112cdf0e10cSrcweir     maFileIds.erase(nFileId);
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
getAllFileIds()115cdf0e10cSrcweir hash_set<sal_uInt16>& ScChartListener::ExternalRefListener::getAllFileIds()
116cdf0e10cSrcweir {
117cdf0e10cSrcweir     return maFileIds;
118cdf0e10cSrcweir }
119cdf0e10cSrcweir 
120cdf0e10cSrcweir // ----------------------------------------------------------------------------
121cdf0e10cSrcweir 
ScChartListener(const String & rName,ScDocument * pDocP,const ScRange & rRange)122cdf0e10cSrcweir ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
123cdf0e10cSrcweir         const ScRange& rRange ) :
124cdf0e10cSrcweir     StrData( rName ),
125cdf0e10cSrcweir     SvtListener(),
126cdf0e10cSrcweir     mpExtRefListener(NULL),
127cdf0e10cSrcweir     mpTokens(new vector<ScSharedTokenRef>),
128cdf0e10cSrcweir     pUnoData( NULL ),
129cdf0e10cSrcweir     pDoc( pDocP ),
130cdf0e10cSrcweir     bUsed( sal_False ),
131cdf0e10cSrcweir     bDirty( sal_False ),
132cdf0e10cSrcweir     bSeriesRangesScheduled( sal_False )
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     SetRangeList( rRange );
135cdf0e10cSrcweir }
136cdf0e10cSrcweir 
ScChartListener(const String & rName,ScDocument * pDocP,const ScRangeListRef & rRangeList)137cdf0e10cSrcweir ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP,
138cdf0e10cSrcweir         const ScRangeListRef& rRangeList ) :
139cdf0e10cSrcweir     StrData( rName ),
140cdf0e10cSrcweir     SvtListener(),
141cdf0e10cSrcweir     mpExtRefListener(NULL),
142cdf0e10cSrcweir     mpTokens(new vector<ScSharedTokenRef>),
143cdf0e10cSrcweir     pUnoData( NULL ),
144cdf0e10cSrcweir     pDoc( pDocP ),
145cdf0e10cSrcweir     bUsed( sal_False ),
146cdf0e10cSrcweir     bDirty( sal_False ),
147cdf0e10cSrcweir     bSeriesRangesScheduled( sal_False )
148cdf0e10cSrcweir {
149cdf0e10cSrcweir     ScRefTokenHelper::getTokensFromRangeList(*mpTokens, *rRangeList);
150cdf0e10cSrcweir }
151cdf0e10cSrcweir 
ScChartListener(const String & rName,ScDocument * pDocP,vector<ScSharedTokenRef> * pTokens)152cdf0e10cSrcweir ScChartListener::ScChartListener( const String& rName, ScDocument* pDocP, vector<ScSharedTokenRef>* pTokens ) :
153cdf0e10cSrcweir     StrData( rName ),
154cdf0e10cSrcweir     SvtListener(),
155cdf0e10cSrcweir     mpExtRefListener(NULL),
156cdf0e10cSrcweir     mpTokens(pTokens),
157cdf0e10cSrcweir     pUnoData( NULL ),
158cdf0e10cSrcweir     pDoc( pDocP ),
159cdf0e10cSrcweir     bUsed( sal_False ),
160cdf0e10cSrcweir     bDirty( sal_False ),
161cdf0e10cSrcweir     bSeriesRangesScheduled( sal_False )
162cdf0e10cSrcweir {
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
ScChartListener(const ScChartListener & r)165cdf0e10cSrcweir ScChartListener::ScChartListener( const ScChartListener& r ) :
166cdf0e10cSrcweir     StrData( r ),
167cdf0e10cSrcweir     SvtListener(),
168cdf0e10cSrcweir     mpExtRefListener(NULL),
169cdf0e10cSrcweir     mpTokens(new vector<ScSharedTokenRef>(*r.mpTokens)),
170cdf0e10cSrcweir     pUnoData( NULL ),
171cdf0e10cSrcweir     pDoc( r.pDoc ),
172cdf0e10cSrcweir     bUsed( sal_False ),
173cdf0e10cSrcweir     bDirty( r.bDirty ),
174cdf0e10cSrcweir     bSeriesRangesScheduled( r.bSeriesRangesScheduled )
175cdf0e10cSrcweir {
176cdf0e10cSrcweir     if ( r.pUnoData )
177cdf0e10cSrcweir         pUnoData = new ScChartUnoData( *r.pUnoData );
178cdf0e10cSrcweir 
179cdf0e10cSrcweir     if (r.mpExtRefListener.get())
180cdf0e10cSrcweir     {
181cdf0e10cSrcweir         // Re-register this new listener for the files that the old listener
182cdf0e10cSrcweir         // was listening to.
183cdf0e10cSrcweir 
184cdf0e10cSrcweir         ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
185cdf0e10cSrcweir         const hash_set<sal_uInt16>& rFileIds = r.mpExtRefListener->getAllFileIds();
186cdf0e10cSrcweir         mpExtRefListener.reset(new ExternalRefListener(*this, pDoc));
187cdf0e10cSrcweir         hash_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
188cdf0e10cSrcweir         for (; itr != itrEnd; ++itr)
189cdf0e10cSrcweir         {
190cdf0e10cSrcweir             pRefMgr->addLinkListener(*itr, mpExtRefListener.get());
191cdf0e10cSrcweir             mpExtRefListener->addFileId(*itr);
192cdf0e10cSrcweir         }
193cdf0e10cSrcweir     }
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
~ScChartListener()196cdf0e10cSrcweir ScChartListener::~ScChartListener()
197cdf0e10cSrcweir {
198cdf0e10cSrcweir 	if ( HasBroadcaster() )
199cdf0e10cSrcweir 		EndListeningTo();
200cdf0e10cSrcweir 	delete pUnoData;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir     if (mpExtRefListener.get())
203cdf0e10cSrcweir     {
204cdf0e10cSrcweir         // Stop listening to all external files.
205cdf0e10cSrcweir         ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
206cdf0e10cSrcweir         const hash_set<sal_uInt16>& rFileIds = mpExtRefListener->getAllFileIds();
207cdf0e10cSrcweir         hash_set<sal_uInt16>::const_iterator itr = rFileIds.begin(), itrEnd = rFileIds.end();
208cdf0e10cSrcweir         for (; itr != itrEnd; ++itr)
209cdf0e10cSrcweir             pRefMgr->removeLinkListener(*itr, mpExtRefListener.get());
210cdf0e10cSrcweir     }
211cdf0e10cSrcweir }
212cdf0e10cSrcweir 
Clone() const213cdf0e10cSrcweir ScDataObject* ScChartListener::Clone() const
214cdf0e10cSrcweir {
215cdf0e10cSrcweir 	return new ScChartListener( *this );
216cdf0e10cSrcweir }
217cdf0e10cSrcweir 
SetUno(const uno::Reference<chart::XChartDataChangeEventListener> & rListener,const uno::Reference<chart::XChartData> & rSource)218cdf0e10cSrcweir void ScChartListener::SetUno(
219cdf0e10cSrcweir 		const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
220cdf0e10cSrcweir 		const uno::Reference< chart::XChartData >& rSource )
221cdf0e10cSrcweir {
222cdf0e10cSrcweir //	DBG_ASSERT( rListener.is() && rSource.is(), "Nullpointer bei SetUno" );
223cdf0e10cSrcweir 	delete pUnoData;
224cdf0e10cSrcweir 	pUnoData = new ScChartUnoData( rListener, rSource );
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
GetUnoListener() const227cdf0e10cSrcweir uno::Reference< chart::XChartDataChangeEventListener > ScChartListener::GetUnoListener() const
228cdf0e10cSrcweir {
229cdf0e10cSrcweir 	if ( pUnoData )
230cdf0e10cSrcweir 		return pUnoData->GetListener();
231cdf0e10cSrcweir 	return uno::Reference< chart::XChartDataChangeEventListener >();
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
GetUnoSource() const234cdf0e10cSrcweir uno::Reference< chart::XChartData > ScChartListener::GetUnoSource() const
235cdf0e10cSrcweir {
236cdf0e10cSrcweir 	if ( pUnoData )
237cdf0e10cSrcweir 		return pUnoData->GetSource();
238cdf0e10cSrcweir 	return uno::Reference< chart::XChartData >();
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
Notify(SvtBroadcaster &,const SfxHint & rHint)241cdf0e10cSrcweir void ScChartListener::Notify( SvtBroadcaster&, const SfxHint& rHint )
242cdf0e10cSrcweir {
243cdf0e10cSrcweir     const ScHint* p = dynamic_cast<const ScHint*>(&rHint);
244cdf0e10cSrcweir     if (p && (p->GetId() & (SC_HINT_DATACHANGED | SC_HINT_DYING)))
245cdf0e10cSrcweir         SetUpdateQueue();
246cdf0e10cSrcweir }
247cdf0e10cSrcweir 
Update()248cdf0e10cSrcweir void ScChartListener::Update()
249cdf0e10cSrcweir {
250cdf0e10cSrcweir 	if ( pDoc->IsInInterpreter() )
251cdf0e10cSrcweir 	{	// #73482# If interpreting do nothing and restart timer so we don't
252cdf0e10cSrcweir 		// interfere with interpreter and don't produce an Err522 or similar.
253cdf0e10cSrcweir 		// This may happen if we are rescheduled via Basic function.
254cdf0e10cSrcweir 		pDoc->GetChartListenerCollection()->StartTimer();
255cdf0e10cSrcweir 		return ;
256cdf0e10cSrcweir 	}
257cdf0e10cSrcweir 	if ( pUnoData )
258cdf0e10cSrcweir 	{
259cdf0e10cSrcweir 		bDirty = sal_False;
260cdf0e10cSrcweir 		//!	irgendwann mal erkennen, was sich innerhalb des Charts geaendert hat
261cdf0e10cSrcweir 		chart::ChartDataChangeEvent aEvent( pUnoData->GetSource(),
262cdf0e10cSrcweir 										chart::ChartDataChangeType_ALL,
263cdf0e10cSrcweir 										0, 0, 0, 0 );
264cdf0e10cSrcweir 		pUnoData->GetListener()->chartDataChanged( aEvent );
265cdf0e10cSrcweir 	}
266cdf0e10cSrcweir 	else if ( pDoc->GetAutoCalc() )
267cdf0e10cSrcweir 	{
268cdf0e10cSrcweir 		bDirty = sal_False;
269cdf0e10cSrcweir 		pDoc->UpdateChart( GetString());
270cdf0e10cSrcweir 	}
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
GetRangeList() const273cdf0e10cSrcweir ScRangeListRef ScChartListener::GetRangeList() const
274cdf0e10cSrcweir {
275cdf0e10cSrcweir     ScRangeListRef aRLRef(new ScRangeList);
276cdf0e10cSrcweir     ScRefTokenHelper::getRangeListFromTokens(*aRLRef, *mpTokens);
277cdf0e10cSrcweir     return aRLRef;
278cdf0e10cSrcweir }
279cdf0e10cSrcweir 
SetRangeList(const ScRangeListRef & rNew)280cdf0e10cSrcweir void ScChartListener::SetRangeList( const ScRangeListRef& rNew )
281cdf0e10cSrcweir {
282cdf0e10cSrcweir     vector<ScSharedTokenRef> aTokens;
283cdf0e10cSrcweir     ScRefTokenHelper::getTokensFromRangeList(aTokens, *rNew);
284cdf0e10cSrcweir     mpTokens->swap(aTokens);
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
SetRangeList(const ScRange & rRange)287cdf0e10cSrcweir void ScChartListener::SetRangeList( const ScRange& rRange )
288cdf0e10cSrcweir {
289cdf0e10cSrcweir     ScSharedTokenRef pToken;
290cdf0e10cSrcweir     ScRefTokenHelper::getTokenFromRange(pToken, rRange);
291cdf0e10cSrcweir     mpTokens->push_back(pToken);
292cdf0e10cSrcweir }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir namespace {
295cdf0e10cSrcweir 
296cdf0e10cSrcweir class StartEndListening : public unary_function<ScSharedTokenRef, void>
297cdf0e10cSrcweir {
298cdf0e10cSrcweir public:
StartEndListening(ScDocument * pDoc,ScChartListener & rParent,bool bStart)299cdf0e10cSrcweir     StartEndListening(ScDocument* pDoc, ScChartListener& rParent, bool bStart) :
300cdf0e10cSrcweir         mpDoc(pDoc), mrParent(rParent), mbStart(bStart) {}
301cdf0e10cSrcweir 
operator ()(const ScSharedTokenRef & pToken)302cdf0e10cSrcweir     void operator() (const ScSharedTokenRef& pToken)
303cdf0e10cSrcweir     {
304cdf0e10cSrcweir         if (!ScRefTokenHelper::isRef(pToken))
305cdf0e10cSrcweir             return;
306cdf0e10cSrcweir 
307cdf0e10cSrcweir         bool bExternal = ScRefTokenHelper::isExternalRef(pToken);
308cdf0e10cSrcweir         if (bExternal)
309cdf0e10cSrcweir         {
310cdf0e10cSrcweir             sal_uInt16 nFileId = pToken->GetIndex();
311cdf0e10cSrcweir             ScExternalRefManager* pRefMgr = mpDoc->GetExternalRefManager();
312cdf0e10cSrcweir             ScChartListener::ExternalRefListener* pExtRefListener = mrParent.GetExtRefListener();
313cdf0e10cSrcweir             if (mbStart)
314cdf0e10cSrcweir             {
315cdf0e10cSrcweir                 pRefMgr->addLinkListener(nFileId, pExtRefListener);
316cdf0e10cSrcweir                 pExtRefListener->addFileId(nFileId);
317cdf0e10cSrcweir             }
318cdf0e10cSrcweir             else
319cdf0e10cSrcweir             {
320cdf0e10cSrcweir                 pRefMgr->removeLinkListener(nFileId, pExtRefListener);
321cdf0e10cSrcweir                 pExtRefListener->removeFileId(nFileId);
322cdf0e10cSrcweir             }
323cdf0e10cSrcweir         }
324cdf0e10cSrcweir         else
325cdf0e10cSrcweir         {
326cdf0e10cSrcweir             ScRange aRange;
327cdf0e10cSrcweir             ScRefTokenHelper::getRangeFromToken(aRange, pToken, bExternal);
328cdf0e10cSrcweir             if (mbStart)
329cdf0e10cSrcweir                 startListening(aRange);
330cdf0e10cSrcweir             else
331cdf0e10cSrcweir                 endListening(aRange);
332cdf0e10cSrcweir         }
333cdf0e10cSrcweir     }
334cdf0e10cSrcweir 
335cdf0e10cSrcweir private:
startListening(const ScRange & rRange)336cdf0e10cSrcweir     void startListening(const ScRange& rRange)
337cdf0e10cSrcweir     {
338cdf0e10cSrcweir         if (rRange.aStart == rRange.aEnd)
339cdf0e10cSrcweir             mpDoc->StartListeningCell(rRange.aStart, &mrParent);
340cdf0e10cSrcweir         else
341cdf0e10cSrcweir             mpDoc->StartListeningArea(rRange, &mrParent);
342cdf0e10cSrcweir     }
343cdf0e10cSrcweir 
endListening(const ScRange & rRange)344cdf0e10cSrcweir     void endListening(const ScRange& rRange)
345cdf0e10cSrcweir     {
346cdf0e10cSrcweir         if (rRange.aStart == rRange.aEnd)
347cdf0e10cSrcweir             mpDoc->EndListeningCell(rRange.aStart, &mrParent);
348cdf0e10cSrcweir         else
349cdf0e10cSrcweir             mpDoc->EndListeningArea(rRange, &mrParent);
350cdf0e10cSrcweir     }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir private:
353cdf0e10cSrcweir     ScDocument* mpDoc;
354cdf0e10cSrcweir     ScChartListener& mrParent;
355cdf0e10cSrcweir     bool mbStart;
356cdf0e10cSrcweir };
357cdf0e10cSrcweir 
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
StartListeningTo()360cdf0e10cSrcweir void ScChartListener::StartListeningTo()
361cdf0e10cSrcweir {
362cdf0e10cSrcweir     if (!mpTokens.get() || mpTokens->empty())
363cdf0e10cSrcweir         // no references to listen to.
364cdf0e10cSrcweir         return;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir     for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(pDoc, *this, true));
367cdf0e10cSrcweir }
368cdf0e10cSrcweir 
EndListeningTo()369cdf0e10cSrcweir void ScChartListener::EndListeningTo()
370cdf0e10cSrcweir {
371cdf0e10cSrcweir     if (!mpTokens.get() || mpTokens->empty())
372cdf0e10cSrcweir         // no references to listen to.
373cdf0e10cSrcweir         return;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir     for_each(mpTokens->begin(), mpTokens->end(), StartEndListening(pDoc, *this, false));
376cdf0e10cSrcweir }
377cdf0e10cSrcweir 
378cdf0e10cSrcweir 
ChangeListening(const ScRangeListRef & rRangeListRef,sal_Bool bDirtyP)379cdf0e10cSrcweir void ScChartListener::ChangeListening( const ScRangeListRef& rRangeListRef,
380cdf0e10cSrcweir 			sal_Bool bDirtyP  )
381cdf0e10cSrcweir {
382cdf0e10cSrcweir 	EndListeningTo();
383cdf0e10cSrcweir 	SetRangeList( rRangeListRef );
384cdf0e10cSrcweir 	StartListeningTo();
385cdf0e10cSrcweir 	if ( bDirtyP )
386cdf0e10cSrcweir 		SetDirty( sal_True );
387cdf0e10cSrcweir }
388cdf0e10cSrcweir 
389cdf0e10cSrcweir 
UpdateScheduledSeriesRanges()390cdf0e10cSrcweir void ScChartListener::UpdateScheduledSeriesRanges()
391cdf0e10cSrcweir {
392cdf0e10cSrcweir 	if ( bSeriesRangesScheduled )
393cdf0e10cSrcweir 	{
394cdf0e10cSrcweir 		bSeriesRangesScheduled = sal_False;
395cdf0e10cSrcweir 		UpdateSeriesRanges();
396cdf0e10cSrcweir 	}
397cdf0e10cSrcweir }
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 
UpdateChartIntersecting(const ScRange & rRange)400cdf0e10cSrcweir void ScChartListener::UpdateChartIntersecting( const ScRange& rRange )
401cdf0e10cSrcweir {
402cdf0e10cSrcweir     ScSharedTokenRef pToken;
403cdf0e10cSrcweir     ScRefTokenHelper::getTokenFromRange(pToken, rRange);
404cdf0e10cSrcweir 
405cdf0e10cSrcweir     if (ScRefTokenHelper::intersects(*mpTokens, pToken))
406cdf0e10cSrcweir     {
407cdf0e10cSrcweir         // force update (chart has to be loaded), don't use ScChartListener::Update
408cdf0e10cSrcweir         pDoc->UpdateChart( GetString());
409cdf0e10cSrcweir     }
410cdf0e10cSrcweir }
411cdf0e10cSrcweir 
412cdf0e10cSrcweir 
UpdateSeriesRanges()413cdf0e10cSrcweir void ScChartListener::UpdateSeriesRanges()
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     ScRangeListRef pRangeList(new ScRangeList);
416cdf0e10cSrcweir     ScRefTokenHelper::getRangeListFromTokens(*pRangeList, *mpTokens);
417cdf0e10cSrcweir     pDoc->SetChartRangeList(GetString(), pRangeList);
418cdf0e10cSrcweir }
419cdf0e10cSrcweir 
GetExtRefListener()420cdf0e10cSrcweir ScChartListener::ExternalRefListener* ScChartListener::GetExtRefListener()
421cdf0e10cSrcweir {
422cdf0e10cSrcweir     if (!mpExtRefListener.get())
423cdf0e10cSrcweir         mpExtRefListener.reset(new ExternalRefListener(*this, pDoc));
424cdf0e10cSrcweir 
425cdf0e10cSrcweir     return mpExtRefListener.get();
426cdf0e10cSrcweir }
427cdf0e10cSrcweir 
SetUpdateQueue()428cdf0e10cSrcweir void ScChartListener::SetUpdateQueue()
429cdf0e10cSrcweir {
430cdf0e10cSrcweir     bDirty = true;
431cdf0e10cSrcweir     pDoc->GetChartListenerCollection()->StartTimer();
432cdf0e10cSrcweir }
433cdf0e10cSrcweir 
operator ==(const ScChartListener & r)434cdf0e10cSrcweir sal_Bool ScChartListener::operator==( const ScChartListener& r )
435cdf0e10cSrcweir {
436cdf0e10cSrcweir     bool b1 = (mpTokens.get() && !mpTokens->empty());
437cdf0e10cSrcweir     bool b2 = (r.mpTokens.get() && !r.mpTokens->empty());
438cdf0e10cSrcweir 
439cdf0e10cSrcweir     if (pDoc != r.pDoc || bUsed != r.bUsed || bDirty != r.bDirty ||
440cdf0e10cSrcweir         bSeriesRangesScheduled != r.bSeriesRangesScheduled ||
441cdf0e10cSrcweir         GetString() != r.GetString() || b1 != b2)
442cdf0e10cSrcweir         return false;
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     if (!b1 && !b2)
445cdf0e10cSrcweir         // both token list instances are empty.
446cdf0e10cSrcweir         return true;
447cdf0e10cSrcweir 
448cdf0e10cSrcweir     return *mpTokens == *r.mpTokens;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
451cdf0e10cSrcweir // ============================================================================
452cdf0e10cSrcweir 
ScChartHiddenRangeListener()453cdf0e10cSrcweir ScChartHiddenRangeListener::ScChartHiddenRangeListener()
454cdf0e10cSrcweir {
455cdf0e10cSrcweir }
456cdf0e10cSrcweir 
~ScChartHiddenRangeListener()457cdf0e10cSrcweir ScChartHiddenRangeListener::~ScChartHiddenRangeListener()
458cdf0e10cSrcweir {
459cdf0e10cSrcweir     // empty d'tor
460cdf0e10cSrcweir }
461cdf0e10cSrcweir 
462cdf0e10cSrcweir // === ScChartListenerCollection ======================================
463cdf0e10cSrcweir 
RangeListenerItem(const ScRange & rRange,ScChartHiddenRangeListener * p)464cdf0e10cSrcweir ScChartListenerCollection::RangeListenerItem::RangeListenerItem(const ScRange& rRange, ScChartHiddenRangeListener* p) :
465cdf0e10cSrcweir     maRange(rRange), mpListener(p)
466cdf0e10cSrcweir {
467cdf0e10cSrcweir }
468cdf0e10cSrcweir 
ScChartListenerCollection(ScDocument * pDocP)469cdf0e10cSrcweir ScChartListenerCollection::ScChartListenerCollection( ScDocument* pDocP ) :
470cdf0e10cSrcweir 	ScStrCollection( 4, 4, sal_False ),
471cdf0e10cSrcweir 	pDoc( pDocP )
472cdf0e10cSrcweir {
473cdf0e10cSrcweir 	aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
474cdf0e10cSrcweir }
475cdf0e10cSrcweir 
ScChartListenerCollection(const ScChartListenerCollection & rColl)476cdf0e10cSrcweir ScChartListenerCollection::ScChartListenerCollection(
477cdf0e10cSrcweir 		const ScChartListenerCollection& rColl ) :
478cdf0e10cSrcweir 	ScStrCollection( rColl ),
479cdf0e10cSrcweir 	pDoc( rColl.pDoc )
480cdf0e10cSrcweir {
481cdf0e10cSrcweir 	aTimer.SetTimeoutHdl( LINK( this, ScChartListenerCollection, TimerHdl ) );
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
~ScChartListenerCollection()484cdf0e10cSrcweir ScChartListenerCollection::~ScChartListenerCollection()
485cdf0e10cSrcweir {
486cdf0e10cSrcweir 	//	#96783# remove ChartListener objects before aTimer dtor is called, because
487cdf0e10cSrcweir 	//	ScChartListener::EndListeningTo may cause ScChartListenerCollection::StartTimer
488cdf0e10cSrcweir 	//	to be called if an empty ScNoteCell is deleted
489cdf0e10cSrcweir 
490cdf0e10cSrcweir 	if (GetCount())
491cdf0e10cSrcweir 		FreeAll();
492cdf0e10cSrcweir }
493cdf0e10cSrcweir 
Clone() const494cdf0e10cSrcweir ScDataObject*	ScChartListenerCollection::Clone() const
495cdf0e10cSrcweir {
496cdf0e10cSrcweir 	return new ScChartListenerCollection( *this );
497cdf0e10cSrcweir }
498cdf0e10cSrcweir 
StartAllListeners()499cdf0e10cSrcweir void ScChartListenerCollection::StartAllListeners()
500cdf0e10cSrcweir {
501cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
502cdf0e10cSrcweir 	{
503cdf0e10cSrcweir 		((ScChartListener*) pItems[ nIndex ])->StartListeningTo();
504cdf0e10cSrcweir 	}
505cdf0e10cSrcweir }
506cdf0e10cSrcweir 
ChangeListening(const String & rName,const ScRangeListRef & rRangeListRef,sal_Bool bDirty)507cdf0e10cSrcweir void ScChartListenerCollection::ChangeListening( const String& rName,
508cdf0e10cSrcweir 		const ScRangeListRef& rRangeListRef, sal_Bool bDirty )
509cdf0e10cSrcweir {
510cdf0e10cSrcweir 	ScChartListener aCLSearcher( rName, pDoc, rRangeListRef );
511cdf0e10cSrcweir 	ScChartListener* pCL;
512cdf0e10cSrcweir 	sal_uInt16 nIndex;
513cdf0e10cSrcweir 	if ( Search( &aCLSearcher, nIndex ) )
514cdf0e10cSrcweir 	{
515cdf0e10cSrcweir 		pCL = (ScChartListener*) pItems[ nIndex ];
516cdf0e10cSrcweir 		pCL->EndListeningTo();
517cdf0e10cSrcweir 		pCL->SetRangeList( rRangeListRef );
518cdf0e10cSrcweir 	}
519cdf0e10cSrcweir 	else
520cdf0e10cSrcweir 	{
521cdf0e10cSrcweir 		pCL = new ScChartListener( aCLSearcher );
522cdf0e10cSrcweir 		Insert( pCL );
523cdf0e10cSrcweir 	}
524cdf0e10cSrcweir 	pCL->StartListeningTo();
525cdf0e10cSrcweir 	if ( bDirty )
526cdf0e10cSrcweir 		pCL->SetDirty( sal_True );
527cdf0e10cSrcweir }
528cdf0e10cSrcweir 
FreeUnused()529cdf0e10cSrcweir void ScChartListenerCollection::FreeUnused()
530cdf0e10cSrcweir {
531cdf0e10cSrcweir 	// rueckwaerts wg. Pointer-Aufrueckerei im Array
532cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = nCount; nIndex-- >0; )
533cdf0e10cSrcweir 	{
534cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
535cdf0e10cSrcweir 		//	Uno-Charts nicht rauskicken
536cdf0e10cSrcweir 		//	(werden per FreeUno von aussen geloescht)
537cdf0e10cSrcweir 		if ( !pCL->IsUno() )
538cdf0e10cSrcweir 		{
539cdf0e10cSrcweir 			if ( pCL->IsUsed() )
540cdf0e10cSrcweir 				pCL->SetUsed( sal_False );
541cdf0e10cSrcweir 			else
542cdf0e10cSrcweir 				Free( pCL );
543cdf0e10cSrcweir 		}
544cdf0e10cSrcweir 	}
545cdf0e10cSrcweir }
546cdf0e10cSrcweir 
FreeUno(const uno::Reference<chart::XChartDataChangeEventListener> & rListener,const uno::Reference<chart::XChartData> & rSource)547cdf0e10cSrcweir void ScChartListenerCollection::FreeUno( const uno::Reference< chart::XChartDataChangeEventListener >& rListener,
548cdf0e10cSrcweir 										 const uno::Reference< chart::XChartData >& rSource )
549cdf0e10cSrcweir {
550cdf0e10cSrcweir 	// rueckwaerts wg. Pointer-Aufrueckerei im Array
551cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = nCount; nIndex-- >0; )
552cdf0e10cSrcweir 	{
553cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
554cdf0e10cSrcweir 		if ( pCL->IsUno() &&
555cdf0e10cSrcweir 			 pCL->GetUnoListener() == rListener &&
556cdf0e10cSrcweir 			 pCL->GetUnoSource() == rSource )
557cdf0e10cSrcweir 		{
558cdf0e10cSrcweir 			Free( pCL );
559cdf0e10cSrcweir 		}
560cdf0e10cSrcweir 		//!	sollte nur einmal vorkommen?
561cdf0e10cSrcweir 	}
562cdf0e10cSrcweir }
563cdf0e10cSrcweir 
StartTimer()564cdf0e10cSrcweir void ScChartListenerCollection::StartTimer()
565cdf0e10cSrcweir {
566cdf0e10cSrcweir 	aTimer.SetTimeout( SC_CHARTTIMEOUT );
567cdf0e10cSrcweir 	aTimer.Start();
568cdf0e10cSrcweir }
569cdf0e10cSrcweir 
IMPL_LINK(ScChartListenerCollection,TimerHdl,Timer *,EMPTYARG)570cdf0e10cSrcweir IMPL_LINK( ScChartListenerCollection, TimerHdl, Timer*, EMPTYARG )
571cdf0e10cSrcweir {
572cdf0e10cSrcweir 	if ( Application::AnyInput( INPUT_KEYBOARD ) )
573cdf0e10cSrcweir 	{
574cdf0e10cSrcweir 		aTimer.Start();
575cdf0e10cSrcweir 		return 0;
576cdf0e10cSrcweir 	}
577cdf0e10cSrcweir 	UpdateDirtyCharts();
578cdf0e10cSrcweir 	return 0;
579cdf0e10cSrcweir }
580cdf0e10cSrcweir 
UpdateDirtyCharts()581cdf0e10cSrcweir void ScChartListenerCollection::UpdateDirtyCharts()
582cdf0e10cSrcweir {
583cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
584cdf0e10cSrcweir 	{
585cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
586cdf0e10cSrcweir 		if ( pCL->IsDirty() )
587cdf0e10cSrcweir 			pCL->Update();
588cdf0e10cSrcweir 		if ( aTimer.IsActive() && !pDoc->IsImportingXML())
589cdf0e10cSrcweir 			break;						// da kam einer dazwischen
590cdf0e10cSrcweir 	}
591cdf0e10cSrcweir }
592cdf0e10cSrcweir 
593cdf0e10cSrcweir 
SetDirty()594cdf0e10cSrcweir void ScChartListenerCollection::SetDirty()
595cdf0e10cSrcweir {
596cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
597cdf0e10cSrcweir 	{
598cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
599cdf0e10cSrcweir 		pCL->SetDirty( sal_True );
600cdf0e10cSrcweir 	}
601cdf0e10cSrcweir 	StartTimer();
602cdf0e10cSrcweir }
603cdf0e10cSrcweir 
604cdf0e10cSrcweir 
SetDiffDirty(const ScChartListenerCollection & rCmp,sal_Bool bSetChartRangeLists)605cdf0e10cSrcweir void ScChartListenerCollection::SetDiffDirty(
606cdf0e10cSrcweir 			const ScChartListenerCollection& rCmp, sal_Bool bSetChartRangeLists )
607cdf0e10cSrcweir {
608cdf0e10cSrcweir 	sal_Bool bDirty = sal_False;
609cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
610cdf0e10cSrcweir 	{
611cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
612cdf0e10cSrcweir 		sal_uInt16 nFound;
613cdf0e10cSrcweir 		sal_Bool bFound = rCmp.Search( pCL, nFound );
614cdf0e10cSrcweir 		if ( !bFound ||	(*pCL != *((const ScChartListener*) rCmp.pItems[ nFound ])) )
615cdf0e10cSrcweir 		{
616cdf0e10cSrcweir 			if ( bSetChartRangeLists )
617cdf0e10cSrcweir 			{
618cdf0e10cSrcweir 				if ( bFound )
619cdf0e10cSrcweir 				{
620cdf0e10cSrcweir 					const ScRangeListRef& rList1 = pCL->GetRangeList();
621cdf0e10cSrcweir 					const ScRangeListRef& rList2 =
622cdf0e10cSrcweir 						((const ScChartListener*) rCmp.pItems[ nFound ])->GetRangeList();
623cdf0e10cSrcweir 					sal_Bool b1 = rList1.Is();
624cdf0e10cSrcweir 					sal_Bool b2 = rList2.Is();
625cdf0e10cSrcweir 					if ( b1 != b2 || (b1 && b2 && (*rList1 != *rList2)) )
626cdf0e10cSrcweir 						pDoc->SetChartRangeList( pCL->GetString(), rList1 );
627cdf0e10cSrcweir 				}
628cdf0e10cSrcweir 				else
629cdf0e10cSrcweir 					pDoc->SetChartRangeList( pCL->GetString(), pCL->GetRangeList() );
630cdf0e10cSrcweir 			}
631cdf0e10cSrcweir 			bDirty = sal_True;
632cdf0e10cSrcweir 			pCL->SetDirty( sal_True );
633cdf0e10cSrcweir 		}
634cdf0e10cSrcweir 	}
635cdf0e10cSrcweir 	if ( bDirty )
636cdf0e10cSrcweir 		StartTimer();
637cdf0e10cSrcweir }
638cdf0e10cSrcweir 
639cdf0e10cSrcweir 
SetRangeDirty(const ScRange & rRange)640cdf0e10cSrcweir void ScChartListenerCollection::SetRangeDirty( const ScRange& rRange )
641cdf0e10cSrcweir {
642cdf0e10cSrcweir 	sal_Bool bDirty = sal_False;
643cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
644cdf0e10cSrcweir 	{
645cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
646cdf0e10cSrcweir 		const ScRangeListRef& rList = pCL->GetRangeList();
647cdf0e10cSrcweir 		if ( rList.Is() && rList->Intersects( rRange ) )
648cdf0e10cSrcweir 		{
649cdf0e10cSrcweir 			bDirty = sal_True;
650cdf0e10cSrcweir 			pCL->SetDirty( sal_True );
651cdf0e10cSrcweir 		}
652cdf0e10cSrcweir 	}
653cdf0e10cSrcweir 	if ( bDirty )
654cdf0e10cSrcweir 		StartTimer();
655cdf0e10cSrcweir 
656cdf0e10cSrcweir     // New hidden range listener implementation
657cdf0e10cSrcweir     for (list<RangeListenerItem>::iterator itr = maHiddenListeners.begin(), itrEnd = maHiddenListeners.end();
658cdf0e10cSrcweir           itr != itrEnd; ++itr)
659cdf0e10cSrcweir     {
660cdf0e10cSrcweir         if (itr->maRange.Intersects(rRange))
661cdf0e10cSrcweir             itr->mpListener->notify();
662cdf0e10cSrcweir     }
663cdf0e10cSrcweir }
664cdf0e10cSrcweir 
665cdf0e10cSrcweir 
UpdateScheduledSeriesRanges()666cdf0e10cSrcweir void ScChartListenerCollection::UpdateScheduledSeriesRanges()
667cdf0e10cSrcweir {
668cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
669cdf0e10cSrcweir 	{
670cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
671cdf0e10cSrcweir 		pCL->UpdateScheduledSeriesRanges();
672cdf0e10cSrcweir 	}
673cdf0e10cSrcweir }
674cdf0e10cSrcweir 
675cdf0e10cSrcweir 
UpdateChartsContainingTab(SCTAB nTab)676cdf0e10cSrcweir void ScChartListenerCollection::UpdateChartsContainingTab( SCTAB nTab )
677cdf0e10cSrcweir {
678cdf0e10cSrcweir 	ScRange aRange( 0, 0, nTab, MAXCOL, MAXROW, nTab );
679cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
680cdf0e10cSrcweir 	{
681cdf0e10cSrcweir 		ScChartListener* pCL = (ScChartListener*) pItems[ nIndex ];
682cdf0e10cSrcweir 		pCL->UpdateChartIntersecting( aRange );
683cdf0e10cSrcweir 	}
684cdf0e10cSrcweir }
685cdf0e10cSrcweir 
686cdf0e10cSrcweir 
operator ==(const ScChartListenerCollection & r)687cdf0e10cSrcweir sal_Bool ScChartListenerCollection::operator==( const ScChartListenerCollection& r )
688cdf0e10cSrcweir {
689cdf0e10cSrcweir 	// hier nicht ScStrCollection::operator==() verwenden, der umstaendlich via
690cdf0e10cSrcweir 	// IsEqual und Compare laeuft, stattdessen ScChartListener::operator==()
691cdf0e10cSrcweir 	if ( pDoc != r.pDoc || nCount != r.nCount )
692cdf0e10cSrcweir 		return sal_False;
693cdf0e10cSrcweir 	for ( sal_uInt16 nIndex = 0; nIndex < nCount; nIndex++ )
694cdf0e10cSrcweir 	{
695cdf0e10cSrcweir 		if ( *((ScChartListener*) pItems[ nIndex ]) !=
696cdf0e10cSrcweir 				*((ScChartListener*) r.pItems[ nIndex ]) )
697cdf0e10cSrcweir 			return sal_False;
698cdf0e10cSrcweir 	}
699cdf0e10cSrcweir 	return sal_True;
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
StartListeningHiddenRange(const ScRange & rRange,ScChartHiddenRangeListener * pListener)702cdf0e10cSrcweir void ScChartListenerCollection::StartListeningHiddenRange( const ScRange& rRange, ScChartHiddenRangeListener* pListener )
703cdf0e10cSrcweir {
704cdf0e10cSrcweir     RangeListenerItem aItem(rRange, pListener);
705cdf0e10cSrcweir     maHiddenListeners.push_back(aItem);
706cdf0e10cSrcweir }
707cdf0e10cSrcweir 
708cdf0e10cSrcweir namespace {
709cdf0e10cSrcweir 
710cdf0e10cSrcweir struct MatchListener : public ::std::unary_function<
711cdf0e10cSrcweir         ScChartListenerCollection::RangeListenerItem, bool>
712cdf0e10cSrcweir {
MatchListener__anon273a2fe30211::MatchListener713cdf0e10cSrcweir     MatchListener(const ScChartHiddenRangeListener* pMatch) :
714cdf0e10cSrcweir         mpMatch(pMatch)
715cdf0e10cSrcweir     {
716cdf0e10cSrcweir     }
717cdf0e10cSrcweir 
operator ()__anon273a2fe30211::MatchListener718cdf0e10cSrcweir     bool operator() (const ScChartListenerCollection::RangeListenerItem& rItem) const
719cdf0e10cSrcweir     {
720cdf0e10cSrcweir         return mpMatch == rItem.mpListener;
721cdf0e10cSrcweir     }
722cdf0e10cSrcweir 
723cdf0e10cSrcweir private:
724cdf0e10cSrcweir     const ScChartHiddenRangeListener* mpMatch;
725cdf0e10cSrcweir };
726cdf0e10cSrcweir 
727cdf0e10cSrcweir }
EndListeningHiddenRange(ScChartHiddenRangeListener * pListener)728cdf0e10cSrcweir void ScChartListenerCollection::EndListeningHiddenRange( ScChartHiddenRangeListener* pListener )
729cdf0e10cSrcweir {
730cdf0e10cSrcweir     maHiddenListeners.remove_if(MatchListener(pListener));
731cdf0e10cSrcweir }
732cdf0e10cSrcweir 
733