|
1 /* |
|
2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <MCLFOperationObserver.h> |
|
21 #include <MCLFSortingStyle.h> |
|
22 #include <MCLFItem.h> |
|
23 #include <MCLFChangedItemObserver.h> |
|
24 #include "CCLFEngineImpl.h" |
|
25 #include "CCLFDbItemProvider.h" |
|
26 #include "CCLFItemImpl.h" |
|
27 #include "CCLFDefaultOperation.h" |
|
28 #include "CCLFItemListModelImpl.h" |
|
29 #include "CCLFEventHandler.h" |
|
30 #include "CCLFDbItemContainer.h" |
|
31 #include "MGDebugPrint.h" |
|
32 #include "CCLFQueryAdapter.h" |
|
33 |
|
34 // CONSTANTS |
|
35 const TInt KCLFObserverArrayGranularity( 2 ); |
|
36 const TInt KCLFChangedItemIdArrayGranularity( 10 ); |
|
37 |
|
38 // ----------------------------------------------------------------------------- |
|
39 // CleanupTempModel |
|
40 // ----------------------------------------------------------------------------- |
|
41 // |
|
42 void CCLFEngineImpl::CleanupTempModel( TAny* aObj ) |
|
43 { |
|
44 static_cast< CCLFEngineImpl::CCLFTempModel* >( aObj )->ResetModelArray(); |
|
45 } |
|
46 |
|
47 // ============================ MEMBER FUNCTIONS =============================== |
|
48 |
|
49 // ----------------------------------------------------------------------------- |
|
50 // CCLFEngineImpl::CCLFEngineImpl |
|
51 // ----------------------------------------------------------------------------- |
|
52 // |
|
53 CCLFEngineImpl::CCLFEngineImpl() |
|
54 : iCLFServerProxy( NULL ), |
|
55 iMdESession( NULL ), |
|
56 iError( KErrNone ), |
|
57 iUpdateStartEventHandler( NULL ), |
|
58 iUpdateEndEventHandler( NULL ), |
|
59 iChangedItemObserverArray( KCLFObserverArrayGranularity ), |
|
60 iProcessObserverArray( KCLFObserverArrayGranularity ), |
|
61 iDbItemContainer( NULL ), |
|
62 iItemProvider( NULL ), |
|
63 iQueryAdapter( NULL ) |
|
64 { |
|
65 } |
|
66 |
|
67 // ----------------------------------------------------------------------------- |
|
68 // CCLFEngineImpl::ConstructL |
|
69 // ----------------------------------------------------------------------------- |
|
70 // |
|
71 void CCLFEngineImpl::ConstructL() |
|
72 { |
|
73 iMdESession = CMdESession::NewL( *this ); |
|
74 if( !iActiveSchedulerWait.IsStarted() ) |
|
75 { |
|
76 iActiveSchedulerWait.Start(); |
|
77 } |
|
78 User::LeaveIfError( iError ); |
|
79 iCLFServerProxy = CCLFServerProxy::NewL( *iMdESession ); |
|
80 iQueryAdapter = CCLFQueryAdapter::NewL( *iMdESession ); |
|
81 iUpdateStartEventHandler = CCLFEventHandler::NewL( *iCLFServerProxy, *this ); |
|
82 iUpdateEndEventHandler = CCLFEventHandler::NewL( *iCLFServerProxy, *this ); |
|
83 iDbItemContainer = CCLFDbItemContainer::NewL(); |
|
84 iItemProvider = CCLFDbItemProvider::NewL( *iDbItemContainer, *iQueryAdapter, iMdESession ); |
|
85 iUpdateEndEventHandler->ObserverUpdateEndEvent(); |
|
86 } |
|
87 |
|
88 // ----------------------------------------------------------------------------- |
|
89 // CCLFEngineImpl::NewLC |
|
90 // ----------------------------------------------------------------------------- |
|
91 // |
|
92 CCLFEngineImpl* CCLFEngineImpl::NewLC() |
|
93 { |
|
94 CCLFEngineImpl* self = new( ELeave ) CCLFEngineImpl; |
|
95 CleanupStack::PushL( self ); |
|
96 self->ConstructL(); |
|
97 return self; |
|
98 } |
|
99 |
|
100 // ----------------------------------------------------------------------------- |
|
101 // CCLFEngineImpl::~CCLFEngineImpl |
|
102 // Destructor |
|
103 // ----------------------------------------------------------------------------- |
|
104 // |
|
105 CCLFEngineImpl::~CCLFEngineImpl() |
|
106 { |
|
107 delete iItemProvider; |
|
108 delete iUpdateStartEventHandler; |
|
109 delete iUpdateEndEventHandler; |
|
110 delete iDbItemContainer; |
|
111 delete iCLFServerProxy; |
|
112 iChangedItemObserverArray.Close(); |
|
113 iProcessObserverArray.Close(); |
|
114 delete iQueryAdapter; |
|
115 delete iMdESession; |
|
116 } |
|
117 |
|
118 // ----------------------------------------------------------------------------- |
|
119 // CCLFEngineImpl::AddChangedItemObserverL |
|
120 // ----------------------------------------------------------------------------- |
|
121 // |
|
122 void CCLFEngineImpl::AddChangedItemObserverL( MCLFChangedItemObserver& aObserver ) |
|
123 { |
|
124 iChangedItemObserverArray.AppendL( &aObserver ); |
|
125 } |
|
126 |
|
127 // ----------------------------------------------------------------------------- |
|
128 // CCLFEngineImpl::RemoveChangedItemObserver |
|
129 // ----------------------------------------------------------------------------- |
|
130 // |
|
131 void CCLFEngineImpl::RemoveChangedItemObserver( MCLFChangedItemObserver& aObserver ) |
|
132 { |
|
133 const TInt index( iChangedItemObserverArray.Find( &aObserver ) ); |
|
134 if ( index >= 0 ) |
|
135 { |
|
136 iChangedItemObserverArray.Remove( index ); |
|
137 } |
|
138 } |
|
139 |
|
140 // ----------------------------------------------------------------------------- |
|
141 // CCLFEngineImpl::AddCLFProcessObserverL |
|
142 // ----------------------------------------------------------------------------- |
|
143 // |
|
144 void CCLFEngineImpl::AddCLFProcessObserverL( MCLFProcessObserver& aObserver ) |
|
145 { |
|
146 iProcessObserverArray.AppendL( &aObserver ); |
|
147 if ( !iUpdateStartEventHandler->IsActive() ) |
|
148 { |
|
149 iUpdateStartEventHandler->ObserverUpdateStartEvent(); |
|
150 } |
|
151 } |
|
152 |
|
153 // ----------------------------------------------------------------------------- |
|
154 // CCLFEngineImpl::RemoveCLFProcessObserver |
|
155 // ----------------------------------------------------------------------------- |
|
156 // |
|
157 void CCLFEngineImpl::RemoveCLFProcessObserver( MCLFProcessObserver& aObserver ) |
|
158 { |
|
159 const TInt index( iProcessObserverArray.Find( &aObserver ) ); |
|
160 if ( index >= 0 ) |
|
161 { |
|
162 iProcessObserverArray.Remove( index ); |
|
163 } |
|
164 |
|
165 StopEventHandling(); |
|
166 } |
|
167 |
|
168 // ----------------------------------------------------------------------------- |
|
169 // CCLFEngineImpl::UpdateItemsL |
|
170 // ----------------------------------------------------------------------------- |
|
171 // |
|
172 void CCLFEngineImpl::UpdateItemsL() |
|
173 { |
|
174 User::LeaveIfError( iCLFServerProxy->UpdateAllItemsL() ); |
|
175 } |
|
176 |
|
177 // ----------------------------------------------------------------------------- |
|
178 // CCLFEngineImpl::UpdateItemsL |
|
179 // ----------------------------------------------------------------------------- |
|
180 // |
|
181 void CCLFEngineImpl::UpdateItemsL( const TArray<TCLFItemId>& aItemIDArray ) |
|
182 { |
|
183 User::LeaveIfError( iCLFServerProxy->UpdateItemsL( aItemIDArray ) ); |
|
184 } |
|
185 |
|
186 // ----------------------------------------------------------------------------- |
|
187 // CCLFEngineImpl::UpdateItemsL |
|
188 // ----------------------------------------------------------------------------- |
|
189 // |
|
190 void CCLFEngineImpl::UpdateItemsL( TInt aSemanticId, const TDesC8& aOpaqueData ) |
|
191 { |
|
192 User::LeaveIfError( iCLFServerProxy->UpdateItemsL( aSemanticId, aOpaqueData ) ); |
|
193 } |
|
194 |
|
195 // --------------------------------------------------------------------------- |
|
196 // CCLFEngineImpl::HandleSessionOpened |
|
197 // --------------------------------------------------------------------------- |
|
198 // |
|
199 void CCLFEngineImpl::HandleSessionOpened( CMdESession& /* aSession */, const TInt aError ) |
|
200 { |
|
201 MG_DEBUG2( HSO, "[CLF]\t CCLFEngineImpl::HandleSessionOpened %d", aError ); |
|
202 iActiveSchedulerWait.AsyncStop(); |
|
203 |
|
204 iError = aError; |
|
205 } |
|
206 |
|
207 // --------------------------------------------------------------------------- |
|
208 // CCLFEngineImpl::HandleSessionError |
|
209 // --------------------------------------------------------------------------- |
|
210 // |
|
211 void CCLFEngineImpl::HandleSessionError( CMdESession& /*aSession*/, const TInt aError ) |
|
212 { |
|
213 MG_DEBUG2( HSE, "[CLF]\t CCLFEngineImpl::HandleSessionError %d", aError ); |
|
214 |
|
215 iError = aError; |
|
216 } |
|
217 |
|
218 // ----------------------------------------------------------------------------- |
|
219 // CCLFEngineImpl::CreateListModelLC |
|
220 // ----------------------------------------------------------------------------- |
|
221 // |
|
222 MCLFItemListModel* CCLFEngineImpl::CreateListModelLC( |
|
223 MCLFOperationObserver& aObserver ) |
|
224 { |
|
225 |
|
226 CCLFDbItemProvider* itemProvider = CCLFDbItemProvider::NewL( *iDbItemContainer, *iQueryAdapter, iMdESession ); |
|
227 // self takes ownership of itemProvider. |
|
228 CCLFItemListModelImpl* self = CCLFItemListModelImpl::NewLC( itemProvider, aObserver, iChangedItemModel ); |
|
229 iChangedItemModel.AddObserverL( self ); |
|
230 return self; |
|
231 } |
|
232 |
|
233 // ----------------------------------------------------------------------------- |
|
234 // CCLFEngineImpl::CreateListModelLC |
|
235 // ----------------------------------------------------------------------------- |
|
236 // |
|
237 MCLFItemListModel* CCLFEngineImpl::CreateListModelLC( |
|
238 MCLFOperationObserver& aObserver, |
|
239 TResourceReader& aReader ) |
|
240 { |
|
241 CCLFDbItemProvider* itemProvider = CCLFDbItemProvider::NewL( *iDbItemContainer, *iQueryAdapter, iMdESession ); |
|
242 // self takes ownership of itemProvider. |
|
243 CCLFItemListModelImpl* self = CCLFItemListModelImpl::NewLC( itemProvider, aObserver, iChangedItemModel, aReader ); |
|
244 iChangedItemModel.AddObserverL( self ); |
|
245 return self; |
|
246 } |
|
247 |
|
248 // ----------------------------------------------------------------------------- |
|
249 // CCLFEngineImpl::HandleUpdateEndEventL |
|
250 // ----------------------------------------------------------------------------- |
|
251 // |
|
252 void CCLFEngineImpl::HandleUpdateEndEventL( const TInt aError ) |
|
253 { |
|
254 if ( aError == KErrNone ) |
|
255 { |
|
256 // get changed items and add new ones to array |
|
257 RArray< TCLFItemId > changedItemIdArray; |
|
258 CleanupClosePushL( changedItemIdArray ); |
|
259 iUpdateEndEventHandler->GetChangedItemsL( changedItemIdArray ); |
|
260 const TInt count( changedItemIdArray.Count() ); |
|
261 for ( TInt i = 0; i < count; ++i ) |
|
262 { |
|
263 const TCLFItemId id( changedItemIdArray[ i ] ); |
|
264 const TInt index( |
|
265 iChangedItemModel.iChangedItemIdArray.Find( id ) ); |
|
266 if ( index == KErrNotFound ) |
|
267 { |
|
268 iChangedItemModel.iChangedItemIdArray.AppendL( id ); |
|
269 } |
|
270 } |
|
271 CleanupStack::PopAndDestroy( &changedItemIdArray ); |
|
272 |
|
273 if ( iChangedItemModel.iChangedItemIdArray.Count() ) |
|
274 { |
|
275 iDbItemContainer->SetDeprecatedItems( |
|
276 iChangedItemModel.iChangedItemIdArray ); |
|
277 |
|
278 iItemProvider->PrepareItemsL( |
|
279 iChangedItemModel.iChangedItemIdArray.Array(), |
|
280 *this ); |
|
281 } |
|
282 else |
|
283 { |
|
284 // no changed items -> just notify process observers |
|
285 NotifyProcessObserversL( ECLFUpdateStop ); |
|
286 } |
|
287 } |
|
288 else |
|
289 { |
|
290 const TInt count( iChangedItemObserverArray.Count() ); |
|
291 for ( TInt i = 0 ; i < count ; ++i ) |
|
292 { |
|
293 iChangedItemObserverArray[i]->HandleError( aError ); |
|
294 } |
|
295 } |
|
296 } |
|
297 |
|
298 // ----------------------------------------------------------------------------- |
|
299 // CCLFEngineImpl::OperationCompleteL |
|
300 // ----------------------------------------------------------------------------- |
|
301 // |
|
302 void CCLFEngineImpl::OperationCompleteL( const TInt aError ) |
|
303 { |
|
304 // make sure that changed item model is reset |
|
305 // array must be reset when changed items are handled (also in leave case) |
|
306 CleanupStack::PushL( TCleanupItem( CleanupTempModel, |
|
307 &iChangedItemModel) ); |
|
308 |
|
309 if ( aError ) |
|
310 { |
|
311 const TInt count( iChangedItemObserverArray.Count() ); |
|
312 for( TInt i = 0 ; i < count ; ++i ) |
|
313 { |
|
314 iChangedItemObserverArray[i]->HandleError( aError ); |
|
315 } |
|
316 } |
|
317 else |
|
318 { |
|
319 // put items to container |
|
320 User::LeaveIfError( iItemProvider->GetItems( |
|
321 iChangedItemModel.iItemArray ) ); |
|
322 |
|
323 // notify process observers |
|
324 NotifyProcessObserversL( ECLFUpdateStop ); |
|
325 |
|
326 // notify changed item observers |
|
327 if ( iChangedItemModel.iChangedItemIdArray.Count() > 0 ) |
|
328 { |
|
329 const TInt count( iChangedItemObserverArray.Count() ); |
|
330 for( TInt i = 0 ; i < count ; ++i ) |
|
331 { |
|
332 iChangedItemObserverArray[i]->HandleItemChangeL( |
|
333 iChangedItemModel.iChangedItemIdArray.Array() ); |
|
334 } |
|
335 |
|
336 // notify models |
|
337 iChangedItemModel.NotifyObserverL(); |
|
338 } |
|
339 } |
|
340 CleanupStack::PopAndDestroy(); // TCleanupItem |
|
341 } |
|
342 |
|
343 // ----------------------------------------------------------------------------- |
|
344 // CCLFEngineImpl::HandleUpdateStartEventL |
|
345 // ----------------------------------------------------------------------------- |
|
346 // |
|
347 void CCLFEngineImpl::HandleUpdateStartEventL( const TInt aError ) |
|
348 { |
|
349 if ( aError == KErrNone ) |
|
350 { |
|
351 NotifyProcessObserversL( ECLFUpdateStart ); |
|
352 } |
|
353 } |
|
354 |
|
355 // ----------------------------------------------------------------------------- |
|
356 // CCLFEngineImpl::NotifyProcessObserversL |
|
357 // ----------------------------------------------------------------------------- |
|
358 // |
|
359 void CCLFEngineImpl::NotifyProcessObserversL( TCLFProcessEvent aEvent ) |
|
360 { |
|
361 const TInt count( iProcessObserverArray.Count() ); |
|
362 for ( TInt i = 0 ; i < count ; ++i ) |
|
363 { |
|
364 iProcessObserverArray[i]->HandleCLFProcessEventL( aEvent ); |
|
365 } |
|
366 } |
|
367 |
|
368 // ----------------------------------------------------------------------------- |
|
369 // CCLFEngineImpl::StopEventHandling |
|
370 // ----------------------------------------------------------------------------- |
|
371 // |
|
372 void CCLFEngineImpl::StopEventHandling() |
|
373 { |
|
374 if ( iProcessObserverArray.Count() == 0 ) |
|
375 { |
|
376 // stop "start observing" |
|
377 iUpdateStartEventHandler->Cancel(); |
|
378 } |
|
379 } |
|
380 |
|
381 // ----------------------------------------------------------------------------- |
|
382 // CCLFEngineImpl::CCLFTempModel::IsItemsForModel |
|
383 // ----------------------------------------------------------------------------- |
|
384 // |
|
385 TBool CCLFEngineImpl::CCLFTempModel::IsItemsForModel( |
|
386 const MDesCArray& aMimeTypes, |
|
387 const TArray<TInt>& aMediaTypes, |
|
388 const TArray<TUint>& aModelItemIds ) |
|
389 { |
|
390 // first from item IDs |
|
391 TInt count( aModelItemIds.Count() ); |
|
392 for ( TInt i = 0 ; i < count ; ++i ) |
|
393 { |
|
394 const TInt index( iChangedItemIdArray.FindInOrder( aModelItemIds[ i ] ) ); |
|
395 if( index >= 0 ) |
|
396 { |
|
397 return ETrue; |
|
398 } |
|
399 } |
|
400 |
|
401 // find second from media types (faster) |
|
402 count = aMediaTypes.Count(); |
|
403 for ( TInt i = 0 ; i < count ; ++i ) |
|
404 { |
|
405 const TInt index( iMediaTypeArray.FindInOrder( aMediaTypes[ i ] ) ); |
|
406 if ( index >= 0 ) |
|
407 { |
|
408 return ETrue; |
|
409 } |
|
410 } |
|
411 |
|
412 // and mimetypes, final from mimetypes, |
|
413 // because descriptor comparation is slow |
|
414 count = aMimeTypes.MdcaCount(); |
|
415 const TInt mCount( iMimeTypeArray.MdcaCount() ); |
|
416 for ( TInt i = 0 ; i < count ; ++i ) |
|
417 { |
|
418 // match model mimetypes to changed item(s) mimetypes |
|
419 const TDesC& modelMimeType = aMimeTypes.MdcaPoint( i ); |
|
420 for ( TInt j = 0 ; j < mCount ; ++j ) |
|
421 { |
|
422 const TDesC& changedItemMimeType = iMimeTypeArray.MdcaPoint( j ); |
|
423 const TInt match( changedItemMimeType.Match( modelMimeType ) ); |
|
424 if ( match != KErrNotFound ) |
|
425 { |
|
426 return ETrue; |
|
427 } |
|
428 } |
|
429 } |
|
430 |
|
431 return EFalse; |
|
432 } |
|
433 |
|
434 // ----------------------------------------------------------------------------- |
|
435 // CCLFEngineImpl::CCLFTempModel::CCLFTempModel |
|
436 // ----------------------------------------------------------------------------- |
|
437 // |
|
438 CCLFEngineImpl::CCLFTempModel::CCLFTempModel() |
|
439 : iItemArray( KCLFChangedItemIdArrayGranularity ), |
|
440 iChangedItemIdArray( KCLFChangedItemIdArrayGranularity ), |
|
441 iChangedItemProviderObserverArray( KCLFChangedItemIdArrayGranularity ), |
|
442 iMimeTypeArray( KCLFChangedItemIdArrayGranularity ), |
|
443 iMediaTypeArray( KCLFChangedItemIdArrayGranularity ) |
|
444 { |
|
445 } |
|
446 |
|
447 // ----------------------------------------------------------------------------- |
|
448 // CCLFEngineImpl::CCLFTempModel::~CCLFTempModel |
|
449 // ----------------------------------------------------------------------------- |
|
450 // |
|
451 CCLFEngineImpl::CCLFTempModel::~CCLFTempModel() |
|
452 { |
|
453 ResetModelArray(); |
|
454 iChangedItemProviderObserverArray.Close(); |
|
455 } |
|
456 |
|
457 // ----------------------------------------------------------------------------- |
|
458 // CCLFEngineImpl::CCLFTempModel::AddObserverL |
|
459 // ----------------------------------------------------------------------------- |
|
460 // |
|
461 void CCLFEngineImpl::CCLFTempModel::AddObserverL( |
|
462 MCLFChangedItemProviderObserver* aObserver ) |
|
463 { |
|
464 iChangedItemProviderObserverArray.AppendL( aObserver ); |
|
465 } |
|
466 |
|
467 // ----------------------------------------------------------------------------- |
|
468 // CCLFEngineImpl::CCLFTempModel::ResetModelArray |
|
469 // ----------------------------------------------------------------------------- |
|
470 // |
|
471 void CCLFEngineImpl::CCLFTempModel::ResetModelArray() |
|
472 { |
|
473 iItemArray.ResetAndDestroy(); |
|
474 iMimeTypeArray.Reset(); |
|
475 iMediaTypeArray.Reset(); |
|
476 iChangedItemIdArray.Reset(); |
|
477 } |
|
478 |
|
479 // ----------------------------------------------------------------------------- |
|
480 // CCLFEngineImpl::CCLFTempModel::NotifyObserverL |
|
481 // ----------------------------------------------------------------------------- |
|
482 // |
|
483 void CCLFEngineImpl::CCLFTempModel::NotifyObserverL() |
|
484 { |
|
485 PrepareModelL(); |
|
486 |
|
487 const TInt providerObserverCount( |
|
488 iChangedItemProviderObserverArray.Count() ); |
|
489 for ( TInt i = 0 ; i < providerObserverCount ; ++i ) |
|
490 { |
|
491 iChangedItemProviderObserverArray[i]->NewChangedItemsL(); |
|
492 } |
|
493 } |
|
494 |
|
495 // ----------------------------------------------------------------------------- |
|
496 // CCLFEngineImpl::CCLFTempModel::PrepareModelL |
|
497 // ----------------------------------------------------------------------------- |
|
498 // |
|
499 void CCLFEngineImpl::CCLFTempModel::PrepareModelL() |
|
500 { |
|
501 // sort array for faster find |
|
502 iChangedItemIdArray.Sort(); |
|
503 |
|
504 // get mimetypes and media types from items |
|
505 const TInt modelCount( iItemArray.Count() ); |
|
506 for ( TInt i = 0 ; i < modelCount ; ++i ) |
|
507 { |
|
508 MCLFItem* item = iItemArray[ i ]; |
|
509 |
|
510 TInt32 mediaType( 0 ); |
|
511 TInt error( item->GetField( ECLFFieldIdMediaType, mediaType ) ); |
|
512 if ( error == KErrNone && |
|
513 iMediaTypeArray.FindInOrder( mediaType ) == KErrNotFound ) |
|
514 { |
|
515 User::LeaveIfError( iMediaTypeArray.InsertInOrder( mediaType ) ); |
|
516 } |
|
517 TPtrC mimeType; |
|
518 error = item->GetField( ECLFFieldIdMimeType, mimeType ); |
|
519 TInt pos( 0 ); |
|
520 if ( error == KErrNone && |
|
521 iMimeTypeArray.FindIsq( mimeType, pos ) != 0 ) // not found |
|
522 { |
|
523 iMimeTypeArray.InsertIsqL( mimeType ); |
|
524 } |
|
525 } |
|
526 } |
|
527 |
|
528 // ----------------------------------------------------------------------------- |
|
529 // CCLFEngineImpl::CCLFTempModel::ChangedItemProviderRemoveObserver |
|
530 // ----------------------------------------------------------------------------- |
|
531 // |
|
532 void CCLFEngineImpl::CCLFTempModel::RemoveChangedItemProviderObserver( |
|
533 MCLFChangedItemProviderObserver* aObserver ) |
|
534 { |
|
535 const TInt index( iChangedItemProviderObserverArray.Find( aObserver ) ); |
|
536 if ( index >= 0 ) |
|
537 { |
|
538 iChangedItemProviderObserverArray.Remove( index ); |
|
539 } |
|
540 } |
|
541 |
|
542 // End of File |