|
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 |
|
125 void CChnItutUiStatePredict::OnExit() |
|
126 { |
|
127 // hide dropdownlist & reset its status |
|
128 CFepCtrlDropdownList* punclist = |
|
129 static_cast<CFepCtrlDropdownList*>(iOwner->LayoutContext()->Control(ECtrlIdPuncCandsList)); |
|
130 punclist->ResetAndClear(CFepCtrlDropdownList::EListNoExpandable); |
|
131 iOwner->DataMgr()->ClearChnCandidates(EItutPuncCandidates); |
|
132 punclist->Hide(ETrue); |
|
133 |
|
134 CFepCtrlDropdownList* candlist = |
|
135 static_cast<CFepCtrlDropdownList*>(iOwner->LayoutContext()->Control(ECtrlIdStdCandsList)); |
|
136 candlist->ResetAndClear(CFepCtrlDropdownList::EListExpandable); |
|
137 iOwner->DataMgr()->ClearChnCandidates(EItutCandidates); |
|
138 candlist->Hide(ETrue); |
|
139 |
|
140 //show indicator |
|
141 iOwner->LayoutContext()->Control(ECtrlIdIndicator)->Hide(EFalse); |
|
142 |
|
143 // Hide ICF, Backspace, Arrow contrls when exit to avoid flick |
|
144 //iOwner->LayoutContext()->Control(ECtrlIdICF)->Hide( ETrue ); |
|
145 //iOwner->LayoutContext()->Control(ECtrlIdBackspace)->Hide(ETrue); |
|
146 //iOwner->LayoutContext()->ShowArrowBtn(0); |
|
147 |
|
148 } |
|
149 |
|
150 TBool CChnItutUiStatePredict::HandleKeyL(TInt aCmd, TInt aKey) |
|
151 { |
|
152 TInt immode = iOwner->DataMgr()->InputMode(); |
|
153 |
|
154 if (IsKeyValid(aKey)) |
|
155 { |
|
156 iOwner->SetNumLongPressValid(ETrue); |
|
157 iOwner->SetCurrentStateL(CGenericItutUiMgrBase::EStateComposition); |
|
158 iOwner->CurrentState()->HandleKeyL(aCmd, aKey); |
|
159 return ETrue; |
|
160 } |
|
161 return EFalse; |
|
162 } |
|
163 |
|
164 CGenericItutUiMgrBase::TUiState CChnItutUiStatePredict::StateType() |
|
165 { |
|
166 return CGenericItutUiMgrBase::EStatePredict; |
|
167 } |
|
168 |
|
169 TBool CChnItutUiStatePredict::IsKeyValid(TInt aKey) |
|
170 { |
|
171 TInt immode = iOwner->DataMgr()->InputMode(); |
|
172 |
|
173 return (immode == EPinyin && aKey >= EPtiKey2 && aKey <= EPtiKey9) || |
|
174 (immode == EStroke && aKey >= EPtiKey1 && aKey <= EPtiKey6) || |
|
175 (immode == EZhuyin && aKey >= EPtiKey0 && aKey <= EPtiKey9); |
|
176 } |
|
177 |
|
178 TBool CChnItutUiStatePredict::HandleCtrlEventL(TInt aEventType, |
|
179 CFepUiBaseCtrl* aCtrl, |
|
180 const TDesC& aEventData) |
|
181 { |
|
182 switch (aEventType) |
|
183 { |
|
184 case EItutCmdCandidateSelected: |
|
185 { |
|
186 TPtrC buf = aEventData.Left(aEventData.Length() - 1); |
|
187 |
|
188 if (aCtrl->ControlId() == ECtrlIdStdCandsList) |
|
189 { |
|
190 // if press cell on candidate list, set predictive candidates of it |
|
191 iOwner->DataMgr()->PtiEngine()->SetPredictiveChineseChar(buf); |
|
192 TPtrC cands = iOwner->DataMgr()->PtiEngine()->CandidatePage(); |
|
193 |
|
194 iOwner->DataMgr()->ClearChnCandidates(EItutCandidates); |
|
195 |
|
196 RPointerArray<HBufC>& candslist = TItutDataConverter::AnyToRptrArray( |
|
197 iOwner->DataMgr()->RequestData(EChnCandidates)); |
|
198 TItutDataConverter::ConvertChnPhraseCandidateL(cands, candslist); |
|
199 |
|
200 // remove duplicate punctuation from predict candidate |
|
201 RPointerArray<HBufC>& punccandslist = TItutDataConverter::AnyToRptrArray( |
|
202 iOwner->DataMgr()->RequestData(EChnPuncCandidates)); |
|
203 iLastOverlapIdx = RemoveDuplicateCand(punccandslist, |
|
204 candslist, |
|
205 0, |
|
206 0); |
|
207 |
|
208 CFepCtrlDropdownList* canddroplist = |
|
209 reinterpret_cast<CFepCtrlDropdownList*>(aCtrl); |
|
210 canddroplist->SetCandidatesL(candslist, CFepCtrlDropdownList::EListExpandableWithBubble); |
|
211 |
|
212 // input pressed candidate |
|
213 iOwner->LayoutContext()->SubmitText(buf); |
|
214 |
|
215 return ETrue; |
|
216 } |
|
217 else if (aCtrl->ControlId() == ECtrlIdPuncCandsList) |
|
218 { |
|
219 // if press cell on punc drop list, input it directly |
|
220 iOwner->LayoutContext()->SubmitText(buf); |
|
221 |
|
222 return ETrue; |
|
223 } |
|
224 } |
|
225 break; |
|
226 case EItutCmdGetNextCandidatePage: |
|
227 { |
|
228 if (aCtrl->ControlId() == ECtrlIdStdCandsList) |
|
229 { |
|
230 RPointerArray<HBufC>& candslist = TItutDataConverter::AnyToRptrArray( |
|
231 iOwner->DataMgr()->RequestData(EChnCandidates)); |
|
232 |
|
233 if (candslist.Count() >= KMaxPredictCandCnt) |
|
234 { |
|
235 return ETrue; |
|
236 } |
|
237 |
|
238 // original candidate count before fetch new candidate |
|
239 TInt candscnt = candslist.Count(); |
|
240 if (iOwner->DataMgr()->GetNextPageCandidateL(candslist) == KErrNone) |
|
241 { |
|
242 // remove duplicate punctuation from predict candidate |
|
243 RPointerArray<HBufC>& punccandslist = TItutDataConverter::AnyToRptrArray( |
|
244 iOwner->DataMgr()->RequestData(EChnPuncCandidates)); |
|
245 iLastOverlapIdx = RemoveDuplicateCand(punccandslist, |
|
246 candslist, |
|
247 iLastOverlapIdx + 1, |
|
248 candscnt); |
|
249 |
|
250 if (candslist.Count() >= KMaxPredictCandCnt) |
|
251 { |
|
252 candscnt = candslist.Count(); |
|
253 for (TInt i = KMaxPredictCandCnt; i < candscnt; i++) |
|
254 { |
|
255 delete candslist[KMaxPredictCandCnt]; |
|
256 candslist.Remove(KMaxPredictCandCnt); |
|
257 } |
|
258 } |
|
259 |
|
260 static_cast<CFepCtrlDropdownList*>(aCtrl)->AddCandidatesL(candslist); |
|
261 } |
|
262 |
|
263 return ETrue; |
|
264 } |
|
265 } |
|
266 break; |
|
267 case EItutCmdCandidateExisted: |
|
268 { |
|
269 if (aCtrl->ControlId() == ECtrlIdStdCandsList) |
|
270 { |
|
271 RPointerArray<HBufC>& candslist = TItutDataConverter::AnyToRptrArray( |
|
272 iOwner->DataMgr()->RequestData(EChnCandidates)); |
|
273 |
|
274 if (candslist.Count() >= KMaxPredictCandCnt) |
|
275 { |
|
276 static_cast<CFepCtrlDropdownList*>(aCtrl)->SetFlagCandidateExist(EFalse); |
|
277 } |
|
278 else |
|
279 { |
|
280 static_cast<CFepCtrlDropdownList*>(aCtrl)->SetFlagCandidateExist( |
|
281 iOwner->DataMgr()->NextPageCandidateExist()); |
|
282 } |
|
283 |
|
284 return ETrue; |
|
285 } |
|
286 } |
|
287 break; |
|
288 case EEventControlFocusGained: |
|
289 { |
|
290 if (aCtrl->ControlId() == ECtrlIdICF) |
|
291 { |
|
292 iOwner->SetCurrentStateL(CGenericItutUiMgrBase::EStateStandby); |
|
293 |
|
294 // ui layout may also need to handle this event |
|
295 return EFalse; |
|
296 } |
|
297 } |
|
298 break; |
|
299 case EEventIcfPointerUpEvent: |
|
300 { |
|
301 if (aCtrl->ControlId() == ECtrlIdICF) |
|
302 { |
|
303 iOwner->SetCurrentStateL(CGenericItutUiMgrBase::EStateStandby); |
|
304 |
|
305 // ui layout may also need to handle this event |
|
306 return ETrue; |
|
307 } |
|
308 } |
|
309 break; |
|
310 case EEventRawKeyDownEvent: |
|
311 { |
|
312 |
|
313 if ( iOwner->UiManager()->IsAllowHandleRawKeyEvent()) |
|
314 { |
|
315 TInt immode = iOwner->DataMgr()->InputMode(); |
|
316 const TKeyEvent *key = reinterpret_cast<const TKeyEvent*>(aEventData.Ptr()); |
|
317 if ( ( immode == EPinyin && |
|
318 ( key->iScanCode == EPtiKey0 || key->iScanCode == EPtiKey1 || key->iScanCode == EPtiKeyStar ) ) || |
|
319 ( immode == EStroke && |
|
320 ( key->iScanCode == EPtiKeyStar || key->iScanCode == EPtiKey0 || (key->iScanCode >= EPtiKey7 && key->iScanCode <= EPtiKey9 ))) || |
|
321 ( immode == EZhuyin && key->iScanCode == EPtiKeyStar) || |
|
322 ( key->iScanCode == EStdKeyBackspace)) |
|
323 { |
|
324 // For those special keys, simulate down key immedidately. |
|
325 // to ensure to simulate down key event before up key event |
|
326 iOwner->UiManager()->SimulateImmeRawEvent( key->iScanCode, TRawEvent::EKeyDown ); |
|
327 iOwner->UiManager()->SetLastRawKeyDown( key->iScanCode, ETrue, aCtrl ); |
|
328 return ETrue; |
|
329 } |
|
330 } |
|
331 } |
|
332 break; |
|
333 case EEventRawKeyUpEvent: |
|
334 { |
|
335 if ( iOwner->UiManager()->IsAllowHandleRawKeyEvent()) |
|
336 { |
|
337 TInt immode = iOwner->DataMgr()->InputMode(); |
|
338 const TKeyEvent *key = reinterpret_cast<const TKeyEvent*>(aEventData.Ptr()); |
|
339 if ( ( immode == EPinyin && |
|
340 ( key->iScanCode == EPtiKey0 || key->iScanCode == EPtiKey1 || key->iScanCode == EPtiKeyStar ) ) || |
|
341 ( immode == EStroke && |
|
342 ( key->iScanCode == EPtiKeyStar || key->iScanCode == EPtiKey0 || (key->iScanCode >= EPtiKey7 && key->iScanCode <= EPtiKey9 ))) || |
|
343 ( immode == EZhuyin && key->iScanCode == EPtiKeyStar) || |
|
344 ( key->iScanCode == EStdKeyBackspace)) |
|
345 { |
|
346 // For those special keys, simulate up key events immediately before changing state. |
|
347 // The action can avoid up key event being delayed by running changing state, |
|
348 // otherwise, short press will be thought as long press by window server. |
|
349 iOwner->UiManager()->SimulateImmeRawEvent( key->iScanCode, TRawEvent::EKeyUp ); |
|
350 iOwner->UiManager()->SetLastRawKeyDown( key->iScanCode, EFalse, aCtrl ); |
|
351 iOwner->SetCurrentStateL( CGenericItutUiMgrBase::EStateStandby ); |
|
352 return ETrue; |
|
353 } |
|
354 } |
|
355 } |
|
356 break; |
|
357 default: |
|
358 break; |
|
359 } |
|
360 |
|
361 return EFalse; |
|
362 } |
|
363 |
|
364 TInt CChnItutUiStatePredict::RemoveDuplicateCand(const RPointerArray<HBufC>& aSrc, |
|
365 RPointerArray<HBufC>& aTgt, |
|
366 TInt aSrcStartIdx, |
|
367 TInt aTgtStartIdx) |
|
368 { |
|
369 TInt lastOverlapIdx = KInvalidIndex; |
|
370 |
|
371 // on the assumption that if candidate overlap, |
|
372 // it is overlap only once |
|
373 TInt srccandcnt = aSrc.Count(); |
|
374 |
|
375 for (TInt i = aSrcStartIdx; i < srccandcnt; i++) |
|
376 { |
|
377 for (TInt j = aTgtStartIdx; j < aTgt.Count(); j++) |
|
378 { |
|
379 if (aTgt[j]->Compare(*(aSrc[i])) == 0) |
|
380 { |
|
381 lastOverlapIdx = i; |
|
382 delete aTgt[j]; |
|
383 aTgt.Remove(j); |
|
384 j--; |
|
385 break; |
|
386 } |
|
387 } |
|
388 } |
|
389 |
|
390 return lastOverlapIdx; |
|
391 } |
|
392 |
|
393 // End Of File |