lafagnosticuifoundation/cone/src/coecontrolarray.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     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 	}