|
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 |