|
1 /* |
|
2 * Copyright (c) 2002-2005 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: drop-down list control |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <peninputgeneralitutnew.rsg> |
|
20 #include <peninputitutconfig_chinese.rsg> |
|
21 #include <peninputdropdownlist.h> |
|
22 #include <coemain.h> |
|
23 #include <AknFepGlobalEnums.h> |
|
24 #include <PtiEngine.h> |
|
25 |
|
26 #include "peninputitutchnuistatepredict.h" |
|
27 #include "peninputgenericitutuimgrbase.h" |
|
28 #include "peninputgenericitutdatamgr.h" |
|
29 #include "peninputgenericitutlayoutcontext.h" |
|
30 #include "peninputgenericitutconverter.h" |
|
31 #include "peninputgenericitutwindowmanager.h" |
|
32 |
|
33 const TInt KInvalidIndex = -1; |
|
34 |
|
35 CChnItutUiStatePredict* CChnItutUiStatePredict::NewL(CGenericItutUiMgrBase* aOwner) |
|
36 { |
|
37 CChnItutUiStatePredict* self = new (ELeave) CChnItutUiStatePredict(aOwner); |
|
38 CleanupStack::PushL(self); |
|
39 self->ConstructL(); |
|
40 CleanupStack::Pop(self); |
|
41 return self; |
|
42 } |
|
43 |
|
44 CChnItutUiStatePredict::~CChnItutUiStatePredict() |
|
45 { |
|
46 } |
|
47 |
|
48 CChnItutUiStatePredict::CChnItutUiStatePredict(CGenericItutUiMgrBase* aOwner) |
|
49 :CGenericItutUiStateBase(aOwner), |
|
50 iLastOverlapIdx(KInvalidIndex) |
|
51 { |
|
52 } |
|
53 |
|
54 void CChnItutUiStatePredict::OnEntryL() |
|
55 { |
|
56 HBufC* puncText = NULL; |
|
57 switch (iOwner->DataMgr()->InputMode()) |
|
58 { |
|
59 case EPinyin: |
|
60 { |
|
61 iOwner->DataMgr()->NotifyChangeControlLayout( |
|
62 MItutPropertySubscriber::EItutPropertyKeypadResourceId, |
|
63 R_FINGER_INPUT_KEYPAD_PINYIN_STANDBY_PREDICT); |
|
64 puncText = CCoeEnv::Static()->AllocReadResourceL(R_ITUT_PUNC_PINYIN_ZHUYIN); |
|
65 } |
|
66 break; |
|
67 case EStroke: |
|
68 { |
|
69 TInt resID; |
|
70 if (iOwner->DataMgr()->InputLanguage() == ELangPrcChinese) |
|
71 { |
|
72 resID = R_FINGER_INPUT_KEYPAD_STROKE_STANDBY_PREDICT_PRC; |
|
73 } |
|
74 else |
|
75 { |
|
76 resID = R_FINGER_INPUT_KEYPAD_STROKE_STANDBY_PREDICT_TRA; |
|
77 } |
|
78 iOwner->DataMgr()->NotifyChangeControlLayout( |
|
79 MItutPropertySubscriber::EItutPropertyKeypadResourceId, |
|
80 resID); |
|
81 puncText = CCoeEnv::Static()->AllocReadResourceL(R_ITUT_PUNC_STROKE); |
|
82 } |
|
83 break; |
|
84 case EZhuyin: |
|
85 { |
|
86 iOwner->DataMgr()->NotifyChangeControlLayout( |
|
87 MItutPropertySubscriber::EItutPropertyKeypadResourceId, |
|
88 R_FINGER_INPUT_KEYPAD_ZHUYIN_STANDBY_PREDICT); |
|
89 puncText = CCoeEnv::Static()->AllocReadResourceL(R_ITUT_PUNC_PINYIN_ZHUYIN); |
|
90 } |
|
91 break; |
|
92 default: |
|
93 { |
|
94 // wrong input mode |
|
95 return; |
|
96 } |
|
97 } |
|
98 |
|
99 // show punc drop list, and set candidates to it |
|
100 CleanupStack::PushL( puncText ); |
|
101 CFepCtrlDropdownList* punclist = |
|
102 static_cast<CFepCtrlDropdownList*>(iOwner->LayoutContext()->Control(ECtrlIdPuncCandsList)); |
|
103 punclist->Hide(EFalse); |
|
104 |
|
105 iOwner->DataMgr()->ClearChnCandidates(EItutPuncCandidates); |
|
106 RPointerArray<HBufC>& punccandslist = |
|
107 TItutDataConverter::AnyToRptrArray(iOwner->DataMgr()->RequestData(EChnPuncCandidates)); |
|
108 TItutDataConverter::ConvertNonPhraseCandidateL(*puncText, punccandslist); |
|
109 |
|
110 punclist->SetCandidatesL(punccandslist, CFepCtrlDropdownList::EListNoExpandableWithBubble); |
|
111 CleanupStack::PopAndDestroy( puncText ); |
|
112 |
|
113 // show candidate drop list |
|
114 CFepCtrlDropdownList* candlist = |
|
115 static_cast<CFepCtrlDropdownList*>(iOwner->LayoutContext()->Control(ECtrlIdStdCandsList)); |
|
116 candlist->Hide(EFalse); |
|
117 |
|
118 // may need to change resource id of candidte list to predictive, change keypad resource id if need |
|
119 iOwner->DataMgr()->NotifyChangeControlLayout( |
|
120 MItutPropertySubscriber::EItutPropertyCandidateListResourceId, |
|
121 R_AKN_FEP_NORMAL_CAND_DROP_DOWN_LIST); |
|
122 |
|
123 |
|
124 //hide navi button |
|
125 iOwner->LayoutContext()->ShowArrowBtn(0); |
|
126 |
|
127 //hide indicator |
|
128 iOwner->LayoutContext()->Control(ECtrlIdIndicator)->Hide(ETrue); |
|
129 } |
|
130 |
|
131 void CChnItutUiStatePredict::OnExit() |
|
132 { |
|
133 // hide dropdownlist & reset its status |
|
134 CFepCtrlDropdownList* punclist = |
|
135 static_cast<CFepCtrlDropdownList*>(iOwner->LayoutContext()->Control(ECtrlIdPuncCandsList)); |
|
136 punclist->ResetAndClear(CFepCtrlDropdownList::EListNoExpandable); |
|
137 iOwner->DataMgr()->ClearChnCandidates(EItutPuncCandidates); |
|
138 punclist->Hide(ETrue); |
|
139 |
|
140 CFepCtrlDropdownList* candlist = |
|
141 static_cast<CFepCtrlDropdownList*>(iOwner->LayoutContext()->Control(ECtrlIdStdCandsList)); |
|
142 candlist->ResetAndClear(CFepCtrlDropdownList::EListExpandable); |
|
143 iOwner->DataMgr()->ClearChnCandidates(EItutCandidates); |
|
144 candlist->Hide(ETrue); |
|
145 |
|
146 //show navi button |
|
147 iOwner->LayoutContext()->ShowArrowBtn(EBtnArrowLeft | EBtnArrowRight |
|
148 | EBtnArrowUp| EBtnArrowDown); |
|
149 |
|
150 //show indicator |
|
151 iOwner->LayoutContext()->Control(ECtrlIdIndicator)->Hide(EFalse); |
|
152 |
|
153 } |
|
154 |
|
155 TBool CChnItutUiStatePredict::HandleKeyL(TInt aCmd, TInt aKey) |
|
156 { |
|
157 TInt immode = iOwner->DataMgr()->InputMode(); |
|
158 |
|
159 if (IsKeyValid(aKey)) |
|
160 { |
|
161 iOwner->SetNumLongPressValid(ETrue); |
|
162 iOwner->SetCurrentStateL(CGenericItutUiMgrBase::EStateComposition); |
|
163 iOwner->CurrentState()->HandleKeyL(aCmd, aKey); |
|
164 return ETrue; |
|
165 } |
|
166 return EFalse; |
|
167 } |
|
168 |
|
169 CGenericItutUiMgrBase::TUiState CChnItutUiStatePredict::StateType() |
|
170 { |
|
171 return CGenericItutUiMgrBase::EStatePredict; |
|
172 } |
|
173 |
|
174 TBool CChnItutUiStatePredict::IsKeyValid(TInt aKey) |
|
175 { |
|
176 TInt immode = iOwner->DataMgr()->InputMode(); |
|
177 |
|
178 return (immode == EPinyin && aKey >= EPtiKey2 && aKey <= EPtiKey9) || |
|
179 (immode == EStroke && aKey >= EPtiKey1 && aKey <= EPtiKey6) || |
|
180 (immode == EZhuyin && aKey >= EPtiKey0 && aKey <= EPtiKey9); |
|
181 } |
|
182 |
|
183 TBool CChnItutUiStatePredict::HandleCtrlEventL(TInt aEventType, |
|
184 CFepUiBaseCtrl* aCtrl, |
|
185 const TDesC& aEventData) |
|
186 { |
|
187 switch (aEventType) |
|
188 { |
|
189 case EItutCmdCandidateSelected: |
|
190 { |
|
191 TPtrC buf = aEventData.Left(aEventData.Length() - 1); |
|
192 |
|
193 if (aCtrl->ControlId() == ECtrlIdStdCandsList) |
|
194 { |
|
195 // if press cell on candidate list, set predictive candidates of it |
|
196 iOwner->DataMgr()->PtiEngine()->SetPredictiveChineseChar(buf); |
|
197 TPtrC cands = iOwner->DataMgr()->PtiEngine()->CandidatePage(); |
|
198 |
|
199 iOwner->DataMgr()->ClearChnCandidates(EItutCandidates); |
|
200 |
|
201 RPointerArray<HBufC>& candslist = TItutDataConverter::AnyToRptrArray( |
|
202 iOwner->DataMgr()->RequestData(EChnCandidates)); |
|
203 TItutDataConverter::ConvertChnPhraseCandidateL(cands, candslist); |
|
204 |
|
205 // remove duplicate punctuation from predict candidate |
|
206 RPointerArray<HBufC>& punccandslist = TItutDataConverter::AnyToRptrArray( |
|
207 iOwner->DataMgr()->RequestData(EChnPuncCandidates)); |
|
208 iLastOverlapIdx = RemoveDuplicateCand(punccandslist, |
|
209 candslist, |
|
210 0, |
|
211 0); |
|
212 |
|
213 CFepCtrlDropdownList* canddroplist = |
|
214 reinterpret_cast<CFepCtrlDropdownList*>(aCtrl); |
|
215 canddroplist->SetCandidatesL(candslist, CFepCtrlDropdownList::EListExpandableWithBubble); |
|
216 |
|
217 // input pressed candidate |
|
218 iOwner->LayoutContext()->SubmitText(buf); |
|
219 |
|
220 return ETrue; |
|
221 } |
|
222 else if (aCtrl->ControlId() == ECtrlIdPuncCandsList) |
|
223 { |
|
224 // if press cell on punc drop list, input it directly |
|
225 iOwner->LayoutContext()->SubmitText(buf); |
|
226 |
|
227 return ETrue; |
|
228 } |
|
229 } |
|
230 break; |
|
231 case EItutCmdGetNextCandidatePage: |
|
232 { |
|
233 if (aCtrl->ControlId() == ECtrlIdStdCandsList) |
|
234 { |
|
235 RPointerArray<HBufC>& candslist = TItutDataConverter::AnyToRptrArray( |
|
236 iOwner->DataMgr()->RequestData(EChnCandidates)); |
|
237 |
|
238 if (candslist.Count() >= KMaxPredictCandCnt) |
|
239 { |
|
240 return ETrue; |
|
241 } |
|
242 |
|
243 // original candidate count before fetch new candidate |
|
244 TInt candscnt = candslist.Count(); |
|
245 if (iOwner->DataMgr()->GetNextPageCandidateL(candslist) == KErrNone) |
|
246 { |
|
247 // remove duplicate punctuation from predict candidate |
|
248 RPointerArray<HBufC>& punccandslist = TItutDataConverter::AnyToRptrArray( |
|
249 iOwner->DataMgr()->RequestData(EChnPuncCandidates)); |
|
250 iLastOverlapIdx = RemoveDuplicateCand(punccandslist, |
|
251 candslist, |
|
252 iLastOverlapIdx + 1, |
|
253 candscnt); |
|
254 |
|
255 if (candslist.Count() >= KMaxPredictCandCnt) |
|
256 { |
|
257 candscnt = candslist.Count(); |
|
258 for (TInt i = KMaxPredictCandCnt; i < candscnt; i++) |
|
259 { |
|
260 delete candslist[KMaxPredictCandCnt]; |
|
261 candslist.Remove(KMaxPredictCandCnt); |
|
262 } |
|
263 } |
|
264 |
|
265 static_cast<CFepCtrlDropdownList*>(aCtrl)->AddCandidatesL(candslist); |
|
266 } |
|
267 |
|
268 return ETrue; |
|
269 } |
|
270 } |
|
271 break; |
|
272 case EItutCmdCandidateExisted: |
|
273 { |
|
274 if (aCtrl->ControlId() == ECtrlIdStdCandsList) |
|
275 { |
|
276 RPointerArray<HBufC>& candslist = TItutDataConverter::AnyToRptrArray( |
|
277 iOwner->DataMgr()->RequestData(EChnCandidates)); |
|
278 |
|
279 if (candslist.Count() >= KMaxPredictCandCnt) |
|
280 { |
|
281 static_cast<CFepCtrlDropdownList*>(aCtrl)->SetFlagCandidateExist(EFalse); |
|
282 } |
|
283 else |
|
284 { |
|
285 static_cast<CFepCtrlDropdownList*>(aCtrl)->SetFlagCandidateExist( |
|
286 iOwner->DataMgr()->NextPageCandidateExist()); |
|
287 } |
|
288 |
|
289 return ETrue; |
|
290 } |
|
291 } |
|
292 break; |
|
293 case EEventControlFocusGained: |
|
294 { |
|
295 if (aCtrl->ControlId() == ECtrlIdICF) |
|
296 { |
|
297 iOwner->SetCurrentStateL(CGenericItutUiMgrBase::EStateStandby); |
|
298 |
|
299 // ui layout may also need to handle this event |
|
300 return EFalse; |
|
301 } |
|
302 } |
|
303 break; |
|
304 case EEventIcfPointerUpEvent: |
|
305 { |
|
306 if (aCtrl->ControlId() == ECtrlIdICF) |
|
307 { |
|
308 iOwner->SetCurrentStateL(CGenericItutUiMgrBase::EStateStandby); |
|
309 |
|
310 // ui layout may also need to handle this event |
|
311 return ETrue; |
|
312 } |
|
313 } |
|
314 break; |
|
315 case EEventRawKeyDownEvent: |
|
316 { |
|
317 TInt immode = iOwner->DataMgr()->InputMode(); |
|
318 const TKeyEvent *key = reinterpret_cast<const TKeyEvent*>(aEventData.Ptr()); |
|
319 if ( ( immode == EPinyin && |
|
320 ( key->iScanCode == EPtiKey0 || key->iScanCode == EPtiKey1 || key->iScanCode == EPtiKeyStar ) ) || |
|
321 ( immode == EStroke && |
|
322 ( key->iScanCode == EPtiKeyStar || key->iScanCode == EPtiKey0 || (key->iScanCode >= EPtiKey7 && key->iScanCode <= EPtiKey9 ))) || |
|
323 ( immode == EZhuyin && key->iScanCode == EPtiKeyStar) || |
|
324 ( key->iScanCode == EStdKeyBackspace)) |
|
325 { |
|
326 // For those special keys, simulate down key immedidately. |
|
327 // to ensure to simulate down key event before up key event |
|
328 iOwner->UiManager()->SimulateImmeRawEvent( key->iScanCode, TRawEvent::EKeyDown ); |
|
329 iOwner->UiManager()->SetLastRawKeyDown( key->iScanCode, ETrue, aCtrl ); |
|
330 return ETrue; |
|
331 } |
|
332 } |
|
333 break; |
|
334 case EEventRawKeyUpEvent: |
|
335 { |
|
336 TInt immode = iOwner->DataMgr()->InputMode(); |
|
337 const TKeyEvent *key = reinterpret_cast<const TKeyEvent*>(aEventData.Ptr()); |
|
338 if ( ( immode == EPinyin && |
|
339 ( key->iScanCode == EPtiKey0 || key->iScanCode == EPtiKey1 || key->iScanCode == EPtiKeyStar ) ) || |
|
340 ( immode == EStroke && |
|
341 ( key->iScanCode == EPtiKeyStar || key->iScanCode == EPtiKey0 || (key->iScanCode >= EPtiKey7 && key->iScanCode <= EPtiKey9 ))) || |
|
342 ( immode == EZhuyin && key->iScanCode == EPtiKeyStar) || |
|
343 ( key->iScanCode == EStdKeyBackspace)) |
|
344 { |
|
345 // For those special keys, simulate up key events immediately before changing state. |
|
346 // The action can avoid up key event being delayed by running changing state, |
|
347 // otherwise, short press will be thought as long press by window server. |
|
348 iOwner->UiManager()->SimulateImmeRawEvent( key->iScanCode, TRawEvent::EKeyUp ); |
|
349 iOwner->UiManager()->SetLastRawKeyDown( key->iScanCode, EFalse, aCtrl ); |
|
350 iOwner->SetCurrentStateL( CGenericItutUiMgrBase::EStateStandby ); |
|
351 return ETrue; |
|
352 } |
|
353 } |
|
354 break; |
|
355 default: |
|
356 break; |
|
357 } |
|
358 |
|
359 return EFalse; |
|
360 } |
|
361 |
|
362 TInt CChnItutUiStatePredict::RemoveDuplicateCand(const RPointerArray<HBufC>& aSrc, |
|
363 RPointerArray<HBufC>& aTgt, |
|
364 TInt aSrcStartIdx, |
|
365 TInt aTgtStartIdx) |
|
366 { |
|
367 TInt lastOverlapIdx = KInvalidIndex; |
|
368 |
|
369 // on the assumption that if candidate overlap, |
|
370 // it is overlap only once |
|
371 TInt srccandcnt = aSrc.Count(); |
|
372 |
|
373 for (TInt i = aSrcStartIdx; i < srccandcnt; i++) |
|
374 { |
|
375 for (TInt j = aTgtStartIdx; j < aTgt.Count(); j++) |
|
376 { |
|
377 if (aTgt[j]->Compare(*(aSrc[i])) == 0) |
|
378 { |
|
379 lastOverlapIdx = i; |
|
380 delete aTgt[j]; |
|
381 aTgt.Remove(j); |
|
382 j--; |
|
383 break; |
|
384 } |
|
385 } |
|
386 } |
|
387 |
|
388 return lastOverlapIdx; |
|
389 } |
|
390 |
|
391 // End Of File |