|
1 /* |
|
2 * Copyright (c) 2002 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 "aknshortcuts.h" |
|
20 |
|
21 #include <AknPanic.h> |
|
22 #include <avkon.rsg> |
|
23 #include <eikbtgpc.h> |
|
24 #include <eikenv.h> |
|
25 #include <aknappui.h> |
|
26 #include <avkon.hrh> |
|
27 |
|
28 // The following are needed for template instantiations. aknlists.h |
|
29 // tells the compiler which shortcuttemplates to instantiate. |
|
30 #include <AknGrid.h> |
|
31 #include <aknlists.h> |
|
32 |
|
33 |
|
34 // |
|
35 // Shortcut behavior. |
|
36 // |
|
37 |
|
38 EXPORT_C void AknListBoxShortCuts::RunL() |
|
39 { |
|
40 TShortcutEvent event = EIdle; |
|
41 EndTimer(); |
|
42 ChangeStateL(event); |
|
43 DoProcedureL(); |
|
44 } |
|
45 |
|
46 EXPORT_C void AknListBoxShortCuts::ConstructL() |
|
47 { |
|
48 CTimer::ConstructL(); |
|
49 CActiveScheduler::Add(this); |
|
50 DoProcedureL(); |
|
51 } |
|
52 |
|
53 EXPORT_C AknListBoxShortCuts::AknListBoxShortCuts() |
|
54 : CTimer(EActivePriorityClockTimer), |
|
55 iCurrentTimerType(ENoTimeout), |
|
56 iState(EState1), |
|
57 iIdleNextState(EStateNone), |
|
58 iNaviKeyNextState(EStateNone), |
|
59 iNumKeyNextState(EStateNone), |
|
60 iLocked(EFalse) |
|
61 { } |
|
62 |
|
63 EXPORT_C TBool AknListBoxShortCuts::RecursionLock() |
|
64 { |
|
65 if (iLocked) return EFalse; |
|
66 iLocked = ETrue; |
|
67 return ETrue; |
|
68 } |
|
69 |
|
70 EXPORT_C void AknListBoxShortCuts::RecursionUnlock() |
|
71 { |
|
72 iLocked = EFalse; |
|
73 } |
|
74 |
|
75 // EndTimer() call must be in most derived class too -- we do not want timer events after destruction |
|
76 // of most derived class. |
|
77 EXPORT_C AknListBoxShortCuts::~AknListBoxShortCuts() { EndTimer(); } |
|
78 |
|
79 EXPORT_C TKeyResponse AknListBoxShortCuts::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode /*aType*/) |
|
80 { |
|
81 TShortcutEvent event=ENone; |
|
82 switch (aKeyEvent.iCode) |
|
83 { |
|
84 case EKeyDownArrow: |
|
85 case EKeyUpArrow: |
|
86 event = ENavi; |
|
87 break; |
|
88 case '0': |
|
89 case '1': |
|
90 case '2': |
|
91 case '3': |
|
92 case '4': |
|
93 case '5': |
|
94 case '6': |
|
95 case '7': |
|
96 case '8': |
|
97 case '9': |
|
98 case '*': |
|
99 case '#': |
|
100 event = ENumber; |
|
101 break; |
|
102 }; |
|
103 |
|
104 if (event == ENone) return EKeyWasNotConsumed; |
|
105 ChangeStateL(event); |
|
106 DoProcedureL(); |
|
107 return EKeyWasConsumed; |
|
108 } |
|
109 |
|
110 |
|
111 |
|
112 EXPORT_C void AknListBoxShortCuts::ChangeStateL(TShortcutEvent aEvent) |
|
113 { |
|
114 switch(aEvent) |
|
115 { |
|
116 case EIdle: |
|
117 iState = iIdleNextState; |
|
118 break; |
|
119 case ENavi: |
|
120 iState = iNaviKeyNextState; |
|
121 break; |
|
122 case ENumber: |
|
123 iState = iNumKeyNextState; |
|
124 break; |
|
125 case EStateToOne: |
|
126 EndTimer(); |
|
127 iState=EState1; |
|
128 iIdleNextState=EStateNone; |
|
129 iNaviKeyNextState=EStateNone; |
|
130 iNumKeyNextState=EStateNone; |
|
131 DoProcedureL(); |
|
132 break; |
|
133 case EStateToFive: |
|
134 iState = EState5; |
|
135 break; |
|
136 default: |
|
137 break; |
|
138 }; |
|
139 } |
|
140 |
|
141 EXPORT_C void AknListBoxShortCuts::EndTimer() |
|
142 { |
|
143 if (iCurrentTimerType == ENoTimeout) return; |
|
144 |
|
145 switch(iCurrentTimerType) |
|
146 { |
|
147 case EShortcutActiveTimeout: |
|
148 TRAP_IGNORE( |
|
149 DoActionL(EEnableSoftkeys) |
|
150 ); |
|
151 break; |
|
152 default: |
|
153 break; |
|
154 }; |
|
155 Cancel(); |
|
156 iCurrentTimerType = ENoTimeout; |
|
157 } |
|
158 EXPORT_C void AknListBoxShortCuts::StartTimerL(TShortcutTimerType aTimer) |
|
159 { |
|
160 TInt timeout = 0; |
|
161 EndTimer(); |
|
162 iCurrentTimerType = aTimer; |
|
163 |
|
164 switch(iCurrentTimerType) |
|
165 { |
|
166 case ENoUserActionTimeout: |
|
167 timeout = 20; |
|
168 break; |
|
169 case EIndexDisplayTimeout: |
|
170 timeout = 30; |
|
171 break; |
|
172 case EShortcutActiveTimeout: |
|
173 // Softkeys are disabled during shortcutactivetimeout. |
|
174 DoActionL(EDisableSoftkeys); |
|
175 timeout = 20; |
|
176 break; |
|
177 default: |
|
178 break; |
|
179 }; |
|
180 After(timeout); |
|
181 } |
|
182 |
|
183 EXPORT_C void AknListBoxShortCuts::DoProcedureL() |
|
184 { |
|
185 switch (iState) |
|
186 { |
|
187 case EState1: |
|
188 DoActionL(EBeginning); |
|
189 StartTimerL(ENoUserActionTimeout); |
|
190 iIdleNextState = EState2; |
|
191 iNaviKeyNextState = EState3; |
|
192 iNumKeyNextState = EState4; |
|
193 break; |
|
194 case EState2: // No action during ENoUserActionTimeout |
|
195 DoActionL(EAssertNotFetched); |
|
196 DoActionL(EShowShortcutNumber); |
|
197 StartTimerL(EIndexDisplayTimeout); |
|
198 iIdleNextState = EState2HideOnly; |
|
199 iNaviKeyNextState = EState2HideAndGoState3; |
|
200 iNumKeyNextState = EState2HideAndGoState4; |
|
201 break; |
|
202 case EState2HideOnly: |
|
203 DoActionL(EAssertNotFetched); |
|
204 DoActionL(EHideShortcutNumber); |
|
205 break; |
|
206 case EState2HideAndGoState3: |
|
207 DoActionL(EHideShortcutNumber); |
|
208 // FALL THROUGH |
|
209 case EState3: // Navigation keys |
|
210 DoActionL(EAssertNotFetched); |
|
211 DoActionL(EStoreFocusedItemPos); |
|
212 DoActionL(EForwardKeyEventToListBox); |
|
213 if (DoTest(ENewItemFocused)) |
|
214 { |
|
215 // We're at state 1 again. |
|
216 StartTimerL(ENoUserActionTimeout); |
|
217 iIdleNextState = EState2; |
|
218 iNaviKeyNextState = EState3; |
|
219 iNumKeyNextState = EState4; |
|
220 } |
|
221 break; |
|
222 case EState2HideAndGoState4: |
|
223 DoActionL(EHideShortcutNumber); |
|
224 // FALL THROUGH |
|
225 case EState4: // Numeric keys |
|
226 DoActionL(EAssertNotFetched); |
|
227 DoActionL(EAddKeyAsShortcutDigitAndMoveFocus); |
|
228 if (DoTest(ECheckForValidIndexNumber)) |
|
229 { |
|
230 StartTimerL(EShortcutActiveTimeout); |
|
231 iIdleNextState = EState5; |
|
232 iNumKeyNextState = EState6; |
|
233 iNaviKeyNextState = EState3; |
|
234 } |
|
235 break; |
|
236 case EState5: // After EshortcutActiveTimeout, user did nothing |
|
237 DoActionL(ESelectListBoxItem); |
|
238 ChangeStateL(EStateToOne); |
|
239 break; |
|
240 case EState6: // pressed 0-9 during shortcutactivetimeout |
|
241 DoActionL(EAddKeyAsShortcutDigitAndMoveFocus); |
|
242 if (DoTest(ECheckForValidIndexNumber)) |
|
243 { |
|
244 StartTimerL(EShortcutActiveTimeout); |
|
245 iIdleNextState = EState5; |
|
246 iNumKeyNextState = EState6; |
|
247 iNaviKeyNextState = EState3; |
|
248 } else { |
|
249 DoActionL(ERemoveKeyDigitFromIndexNumber); |
|
250 DoActionL(EPassDigitToNextList); |
|
251 DoActionL(ESelectListBoxItem); |
|
252 ChangeStateL(EStateToOne); |
|
253 |
|
254 } |
|
255 break; |
|
256 default: |
|
257 break; |
|
258 }; |
|
259 } |
|
260 |
|
261 |
|
262 |
|
263 EXPORT_C TInt AknListBoxShortCutsImplementation::ShortcutValueForNextList() |
|
264 { |
|
265 if (iStillNeedToFetchShortcutValue == EFalse) |
|
266 return 0; |
|
267 iStillNeedToFetchShortcutValue = EFalse; |
|
268 return iEvent.iCode; |
|
269 } |
|
270 |
|
271 /* valid values for aValue are 0 and '0' <= aValue <= '9'. Application does not need to know |
|
272 this - they just pass the interger from one list to another. */ |
|
273 EXPORT_C void AknListBoxShortCutsImplementation::SetShortcutValueFromPrevList(TInt /*aValue*/) |
|
274 { |
|
275 #if 0 |
|
276 if (aValue == 0) return; |
|
277 |
|
278 __ASSERT_DEBUG(aValue>=int('0') && aValue<=int('9'), Panic(EAknPanicListboxShortcutInvalidValue)); |
|
279 iEvent.iCode = aValue; |
|
280 TRAP_IGNORE( ChangeStateL(ENumber) ); // THIS MAY LEAVE |
|
281 TRAP_IGNORE( DoProcedureL() ); // THIS MAY LEAVE |
|
282 #endif |
|
283 } |
|
284 |
|
285 |
|
286 EXPORT_C TBool AknListBoxShortCutsImplementation::DoTest(TConcreteQuery q) |
|
287 { |
|
288 TInt focuspos; |
|
289 switch(q) |
|
290 { |
|
291 case ENewItemFocused: |
|
292 focuspos = iListBox->CurrentItemIndex(); |
|
293 if (iFocusItemPos == focuspos) return EFalse; |
|
294 return ETrue; |
|
295 |
|
296 case ECheckForValidIndexNumber: |
|
297 return iListBox->LastCharMatched(); |
|
298 |
|
299 default: |
|
300 break; |
|
301 }; |
|
302 return TRUE; |
|
303 } |
|
304 |
|
305 EXPORT_C AknListBoxShortCutsImplementation::AknListBoxShortCutsImplementation(CEikListBox* aListBox) |
|
306 : iListBox(aListBox) |
|
307 { |
|
308 iStillNeedToFetchShortcutValue = EFalse; |
|
309 } |
|
310 |
|
311 EXPORT_C AknListBoxShortCutsImplementation::~AknListBoxShortCutsImplementation() |
|
312 { |
|
313 EndTimer(); // This must be in most derived class too. |
|
314 delete iCba; |
|
315 } |
|
316 |
|
317 EXPORT_C void AknListBoxShortCutsImplementation::ConstructL() |
|
318 { |
|
319 AknListBoxShortCuts::ConstructL(); |
|
320 iListBox->CreateMatchBufferL(); |
|
321 } |
|
322 |
|
323 EXPORT_C void AknListBoxShortCutsImplementation::DoActionL(TConcreteShortcutActions a) |
|
324 { |
|
325 if (iListBox->Model()->NumberOfItems() == 0) |
|
326 return; |
|
327 |
|
328 TInt code = iEvent.iCode; |
|
329 switch(a) |
|
330 { |
|
331 case EStoreFocusedItemPos: |
|
332 // this is for use of ENewItemFocused |
|
333 iFocusItemPos = iListBox->CurrentItemIndex(); |
|
334 break; |
|
335 case EBeginning: |
|
336 iListBox->ClearMatchBuffer(); |
|
337 break; |
|
338 case EAddKeyAsShortcutDigitAndMoveFocus: |
|
339 iListBox->ClearMatchBuffer(); |
|
340 iListBox->MatchTypedCharL(code); |
|
341 break; |
|
342 case ERemoveKeyDigitFromIndexNumber: |
|
343 break; |
|
344 case EShowShortcutNumber: |
|
345 break; |
|
346 case EHideShortcutNumber: |
|
347 break; |
|
348 case EForwardKeyEventToListBox: |
|
349 iListBox->OfferKeyEventL(iEvent, iEventCode); |
|
350 break; |
|
351 case ESelectListBoxItem: |
|
352 iListBox->ReportListBoxEventL(MEikListBoxObserver::EEventEnterKeyPressed); |
|
353 break; |
|
354 case EPassDigitToNextList: |
|
355 break; |
|
356 case EDisableSoftkeys: |
|
357 // uses MEikCommandObserver (it should not do anything) |
|
358 #if 0 |
|
359 iCba = iAvkonAppUi->Cba(); |
|
360 iCba->AddCommandL(0, EAknSoftkeyDummyUsedWithShortcuts, _L(" ")); |
|
361 iCba->AddCommandL(1, EAknSoftkeyDummyUsedWithShortcuts, _L(" ")); |
|
362 #endif |
|
363 #if NOT_NEEDED_ANYMORE |
|
364 if (iCba) |
|
365 { |
|
366 delete iCba; |
|
367 iCba = NULL; |
|
368 } |
|
369 iCba = CEikButtonGroupContainer::NewL(CEikButtonGroupContainer::ECba, CEikButtonGroupContainer::EHorizontal, this, R_AVKON_SOFTKEYS_EMPTY, *iListBox); |
|
370 iCba->SetBoundingRect(TRect(TPoint(0,0),CEikonEnv::Static()->ScreenDevice()->SizeInPixels())); |
|
371 iCba->MinimumSize(); |
|
372 iCba->MakeVisible(ETrue); |
|
373 iListBox->UpdateScrollBarsL(); |
|
374 #endif |
|
375 break; |
|
376 case EEnableSoftkeys: |
|
377 #if 0 |
|
378 iCba = iAvkonAppUi->Cba(); |
|
379 iCba->RemoveCommandFromStack(0, EAknSoftkeyDummyUsedWithShortcuts); |
|
380 iCba->RemoveCommandFromStack(1, EAknSoftkeyDummyUsedWithShortcuts); |
|
381 #endif |
|
382 |
|
383 #if NOT_NEEDED_ANYMORE |
|
384 iCba->MakeVisible(EFalse); |
|
385 delete iCba; |
|
386 iCba = 0; |
|
387 iListBox->UpdateScrollBarsL(); |
|
388 #endif |
|
389 break; |
|
390 case EAssertNotFetched: |
|
391 break; |
|
392 default: |
|
393 break; |
|
394 }; |
|
395 } |
|
396 |
|
397 |
|
398 EXPORT_C void AknListBoxShortCutsImplementation::ProcessCommandL(TInt) |
|
399 { |
|
400 } |
|
401 |
|
402 EXPORT_C TKeyResponse AknListBoxShortCutsImplementation::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) |
|
403 { |
|
404 iEvent = aKeyEvent; |
|
405 iEventCode = aType; |
|
406 return AknListBoxShortCuts::OfferKeyEventL(aKeyEvent, aType); |
|
407 } |
|
408 |
|
409 // End of File |