|
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <coecontrolarray.h> // class CCoeControlArray |
|
17 #include <coecntrl.h> // class CCoeControl |
|
18 #include "coepanic.h" // Cone panic codes |
|
19 #include <e32std.h> // class EUser |
|
20 |
|
21 /** |
|
22 Flags used internally. |
|
23 */ |
|
24 enum TFlags |
|
25 { |
|
26 /** Controls are owned externally. This means that the destructor |
|
27 shouldn't delete the individual controls. |
|
28 */ |
|
29 EControlsOwnedExternally = 0x01, |
|
30 /** When the array is locked any attempt to add or remove elements will result in KErrLocked. |
|
31 */ |
|
32 EArrayLocked = 0x02 |
|
33 }; |
|
34 |
|
35 LOCAL_C void CleanupComponentControl(TAny* aCleanupItem) |
|
36 { |
|
37 CCoeControl* control = reinterpret_cast<CCoeControl*>(aCleanupItem); |
|
38 if (control) |
|
39 { |
|
40 control->RemoveFromParent(); |
|
41 delete control; |
|
42 } |
|
43 } |
|
44 |
|
45 LOCAL_C void CleanupExternallyOwnedComponentControl(TAny* aCleanupItem) |
|
46 { |
|
47 CCoeControl* control = reinterpret_cast<CCoeControl*>(aCleanupItem); |
|
48 if (control) |
|
49 { |
|
50 control->RemoveFromParent(); |
|
51 } |
|
52 } |
|
53 |
|
54 // |
|
55 // class CCoeControlArray::TCursor |
|
56 // |
|
57 |
|
58 /** Updates the cursor so that it points to the previous element in the array. |
|
59 If the current element is the first one then this function does nothing and returns EFalse. |
|
60 |
|
61 @return EFalse if the current element was the first one in the array, ETrue if it wasn't and the function |
|
62 actually did something. |
|
63 */ |
|
64 EXPORT_C TBool CCoeControlArray::TCursor::Prev() |
|
65 { |
|
66 if(iIndex <= 0) |
|
67 return EFalse; |
|
68 |
|
69 iIndex--; |
|
70 UpdateMemento(); |
|
71 return ETrue; |
|
72 } |
|
73 |
|
74 /** Updates the cursor so that it points to the next element in the array. |
|
75 If the current element is the last one then this function returns EFalse. |
|
76 |
|
77 @return EFalse if the current element was the last one in the array, ETrue otherwise |
|
78 */ |
|
79 EXPORT_C TBool CCoeControlArray::TCursor::Next() |
|
80 { |
|
81 const TInt count = iArray->Count(); |
|
82 if(iIndex >= count-1) //If last element or beyond move to just off the end of the array |
|
83 { |
|
84 iIndex = count; |
|
85 iMemento = TCoeControlWithId(KCoeNoControlId); |
|
86 return EFalse; |
|
87 } |
|
88 iIndex++; |
|
89 UpdateMemento(); |
|
90 return ETrue; |
|
91 } |
|
92 |
|
93 /** Checks if the cursor is valid. Use this to replace the comparison with NULL that you would |
|
94 do with pointers. This function is typically used on the cursors returned by the find operations. |
|
95 @return ETrue if the cursor points to a control, EFalse otherwise |
|
96 */ |
|
97 EXPORT_C TBool CCoeControlArray::TCursor::IsValid() const |
|
98 { |
|
99 UpdateIndex(); |
|
100 return (iIndex != KErrNotFound); |
|
101 } |
|
102 |
|
103 /** Checks if the cursors are equal. Cursors are equal if they point to the same control in the |
|
104 same array else they are different. |
|
105 @param aCursor The other cursor. |
|
106 @return ETrue if the cursors point to the same position in the same array, EFalse |
|
107 otherwise. |
|
108 */ |
|
109 EXPORT_C TBool CCoeControlArray::TCursor::operator ==(const TCursor& aCursor) const |
|
110 { |
|
111 UpdateIndex(); |
|
112 aCursor.UpdateIndex(); |
|
113 |
|
114 ASSERT(IsValid()); |
|
115 ASSERT(aCursor.IsValid()); |
|
116 |
|
117 return (iIndex == aCursor.iIndex && iArray == aCursor.iArray); |
|
118 } |
|
119 |
|
120 /** Checks if the cursors are different. Cursors are equal if they point to the same control in the |
|
121 same array else they are different. |
|
122 @param aCursor The other cursor. |
|
123 @return EFalse if the cursors point to the same position in the same array, EFalse |
|
124 otherwise. |
|
125 */ |
|
126 EXPORT_C TBool CCoeControlArray::TCursor::operator !=(const TCursor& aCursor) const |
|
127 { |
|
128 UpdateIndex(); |
|
129 aCursor.UpdateIndex(); |
|
130 |
|
131 ASSERT(IsValid()); |
|
132 ASSERT(aCursor.IsValid()); |
|
133 |
|
134 return !(iIndex == aCursor.iIndex && iArray == aCursor.iArray); |
|
135 } |
|
136 |
|
137 /** Constructor. |
|
138 @param aArray The array |
|
139 @param aIndex The index into the array |
|
140 */ |
|
141 CCoeControlArray::TCursor::TCursor(const CCoeControlArray& aArray, TInt aIndex) : |
|
142 iArray(&aArray), iIndex(aIndex), iMemento(KCoeNoControlId) |
|
143 { |
|
144 if(aIndex >= 0 && aIndex < aArray.Count()) |
|
145 iMemento = TCoeControlWithId(aArray.At(aIndex)); |
|
146 } |
|
147 |
|
148 /** Gets the index of the cursor. |
|
149 @return The index i.e. the position in the array |
|
150 */ |
|
151 TInt CCoeControlArray::TCursor::Index() const |
|
152 { |
|
153 UpdateIndex(); |
|
154 return iIndex; |
|
155 } |
|
156 |
|
157 /** Gets the control of the cursor. |
|
158 @return The control. |
|
159 */ |
|
160 EXPORT_C CCoeControl* CCoeControlArray::TCursor::Ctrl() const |
|
161 { |
|
162 UpdateIndex(); |
|
163 if(iIndex == KErrNotFound || iIndex >= iArray->Count()) |
|
164 return NULL; |
|
165 else |
|
166 return iArray->At(iIndex).iControl; |
|
167 } |
|
168 |
|
169 /** This function is used by any operation that requires an update of the memento. |
|
170 */ |
|
171 void CCoeControlArray::TCursor::UpdateMemento() const |
|
172 { |
|
173 if(iIndex >= 0 && iIndex < iArray->Count()) |
|
174 iMemento = iArray->At(iIndex); |
|
175 else |
|
176 { |
|
177 iIndex = KErrNotFound; |
|
178 iMemento = TCoeControlWithId(KErrNotFound); |
|
179 } |
|
180 } |
|
181 |
|
182 /** This function is used by any operation that requires an update of the index. |
|
183 */ |
|
184 void CCoeControlArray::TCursor::UpdateIndex() const |
|
185 { |
|
186 if(!iMemento.iControl) // If we don't know what control this cursor should point to |
|
187 { |
|
188 // This is either an invalid cursor (if iIndex == -1) |
|
189 // or one that points to the element just beyond the end of the array (iIndex == iArray->Count()) |
|
190 |
|
191 // If the iIndex is pointing anywhere but at CCoeControlArray::End() it has gone bad |
|
192 if(iIndex != KErrNotFound && iIndex != iArray->Count()) |
|
193 { |
|
194 iIndex = KErrNotFound; |
|
195 iMemento = TCoeControlWithId(KErrNotFound); |
|
196 } |
|
197 |
|
198 return; |
|
199 } |
|
200 |
|
201 if(iIndex >= 0 && iIndex < iArray->Count()) // If the index is within the valid range |
|
202 { |
|
203 // Check that the control at iIndex is the same as the memento |
|
204 |
|
205 const TCoeControlWithId controlWithId = iArray->At(iIndex); |
|
206 if(iMemento.iControl != controlWithId.iControl) // If not, update the index to match the memento |
|
207 { |
|
208 const TInt newIndex = iArray->Find(iMemento.iControl).iIndex; |
|
209 if(newIndex != KErrNotFound) |
|
210 iIndex = newIndex; |
|
211 else |
|
212 { |
|
213 // If the memento control is no longer in the array, try update the memento instead |
|
214 UpdateMemento(); |
|
215 } |
|
216 } |
|
217 } |
|
218 else |
|
219 { |
|
220 const TInt newIndex = iArray->Find(iMemento.iControl).iIndex; |
|
221 if(newIndex != KErrNotFound) |
|
222 iIndex = newIndex; |
|
223 else |
|
224 iMemento = TCoeControlWithId(KErrNotFound); |
|
225 } |
|
226 } |
|
227 |
|
228 |
|
229 // |
|
230 // class CCoeControlArray |
|
231 // |
|
232 |
|
233 /** Creates a new CCoeControlArray. |
|
234 @param aOwner The control that owns the new array |
|
235 @return A new CCoeControlArray instance |
|
236 */ |
|
237 EXPORT_C CCoeControlArray* CCoeControlArray::NewL(CCoeControl& aOwner) |
|
238 { |
|
239 CCoeControlArray* self = new (ELeave) CCoeControlArray(aOwner); |
|
240 return self; |
|
241 } |
|
242 |
|
243 /** Constructor. |
|
244 */ |
|
245 TCoeControlWithId::TCoeControlWithId(TInt aControlId, CCoeControl* aControl) : iControl(aControl), iId(aControlId) |
|
246 { |
|
247 } |
|
248 |
|
249 /** The destructor will delete the controls in the array only if the EControlsOwnedExternally flag is not set. |
|
250 */ |
|
251 EXPORT_C CCoeControlArray::~CCoeControlArray() |
|
252 { |
|
253 if(!ControlsOwnedExternally()) |
|
254 ResetAndDestroy(); |
|
255 |
|
256 iControls.Close(); |
|
257 } |
|
258 |
|
259 const TInt KControlArrayGranularity = 1; |
|
260 |
|
261 /** Constructor |
|
262 @param aOwner The control that owns the new array |
|
263 */ |
|
264 EXPORT_C CCoeControlArray::CCoeControlArray(CCoeControl& aOwner) |
|
265 : iOwner(aOwner), iControls(KControlArrayGranularity, _FOFF(TCoeControlWithId, iId)) |
|
266 { |
|
267 } |
|
268 |
|
269 /** Gets the number of elements in the array. |
|
270 @return The number of elements in the array |
|
271 */ |
|
272 EXPORT_C TInt CCoeControlArray::Count() const |
|
273 { |
|
274 return iControls.Count(); |
|
275 } |
|
276 |
|
277 /** Removes all the controls from the array but doesn't delete them. |
|
278 */ |
|
279 EXPORT_C void CCoeControlArray::Reset() |
|
280 { |
|
281 iControls.Reset(); |
|
282 } |
|
283 |
|
284 /** Removes all the controls from the array and deletes them. |
|
285 */ |
|
286 EXPORT_C void CCoeControlArray::ResetAndDestroy() |
|
287 { |
|
288 for(TInt i = iControls.Count()-1; i >= 0; i--) // remove from the end, so we don't need to move any items |
|
289 { |
|
290 delete iControls[i].iControl; |
|
291 // The array must be shrunk immediately to avoid Kern-Exec 3 when calling CCoeControl::Components() |
|
292 // or CCoeControl::ComponentControl(TInt aIndex) inside MCoeFocusObserver::HandleDestructionOfFocusedItem |
|
293 iControls.Remove(i); |
|
294 } |
|
295 |
|
296 iControls.Reset(); |
|
297 } |
|
298 |
|
299 /** Sorts the controls using their index as the key. |
|
300 */ |
|
301 EXPORT_C void CCoeControlArray::SortById() |
|
302 { |
|
303 iControls.SortSigned(); |
|
304 } |
|
305 |
|
306 /**This function provides a pluggable implementation to sort the array of controls. |
|
307 @param aOrder The user defined static method which implements the algorithm for sorting. |
|
308 */ |
|
309 EXPORT_C void CCoeControlArray::Sort(TLinearOrder< TCoeControlWithId > aOrder) |
|
310 { |
|
311 iControls.Sort(aOrder); |
|
312 } |
|
313 /** This function checks if the controls are owned by the array or not. If the controls are owned by the array they |
|
314 will be deleted when the array is destroyed else they will not. |
|
315 |
|
316 @return ETrue if the array does NOT own the controls, EFalse if the array owns the controls. |
|
317 */ |
|
318 EXPORT_C TBool CCoeControlArray::ControlsOwnedExternally() const |
|
319 { |
|
320 return (iFlags&EControlsOwnedExternally); |
|
321 } |
|
322 |
|
323 /** Is used to set whether the array owns the controls or not. If the controls are owned by the array they |
|
324 will be deleted when the array is destroyed else they will not. |
|
325 |
|
326 @param aOwnedExternally ETrue if the controls are owned externally, EFalse if |
|
327 they are owned by the array. |
|
328 */ |
|
329 EXPORT_C void CCoeControlArray::SetControlsOwnedExternally(TBool aOwnedExternally) |
|
330 { |
|
331 if(aOwnedExternally) |
|
332 { |
|
333 iFlags |= EControlsOwnedExternally; |
|
334 } |
|
335 else |
|
336 { |
|
337 iFlags &= ~EControlsOwnedExternally; |
|
338 } |
|
339 } |
|
340 |
|
341 /** Checks whether the array is locked or not. If an array is locked any attempt to add or remove controls |
|
342 will fail with KErrLocked. |
|
343 |
|
344 @return ETrue if the array is locked, EFalse otherwise |
|
345 */ |
|
346 EXPORT_C TBool CCoeControlArray::IsArrayLocked() const |
|
347 { |
|
348 return (iFlags&EArrayLocked); |
|
349 } |
|
350 |
|
351 /** Locks the array. If an array is locked any attempt to add or remove controls |
|
352 will fail with KErrLocked. |
|
353 */ |
|
354 EXPORT_C void CCoeControlArray::SetArrayLocked() |
|
355 { |
|
356 iFlags |= EArrayLocked; |
|
357 } |
|
358 |
|
359 /** Gets a cursor that points to the first element of the array. Note that if the array is empty |
|
360 this is actually equivalent to a call to End(). |
|
361 |
|
362 @return A cursor that points to the first control in the array. |
|
363 */ |
|
364 EXPORT_C CCoeControlArray::TCursor CCoeControlArray::Begin() const |
|
365 { |
|
366 return TCursor(*this, 0); |
|
367 } |
|
368 |
|
369 /** Gets a cursor to the position right after the last element in the array. To get the last element |
|
370 use Prev(). This cursor is useful as argument to the insertion function to add the new control at the end of the array. |
|
371 |
|
372 @return A cursor that points right after the last element |
|
373 */ |
|
374 EXPORT_C CCoeControlArray::TCursor CCoeControlArray::End() const |
|
375 { |
|
376 return TCursor(*this, Count()); |
|
377 } |
|
378 |
|
379 /** Gets a cursor to the control, if the control is found in the array. Use |
|
380 the TCursor::IsValid function to check that the search found something or not. |
|
381 |
|
382 @param aControl The control to find. |
|
383 @return A cursor to the control. This may be an invalid cursor if we didn't |
|
384 find the requested control. Use TCursor::IsValid() to check if the cursor is valid. |
|
385 */ |
|
386 EXPORT_C CCoeControlArray::TCursor CCoeControlArray::Find(const CCoeControl* aControl) const |
|
387 { |
|
388 const TInt numControls = iControls.Count(); |
|
389 for(TInt index = 0; index < numControls; index++) |
|
390 { |
|
391 if(iControls[index].iControl == aControl) |
|
392 return TCursor(*this, index); |
|
393 } |
|
394 |
|
395 return TCursor(*this, KCoeNoControlId); |
|
396 } |
|
397 |
|
398 /** Gets a cursor to the control, if the control with the given id is found in the array. |
|
399 Use the TCusror::IsValid function to check that the search found something or not. |
|
400 |
|
401 @param aControlId The id of the control to find. |
|
402 @return A cursor to the control. This may be an invalid cursor if we didn't |
|
403 find the requested control. Use TCursor::IsValid() to check if the cursor is valid. |
|
404 */ |
|
405 EXPORT_C CCoeControlArray::TCursor CCoeControlArray::Find(TInt aControlId) const |
|
406 { |
|
407 const TInt index = iControls.Find(TCoeControlWithId(aControlId)); |
|
408 return TCursor(*this, index); |
|
409 } |
|
410 |
|
411 /** Appends a control at the end of the array. |
|
412 |
|
413 @param aControl The control to add |
|
414 @param aControlId The id for the new control |
|
415 @return A cursor to the added control |
|
416 */ |
|
417 EXPORT_C CCoeControlArray::TCursor CCoeControlArray::AppendLC(CCoeControl* aControl, TInt aControlId) |
|
418 { |
|
419 TCursor cursor = End(); |
|
420 InsertLC(cursor, aControl, aControlId); |
|
421 return cursor; |
|
422 } |
|
423 |
|
424 /** Inserts a control after the control with the given id. |
|
425 |
|
426 Each array has an owner (an instance of the CCoeControl class) which is the container of all the child controls. |
|
427 Each control has a parent and for the child controls this parent must be the container. This function will automatically |
|
428 update the parent of aControl. |
|
429 |
|
430 The function will also result in the CCoeControl::HandleControlArrayEventL method being called |
|
431 on the owner of the array. The event being generated is EControlAdded. |
|
432 |
|
433 @param aInsertAfterId The id of the control after which we want to insert the new control. If a control with this |
|
434 id can't be found in the array the function will leave with KErrNotFound. |
|
435 @param aControl The new control we want to add. |
|
436 @param aControlId The id of the new control. |
|
437 @return A cursor to the added control |
|
438 @leave KErrLocked if the array has been locked using the CCoeControlArray::SetArrayLocked() function. |
|
439 @leave KErrNotFound if the array doesn't contain a control identified by aInsertAfterId. |
|
440 */ |
|
441 EXPORT_C CCoeControlArray::TCursor CCoeControlArray::InsertAfterLC(TInt aInsertAfterId, CCoeControl* aControl, TInt aControlId) |
|
442 { |
|
443 const TInt index = IndexById(aInsertAfterId); |
|
444 if(index == KErrNotFound) |
|
445 { |
|
446 if(!(iFlags & EControlsOwnedExternally)) |
|
447 delete aControl; |
|
448 User::Leave(KErrNotFound); |
|
449 } |
|
450 TCursor cursor(*this, index); |
|
451 cursor.Next(); // insert before the next item |
|
452 return(InsertLC(cursor, aControl, aControlId)); |
|
453 } |
|
454 |
|
455 /** Inserts a control at the given position. |
|
456 |
|
457 Each array has an owner (an instance of the CCoeControl class) which is the container of all the child controls. |
|
458 Each control has a parent and for the child controls this parent must be the container. This function will automatically |
|
459 update the parent of aControl. |
|
460 |
|
461 The function will also result in the CCoeControl::HandleControlArrayEventL method being called |
|
462 on the owner of the array. The event being generated is EControlAdded. |
|
463 |
|
464 @param aInsertAt The position at which we want to insert the new control. |
|
465 @param aControl The new control we want to add. |
|
466 @param aControlId The id of the new control. |
|
467 @return A cursor to the added control |
|
468 @leave KErrLocked if the array has been locked using the CCoeControlArray::SetArrayLocked() function. |
|
469 */ |
|
470 EXPORT_C CCoeControlArray::TCursor CCoeControlArray::InsertLC(TCursor& aInsertAt, CCoeControl* aControl, TInt aControlId) |
|
471 { |
|
472 __ASSERT_DEBUG(this, Panic(ECoePanicNonExistentArray)); |
|
473 |
|
474 const TBool externallyOwned = iFlags & EControlsOwnedExternally; |
|
475 |
|
476 // Set parent before pushing the CleanupComponenetControl, so that we can |
|
477 // look for external ownership on parent if something leaves |
|
478 const TInt err = aControl->SetParent(&iOwner); |
|
479 if(err != KErrNone) |
|
480 { |
|
481 if(!externallyOwned) |
|
482 delete aControl; |
|
483 User::Leave(err); |
|
484 } |
|
485 |
|
486 CleanupStack::PushL(TCleanupItem((externallyOwned ? |
|
487 CleanupExternallyOwnedComponentControl : |
|
488 CleanupComponentControl), |
|
489 aControl)); |
|
490 |
|
491 if(IsArrayLocked()) |
|
492 User::Leave(KErrLocked); |
|
493 |
|
494 #ifdef _DEBUG |
|
495 __ASSERT_DEBUG(aControlId == KCoeNoControlId || |
|
496 iControls.Find(TCoeControlWithId(aControlId)) == KErrNotFound, Panic(ECoePanicDuplicateControlId)); |
|
497 #endif |
|
498 |
|
499 // To preserve the insertion order of controls without assigned ID |
|
500 if(aControlId == KCoeNoControlId) // If the control has not been given an ID... |
|
501 { |
|
502 // ...loop through all controls and find the largest negative ID (i.e. the one closest to zero) |
|
503 TInt autoId = KMinTInt32; |
|
504 const TInt count = iControls.Count(); |
|
505 for(TInt i = 0; i < count; i++) |
|
506 { |
|
507 const TInt controlId = iControls[i].iId; |
|
508 if(controlId < 0 && autoId <= controlId) |
|
509 { |
|
510 autoId = controlId+1; |
|
511 } |
|
512 } |
|
513 |
|
514 aControlId = autoId; // Give the new control the next larger negative ID |
|
515 } |
|
516 |
|
517 iControls.InsertL(TCoeControlWithId(aControlId, aControl), aInsertAt.Index()); |
|
518 iOwner.HandleControlArrayEventL(EControlAdded, this, aControl, aControlId); |
|
519 |
|
520 const TCursor newItemCursor = aInsertAt; |
|
521 aInsertAt.Next(); // Move the cursor forward to presserve its position in the array |
|
522 |
|
523 return newItemCursor; |
|
524 } |
|
525 |
|
526 /** Removes a control but does NOT delete the control itself. The ownership of the control is |
|
527 transferred to the caller. |
|
528 |
|
529 The function will also result in the CCoeControl::HandleControlArrayEventL method being called |
|
530 on the owner of the array. The event being generated is EControlRemoved. |
|
531 |
|
532 @param aControl The control to remove |
|
533 @return KErrNone if the control was removed successfully, KErrNotFound if the control could not be found. |
|
534 */ |
|
535 EXPORT_C TInt CCoeControlArray::Remove(const CCoeControl* aControl) |
|
536 { |
|
537 for(TInt i = 0; i < iControls.Count(); i++) |
|
538 { |
|
539 const TCoeControlWithId controlWithId = iControls[i]; |
|
540 if(controlWithId.iControl == aControl) |
|
541 { |
|
542 iControls.Remove(i); |
|
543 // EControlRemoved event must never cause leave |
|
544 TRAP_IGNORE(iOwner.HandleControlArrayEventL(EControlRemoved, this, controlWithId.iControl, controlWithId.iId)); |
|
545 return KErrNone; |
|
546 } |
|
547 } |
|
548 |
|
549 return KErrNotFound; |
|
550 } |
|
551 |
|
552 /** Removes a control but does NOT delete the control itself. The ownership of the control is |
|
553 transferred to the caller. |
|
554 |
|
555 The function will also result in the CCoeControl::HandleControlArrayEventL method being called |
|
556 on the owner of the array. The event being generated is EControlRemoved. |
|
557 |
|
558 @param aRemoveAt The position of the control to remove |
|
559 @return A pointer to the control that has been removed. This can be used by the caller to delete the control. |
|
560 */ |
|
561 EXPORT_C CCoeControl* CCoeControlArray::Remove(TCursor aRemoveAt) |
|
562 { |
|
563 const TCoeControlWithId controlWithId = iControls[aRemoveAt.Index()]; |
|
564 iControls.Remove(aRemoveAt.Index()); |
|
565 // EControlRemoved event must never cause leave |
|
566 TRAP_IGNORE(iOwner.HandleControlArrayEventL(EControlRemoved, this, controlWithId.iControl, controlWithId.iId)); |
|
567 |
|
568 return controlWithId.iControl; |
|
569 } |
|
570 |
|
571 /** Removes a control but does NOT delete the control itself. The ownership of the control is |
|
572 transferred to the caller. |
|
573 |
|
574 The function will also result in the CCoeControl::HandleControlArrayEventL method being called |
|
575 on the owner of the array. The event being generated is EControlRemoved. |
|
576 |
|
577 @param aControlId The id of the control to remove |
|
578 @return A pointer to the control that has been removed. This can be used by the caller to delete the control. The function |
|
579 returns NULL if no control with the given aControlId has been found. |
|
580 */ |
|
581 EXPORT_C CCoeControl* CCoeControlArray::RemoveById(TInt aControlId) |
|
582 { |
|
583 const TInt index = IndexById(aControlId); |
|
584 if(index != KErrNotFound) |
|
585 { |
|
586 const TCoeControlWithId controlWithId = iControls[index]; |
|
587 iControls.Remove(index); |
|
588 // EControlRemoved event must never cause leave |
|
589 TRAP_IGNORE(iOwner.HandleControlArrayEventL(EControlRemoved, this, controlWithId.iControl, controlWithId.iId)); |
|
590 return controlWithId.iControl; |
|
591 } |
|
592 |
|
593 return NULL; |
|
594 } |
|
595 |
|
596 /** Gets the element at the given index. |
|
597 @param aIndex The index of the control |
|
598 @return The control and its id |
|
599 */ |
|
600 EXPORT_C TCoeControlWithId CCoeControlArray::At(TInt aIndex) |
|
601 { |
|
602 return iControls[aIndex]; |
|
603 } |
|
604 |
|
605 /** Gets the element at the given index. |
|
606 @param aIndex The index of the control |
|
607 @return The control and its id |
|
608 */ |
|
609 EXPORT_C const TCoeControlWithId CCoeControlArray::At(TInt aIndex) const |
|
610 { |
|
611 return iControls[aIndex]; |
|
612 } |
|
613 |
|
614 /** Gets the id of the control. |
|
615 @param aControl The control |
|
616 @return The id of the control or KErrNotFound if the control can't be found. |
|
617 */ |
|
618 EXPORT_C TInt CCoeControlArray::Id(const CCoeControl& aControl) const |
|
619 { |
|
620 for(TInt i = 0; i < iControls.Count(); i++) |
|
621 { |
|
622 if(iControls[i].iControl == &aControl) |
|
623 return iControls[i].iId; |
|
624 } |
|
625 |
|
626 return KErrNotFound; |
|
627 } |
|
628 |
|
629 /** Replaces a control in the array with another control. |
|
630 |
|
631 @param aOriginalControl The control that must be replaced |
|
632 @param aNewControl The new control |
|
633 @return A standard error code |
|
634 */ |
|
635 EXPORT_C TInt CCoeControlArray::Replace(CCoeControl* aOriginalControl, CCoeControl* aNewControl) |
|
636 { |
|
637 __ASSERT_DEBUG(this, Panic(ECoePanicNonExistentArray)); |
|
638 for(TInt i = 0; i < iControls.Count(); i++) |
|
639 { |
|
640 if(iControls[i].iControl == aOriginalControl) |
|
641 { |
|
642 iControls[i].iControl = aNewControl; |
|
643 return KErrNone; |
|
644 } |
|
645 } |
|
646 |
|
647 return KErrNotFound; |
|
648 } |
|
649 |
|
650 /** Gets the control with the given id or NULL if there is no control with the given id. |
|
651 @param aControlId The id of the control |
|
652 @return The control with the given id or null. |
|
653 */ |
|
654 EXPORT_C CCoeControl* CCoeControlArray::CtrlById(TInt aControlId) const |
|
655 { |
|
656 const TInt index = IndexById(aControlId); |
|
657 return (index != KErrNotFound ? iControls[index].iControl : NULL); |
|
658 } |
|
659 |
|
660 /** Gets the index of the control with the given id or KErrNotFound if there is no control that has |
|
661 that id. |
|
662 @param aControlId The id of the control |
|
663 @return The index of the control with the given id or KErrNotFound. |
|
664 */ |
|
665 TInt CCoeControlArray::IndexById(TInt aControlId) const |
|
666 { |
|
667 if(aControlId == KErrNotFound) |
|
668 return KErrNotFound; |
|
669 |
|
670 const TInt index = iControls.Find(TCoeControlWithId(aControlId)); |
|
671 return index; |
|
672 } |