appfw/apparchitecture/apgrfx/APGCTL.CPP
changeset 0 2e3d3ce01487
equal deleted inserted replaced
-1:000000000000 0:2e3d3ce01487
       
     1 // Copyright (c) 1997-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 <e32uid.h>
       
    17 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    18 #if !defined(__APGCTL_LIST_H__)
       
    19 #include "apgctllist.h"
       
    20 #endif
       
    21 #endif //SYMBIAN_ENABLE_SPLIT_HEADERS
       
    22 #include "APGCTL.H"
       
    23 #include "APGICNFL.H" 
       
    24 #include "APGSTD.H" 
       
    25 #include "APFDEF.H"
       
    26 #include "../apparc/TRACE.H"
       
    27 #include "APGCLI.H"
       
    28 #include "APACMDLN.H"
       
    29 
       
    30 //
       
    31 // CApaSystemControl
       
    32 //
       
    33 
       
    34 CApaSystemControl* CApaSystemControl::NewL(RFs& aFs,const TDesC& aFullPath,const TUidType aUidType)
       
    35 	{
       
    36 	CApaSystemControl* self=new(ELeave) CApaSystemControl(aFs);
       
    37 	CleanupStack::PushL(self);
       
    38 	self->ConstructL(aFullPath,aUidType);
       
    39 	CleanupStack::Pop();
       
    40 	return self;
       
    41 	}
       
    42 
       
    43 CApaSystemControl::CApaSystemControl(RFs& aFs)
       
    44 	:iExists(ETrue),
       
    45 	 iFs(aFs)
       
    46 	{}
       
    47 
       
    48 
       
    49 CApaSystemControl::~CApaSystemControl()
       
    50 	{
       
    51 	delete iCaption;
       
    52 	delete iShortCaption;
       
    53 	delete iIcon;
       
    54 	iNext = NULL;
       
    55 	}
       
    56 
       
    57 void CApaSystemControl::ConstructL(const TDesC& aFullPath,const TUidType aUidType)
       
    58 	{
       
    59 	//
       
    60 	// check the file type
       
    61 	if (aUidType[1]!=KUidApp) 
       
    62 		User::Leave(KErrNotSupported);
       
    63 
       
    64 	iFullPath=aFullPath;
       
    65 	iUidType=aUidType;
       
    66 
       
    67 	//Construct the new style control panel application. 
       
    68 	RApaLsSession ls;
       
    69 	User::LeaveIfError(ls.Connect());
       
    70 	CleanupClosePushL(ls);
       
    71 	TApaAppInfo info;
       
    72 	if(ls.GetAppInfo(info, aUidType[2])==KErrNone && info.iCaption.Length()>0)
       
    73 		{
       
    74 		iCaption=info.iCaption.AllocL();
       
    75 		iShortCaption=iCaption->AllocL();
       
    76 		}
       
    77 	// get the icon for the application
       
    78 	CApaMaskedBitmap *icon=CApaMaskedBitmap::NewLC();
       
    79 	User::LeaveIfError(ls.GetAppIcon(aUidType[2], TSize(48,48), *icon));
       
    80 	CleanupStack::Pop(icon);
       
    81 	iIcon=icon;
       
    82 	CleanupStack::PopAndDestroy(&ls);
       
    83 
       
    84 	if (!iCaption)
       
    85 		{
       
    86 		TParsePtrC ptr(aFullPath);
       
    87 		iCaption = ptr.Name().AllocL();
       
    88 		iShortCaption = iCaption->AllocL();
       
    89 		}
       
    90 	}
       
    91 
       
    92 EXPORT_C void CApaSystemControl::CreateL()
       
    93 /*
       
    94 Connects to apparc server and ask the server to launch an application.
       
    95 */
       
    96 	{
       
    97 	RApaLsSession apparcsession;
       
    98 	User::LeaveIfError(apparcsession.Connect());
       
    99 	CleanupClosePushL(apparcsession);
       
   100 	TThreadId threadId;
       
   101 	CApaCommandLine *commandLine=CApaCommandLine::NewLC();
       
   102 	commandLine->SetExecutableNameL(iFullPath);
       
   103 	commandLine->SetCommandL(EApaCommandRunWithoutViews);
       
   104 	User::LeaveIfError(apparcsession.StartApp(*commandLine,threadId));
       
   105 	CleanupStack::PopAndDestroy(2,&apparcsession);
       
   106 		
       
   107 	//To preserve the existing synchronous behaviour of control panel items
       
   108 	//we logon to the newly started control panel thread and wait
       
   109 	//till it exits.
       
   110 	RThread thread;
       
   111 	User::LeaveIfError(thread.Open(threadId,EOwnerThread));
       
   112 	TRequestStatus status;
       
   113 	thread.Logon(status);
       
   114 	User::WaitForRequest(status);
       
   115 	thread.Close();
       
   116 	} //lint !e1762 Member function could be made const - Lint is wrong, it should not be const
       
   117 
       
   118 EXPORT_C TUid CApaSystemControl::Type()const
       
   119 /** Gets the UID that uniquely identifies the control.
       
   120 
       
   121 @return The UID. */
       
   122 	{
       
   123 	return iUidType[2];
       
   124 	}
       
   125 
       
   126 EXPORT_C TFileName CApaSystemControl::FileName()const
       
   127 /** Gets the full path name of the control. 
       
   128 
       
   129 @return The full path name. */
       
   130 	{
       
   131 	return iFullPath;
       
   132 	}
       
   133 
       
   134 EXPORT_C CApaMaskedBitmap* CApaSystemControl::Icon()const
       
   135 /** Gets the control's icon.
       
   136 
       
   137 @return The icon bitmap. */
       
   138 	{
       
   139 	return iIcon;
       
   140 	}
       
   141 
       
   142 EXPORT_C TPtrC CApaSystemControl::Caption()const
       
   143 /** Gets the control's caption.
       
   144 
       
   145 @return A non-modifiable pointer descriptor representing the control's caption. */
       
   146 	{
       
   147 	__ASSERT_DEBUG(iCaption,Panic(EDPanicNoCaptionInControl));
       
   148 	return *iCaption;
       
   149 	}
       
   150 
       
   151 
       
   152 EXPORT_C TPtrC CApaSystemControl::ShortCaption()const
       
   153 /** Gets the control's short caption.
       
   154 
       
   155 @return A non-modifiable pointer descriptor representing the control's short 
       
   156 caption. */
       
   157 	{
       
   158 	__ASSERT_DEBUG(iCaption,Panic(EDPanicNoCaptionInControl));
       
   159 	if (iShortCaption)
       
   160 		return *iShortCaption;
       
   161 	else
       
   162 		return *iCaption;
       
   163 	}
       
   164 
       
   165 //
       
   166 // CApaSystemControlList
       
   167 //
       
   168 
       
   169 EXPORT_C CApaSystemControlList* CApaSystemControlList::NewL(RFs& aFs)
       
   170 /** Allocates and constructs a control panel application list. After construction, 
       
   171 it calls UpdateL(), to initialise the list.
       
   172 
       
   173 @param aFs Handle to a file server session.
       
   174 @return	The newly created control panel application list. */
       
   175 	{
       
   176 	CApaSystemControlList* self=new(ELeave) CApaSystemControlList(aFs);
       
   177 	CleanupStack::PushL(self);
       
   178 	self->UpdateL();
       
   179 	CleanupStack::Pop(self);
       
   180 	return self;
       
   181 	}
       
   182 
       
   183 EXPORT_C CApaSystemControlList::~CApaSystemControlList()
       
   184 /** Destructor. */
       
   185 	{
       
   186 	CApaSystemControl* control=iControl;
       
   187 	CApaSystemControl* next;
       
   188 	while (control)
       
   189 		{
       
   190 		next = control->iNext;
       
   191 		delete control;
       
   192 		control = next;
       
   193 		}
       
   194 	iControl = NULL;
       
   195 	}
       
   196 
       
   197 EXPORT_C TInt CApaSystemControlList::Count()const
       
   198 /** Gets the number of control panel applications in the list.
       
   199 
       
   200 @return The number of control panel applications in the list. */
       
   201 	{
       
   202 	TInt count=0;
       
   203 	CApaSystemControl* control=iControl;
       
   204 	while (control)
       
   205 		{
       
   206 		count++;
       
   207 		control = control->iNext;
       
   208 		}
       
   209 	return count;
       
   210 	}
       
   211 
       
   212 
       
   213 EXPORT_C TInt CApaSystemControlList::Index(TUid aType)const
       
   214 /** Gets the index into the list of the control panel application 
       
   215 whose third UID matches the specified UID.
       
   216 
       
   217 @param aType The control panel application specific UID.
       
   218 @return The index of the control panel application if there is a 
       
   219 match, or KErrNotFound if not. */
       
   220 	{
       
   221 	TInt count=0;
       
   222 	CApaSystemControl* control=iControl;
       
   223 	while (control && control->Type()!=aType)
       
   224 		{
       
   225 		count++;
       
   226 		control = control->iNext;
       
   227 		}
       
   228 	if (!control)
       
   229 		count = KErrNotFound;
       
   230 	return count;
       
   231 	}
       
   232 
       
   233 
       
   234 EXPORT_C CApaSystemControl* CApaSystemControlList::Control(TInt aIndex)const
       
   235 /** Gets the control panel application at the specified index in the list.
       
   236 
       
   237 @param aIndex Index of a control panel application in the list. 
       
   238 @return The control panel application at the specified index in the list.
       
   239 @panic APGRFX 10. The index is out of range. */
       
   240 
       
   241 	{
       
   242 	TInt count=0;
       
   243 	CApaSystemControl* control=iControl;
       
   244 	while (control && count!=aIndex)
       
   245 		{
       
   246 		count++;
       
   247 		control = control->iNext;
       
   248 		}
       
   249 	//
       
   250 	__ASSERT_ALWAYS(control,Panic(EPanicIndexOutOfRange));
       
   251 	return control;
       
   252 	}
       
   253 
       
   254 
       
   255 EXPORT_C CApaSystemControl* CApaSystemControlList::Control(TUid aType)const
       
   256 /** Gets the control panel application in the list with the specified UID. 
       
   257 
       
   258 @param aType The control panel applications third UID. 
       
   259 @return The control panel application whose type matches aType, or null 
       
   260 if none match. */
       
   261 
       
   262 	{
       
   263 	CApaSystemControl* control=iControl;
       
   264 	while (control && control->Type()!=aType)
       
   265 		control = control->iNext;
       
   266 	return control;
       
   267 	}
       
   268 
       
   269 
       
   270 CApaSystemControl* CApaSystemControlList::PreviousControl(const CApaSystemControl* aControl) const
       
   271 	{
       
   272 	CApaSystemControl* control=iControl;
       
   273 	CApaSystemControl* previous=NULL;
       
   274 	while (control && control!=aControl)
       
   275 		{
       
   276 		previous = control;
       
   277 		control = control->iNext;
       
   278 		}
       
   279 	if (!control)
       
   280 		previous = NULL;
       
   281 	return previous;
       
   282 	}
       
   283 
       
   284 
       
   285 EXPORT_C void CApaSystemControlList::UpdateL()
       
   286 /** Updates the list of control panel applications. For each new one found, a CApaSystemControl 
       
   287 object is created and added to the list. Control panel applications that no longer 
       
   288 exist are removed, and applications already in the list can be replaced 
       
   289 by ones found on earlier drives in the search order(y:->a: then z:). */
       
   290 
       
   291 // increments iUpdateCount if list has changed
       
   292 // if an error occurs, the list will not be complete but will be functional
       
   293  
       
   294 	{
       
   295 	__SHOW_TRACE(_L("Starting CApaSystemControlList::UpdateL()"));
       
   296 	// set all the current controls to "dont exist", so we can find them again
       
   297 	CApaSystemControl* control=iControl;
       
   298 	while (control)
       
   299 		{
       
   300 		control->iExists = EFalse;
       
   301 		control = control->iNext;
       
   302 		}
       
   303 
       
   304 	//Connect to the apparc server and get the control panel application. 
       
   305 	TBool listChanged=EFalse;
       
   306 	RApaLsSession apparcsession;
       
   307 	User::LeaveIfError(apparcsession.Connect());
       
   308 	CleanupClosePushL(apparcsession);
       
   309 	//Set the filter
       
   310 	User::LeaveIfError(apparcsession.GetFilteredApps(TApaAppCapability::EControlPanelItem,TApaAppCapability::EControlPanelItem));
       
   311 	
       
   312 	TApaAppInfo aInfo;
       
   313 	//Fetch the control panel information one by one and add a corresponding control
       
   314 	//to the control's list.
       
   315 	while(apparcsession.GetNextApp(aInfo) == KErrNone)
       
   316 		{
       
   317 		control=Control(aInfo.iUid);
       
   318 		if (control == NULL)
       
   319 			{// not in list, so add it at the start
       
   320 			__SHOW_TRACE(_L("...New control located"));
       
   321 			listChanged=ETrue;
       
   322 			TUidType uidType(KExecutableImageUid,KUidApp,aInfo.iUid);
       
   323 			TRAPD(err,control = CApaSystemControl::NewL(iFs,aInfo.iFullName,uidType));
       
   324 			if (err==KErrNone)
       
   325 				{
       
   326 				__SHOW_TRACE(_L("...control added"));
       
   327 				control->iNext = iControl;
       
   328 				iControl = control;
       
   329 				}
       
   330 			}
       
   331 		else if (!control->iExists)
       
   332 			{// not already found - we made need to override this one
       
   333 			if (aInfo.iFullName.CompareF(control->FileName()) != 0)
       
   334 				{
       
   335 				__SHOW_TRACE(_L("...new instance of control - delete old one"));
       
   336 				// delete the old one before creating the new one so that the correct library is loaded
       
   337 				CApaSystemControl* prev=PreviousControl(control);
       
   338 				if (prev)
       
   339 					{
       
   340 					prev->iNext=control->iNext;
       
   341 					}
       
   342 				else
       
   343 					{
       
   344 					iControl=control->iNext;
       
   345 					}
       
   346 				delete control;
       
   347 				control=NULL;
       
   348 				listChanged=ETrue;
       
   349 				// create the new one. Add it to the list if this is successful
       
   350 				__SHOW_TRACE(_L("...create new one"));
       
   351 				TUidType uidType(KExecutableImageUid,KUidApp,aInfo.iUid);
       
   352 				TRAPD(err,control = CApaSystemControl::NewL(iFs,aInfo.iFullName,uidType));
       
   353 				if (err==KErrNone)
       
   354 					{
       
   355 					__SHOW_TRACE(_L("...new one created"));
       
   356 					control->iNext=iControl;
       
   357 					iControl=control;
       
   358 					}
       
   359 				}
       
   360 			else
       
   361 				{
       
   362 				control->iExists=ETrue;
       
   363 				}
       
   364 			}
       
   365 		}
       
   366 		
       
   367 	CleanupStack::PopAndDestroy(&apparcsession); //apparcsession destroy
       
   368 
       
   369 	CApaSystemControl* previousControl=NULL;
       
   370 	control = iControl;
       
   371 	while (control)
       
   372 		{
       
   373 		if (!control->iExists)
       
   374 			{
       
   375 			listChanged=ETrue;
       
   376 			if (!previousControl)
       
   377 				{// this must be the first control in the list, ie iControl
       
   378 				iControl = control->iNext;
       
   379 				delete control;
       
   380 				control = iControl;
       
   381 				}
       
   382 			else
       
   383 				{
       
   384 				previousControl->iNext = control->iNext;
       
   385 				delete control;
       
   386 				previousControl = previousControl->iNext;
       
   387 				control = previousControl->iNext;
       
   388 				}
       
   389 			}
       
   390 		else
       
   391 			{
       
   392 			control = control->iNext;
       
   393 			}
       
   394 		}
       
   395 	//
       
   396 	// increment the counter if the list has changed
       
   397 	if (listChanged)
       
   398 		{
       
   399 		iUpdateCount++;
       
   400 		}
       
   401 	}
       
   402 
       
   403 CApaSystemControlList::CApaSystemControlList(RFs& aFs):iFs(aFs)
       
   404 	{
       
   405 	}
       
   406