|
1 /* |
|
2 * Copyright (c) 2009 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 * Defines a custom editor window for Text editor component. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INTERNAL INCLUDES |
|
20 #include "CMIDTextEditorEdwin.h" |
|
21 #include "CMIDEdwinUtils.h" |
|
22 #include "CMIDTextEditorEdwinCustomDraw.h" |
|
23 #include "CMIDEditingStateIndicator.h" |
|
24 #include "CMIDDisplayable.h" |
|
25 |
|
26 // EXTERNAL INCLUDES |
|
27 #include <MMIDTextEditor.h> // MMIDTextEditorObserver |
|
28 #include <aknextendedinputcapabilities.h> |
|
29 #include <AknSettingCache.h> |
|
30 #include <eikedwob.h> |
|
31 #include <j2me/jdebug.h> |
|
32 |
|
33 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
34 #include <AknPriv.hrh> |
|
35 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
36 |
|
37 const TInt KColorOpaque = 255; |
|
38 const TInt KCharMinus = 0x2d; |
|
39 |
|
40 // --------------------------------------------------------------------------- |
|
41 // CMIDTextEditorEdwin::CMIDTextEditorEdwin |
|
42 // --------------------------------------------------------------------------- |
|
43 // |
|
44 CMIDTextEditorEdwin::CMIDTextEditorEdwin(CMIDEdwinUtils& aEdwinUtils) |
|
45 : CEikEdwin(), |
|
46 iMultiline(EFalse), |
|
47 iCursorPosForAction(KErrNotFound), |
|
48 iEdwinUtils(aEdwinUtils) |
|
49 { |
|
50 DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin +"); |
|
51 |
|
52 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
53 iPartialVKBOpen = EFalse; |
|
54 iDisplayable = NULL; |
|
55 iJavaAppUi = NULL; |
|
56 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
57 // Set margins to zero |
|
58 TMargins8 margins; |
|
59 margins.SetAllValuesTo(0); |
|
60 SetBorderViewMargins(margins); |
|
61 // Set layout |
|
62 CAknEnv::Static()->GetCurrentLayoutId(iDirection); |
|
63 // Set visible content height |
|
64 iVisibleContentHeight = 0; |
|
65 // Set border to zero |
|
66 SetBorder(TGulBorder::ENone); |
|
67 SetFocusing(ETrue); |
|
68 DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin -"); |
|
69 } |
|
70 |
|
71 // --------------------------------------------------------------------------- |
|
72 // CMIDTextEditorEdwin::~CMIDTextEditorEdwin |
|
73 // --------------------------------------------------------------------------- |
|
74 // |
|
75 CMIDTextEditorEdwin::~CMIDTextEditorEdwin() |
|
76 { |
|
77 DEBUG("CMIDTextEditorEdwin::~CMIDTextEditorEdwin"); |
|
78 } |
|
79 |
|
80 // --------------------------------------------------------------------------- |
|
81 // CMIDTextEditorEdwin::ConstructL |
|
82 // (other items were commented in the header file) |
|
83 // --------------------------------------------------------------------------- |
|
84 // |
|
85 void CMIDTextEditorEdwin::ConstructL( |
|
86 TInt aEdwinFlags, |
|
87 TInt aWidthInChars, |
|
88 TInt aTextLimit, |
|
89 TInt aNumberOfLines) |
|
90 { |
|
91 DEBUG("CMIDTextEditorEdwin::ConstructL +"); |
|
92 |
|
93 CEikEdwin::ConstructL( |
|
94 aEdwinFlags, aWidthInChars, aTextLimit, aNumberOfLines); |
|
95 |
|
96 // Supress all background drawing of CEikEdwin so that this editor |
|
97 // can draw the correct custom color to the background. |
|
98 SetSuppressBackgroundDrawing(ETrue); |
|
99 |
|
100 // No background control context. This way it is possible to change the |
|
101 // background color of the text editor. By default, it is white. |
|
102 SetSkinBackgroundControlContextL(NULL); |
|
103 |
|
104 // Observer events in the editor. Note that this must be done in order |
|
105 // to avoid resulting incorrect content in numeric and decimal editors |
|
106 SetEdwinObserver(this); |
|
107 |
|
108 // To have the line where cursor is properly displayed. |
|
109 if (iLayout) |
|
110 { |
|
111 iLayout->RestrictScrollToTopsOfLines(EFalse); |
|
112 } |
|
113 |
|
114 DEBUG("CMIDTextEditorEdwin::ConstructL -"); |
|
115 } |
|
116 |
|
117 // --------------------------------------------------------------------------- |
|
118 // CMIDTextEditorEdwin::OfferKeyEventL |
|
119 // (other items were commented in the header file) |
|
120 // --------------------------------------------------------------------------- |
|
121 // |
|
122 TKeyResponse CMIDTextEditorEdwin::OfferKeyEventL( |
|
123 const TKeyEvent& aKeyEvent, |
|
124 TEventCode aType) |
|
125 { |
|
126 DEBUG_INT("CMIDTextEditorEdwin::OfferKeyEventL +, aType=%d", aType); |
|
127 |
|
128 TKeyResponse response = EKeyWasNotConsumed; |
|
129 |
|
130 if ((aType == EEventKey) && |
|
131 (aKeyEvent.iCode == EKeyEnter) && |
|
132 (!iMultiline || |
|
133 iConstraints & MMIDTextField::EPassword || |
|
134 !IsConstraintSet(MMIDTextField::EAny))) |
|
135 { |
|
136 // Enter key for single-line editor, password and other than any |
|
137 // editors is simply passed on. |
|
138 DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -, ignoring enter"); |
|
139 |
|
140 return response; |
|
141 } |
|
142 |
|
143 // Offer key event to editor window if it is set focused and visible. |
|
144 // If the editor is set hidden, OfferKeyEventL will update the content |
|
145 // in the editor and draw it. So the editor content CANNOT be modified |
|
146 // if it is not visible and focused. |
|
147 if (IsFocused() && IsVisible()) |
|
148 { |
|
149 DEBUG("CMIDTextEditorEdwin::OfferKeyEventL, focused=true"); |
|
150 |
|
151 // Edwin does not report cursor movements with text updates |
|
152 // Store the current position here for future use. |
|
153 iCursorPosForAction = CursorPos(); |
|
154 |
|
155 // Try handling special characters. |
|
156 response = HandleSpecialKeyEventsL(aKeyEvent, aType); |
|
157 |
|
158 // Not handled, try with CEikEdwin |
|
159 // Consume down and up type of keyevents |
|
160 if ((response == EKeyWasConsumed) || |
|
161 (aType != EEventKey && aKeyEvent.iScanCode != |
|
162 EStdKeyApplication0)) |
|
163 { |
|
164 response = EKeyWasConsumed; |
|
165 } |
|
166 else |
|
167 { |
|
168 // Old text is needed if the new content is not valid for the |
|
169 // given set of constraints. This validation is made because |
|
170 // CEikEdwin and FEP seem to input text that is not always |
|
171 // valid for the given Java-specific constraints. No very |
|
172 // optimized solution to allocate heap here but at least this |
|
173 // solution is bulletproof and prevents illegal contents. |
|
174 // This also prevents that the implementation does not ignore |
|
175 // special characters such as navigation and hotkeys. |
|
176 HBufC* oldContent = GetTextInHBufL(); |
|
177 |
|
178 CleanupStack::PushL(oldContent); |
|
179 |
|
180 response = CEikEdwin::OfferKeyEventL(aKeyEvent, aType); |
|
181 |
|
182 if (response == EKeyWasConsumed) { |
|
183 // Validate new content and undo if not valid. |
|
184 if (!iEdwinUtils.ConstraintsValidForText( |
|
185 Read(), iConstraints, EFalse)) |
|
186 { |
|
187 CEikEdwin::SetTextL(oldContent); |
|
188 // Notify about text change. |
|
189 HandleTextChangedL(); |
|
190 // Restore cursor's original position. |
|
191 SetCursorPosL(iCursorPosForAction, EFalse); |
|
192 } |
|
193 } |
|
194 else |
|
195 { |
|
196 // Consuming the up/down arrows, because edwin does not |
|
197 // consume them if at first/last line. |
|
198 if ((aType == EEventKey) && |
|
199 (((aKeyEvent.iCode == EKeyUpArrow) || |
|
200 (aKeyEvent.iCode == EKeyDownArrow)) || |
|
201 ((aKeyEvent.iScanCode == EStdKeyUpArrow) || |
|
202 (aKeyEvent.iScanCode == EStdKeyDownArrow)))) |
|
203 { |
|
204 response = EKeyWasConsumed; |
|
205 } |
|
206 } |
|
207 CleanupStack::PopAndDestroy(oldContent); |
|
208 } |
|
209 |
|
210 // Update current selection. |
|
211 iSelection = Selection(); |
|
212 |
|
213 // Draw now so that background gets updated. Otherwise the |
|
214 // content may not be updated (e.g. cursor may be visible |
|
215 // if a line is deleted from the editor. |
|
216 // Transparency needs whole redraw of the editor's content. |
|
217 if (IsTransparent()) |
|
218 { |
|
219 iParent->DrawNow(Rect()); |
|
220 } |
|
221 else |
|
222 { |
|
223 DrawDeferred(); |
|
224 } |
|
225 } |
|
226 |
|
227 DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -"); |
|
228 |
|
229 return response; |
|
230 } |
|
231 |
|
232 // --------------------------------------------------------------------------- |
|
233 // CMIDTextEditorEdwin::Traverse |
|
234 // (other items were commented in the header file) |
|
235 // --------------------------------------------------------------------------- |
|
236 // |
|
237 TBool CMIDTextEditorEdwin::Traverse(const TKeyEvent& aEvent) |
|
238 { |
|
239 TInt cursorPos = 0; |
|
240 TBool traverse = EFalse; |
|
241 |
|
242 if ((aEvent.iCode == EKeyDownArrow) || |
|
243 (aEvent.iScanCode == EStdKeyDownArrow)) |
|
244 { |
|
245 cursorPos = CursorPos(); |
|
246 if (TextLength() == cursorPos) |
|
247 { |
|
248 traverse = ETrue; |
|
249 } |
|
250 |
|
251 } |
|
252 else if ((aEvent.iCode == EKeyUpArrow) || |
|
253 (aEvent.iScanCode == EStdKeyUpArrow)) |
|
254 { |
|
255 cursorPos = CursorPos(); |
|
256 if (cursorPos == 0) |
|
257 { |
|
258 traverse = ETrue; |
|
259 } |
|
260 |
|
261 } |
|
262 |
|
263 return traverse; |
|
264 } |
|
265 // --------------------------------------------------------------------------- |
|
266 // CMIDTextEditorEdwin::Draw |
|
267 // (other items were commented in the header file) |
|
268 // --------------------------------------------------------------------------- |
|
269 // |
|
270 void CMIDTextEditorEdwin::Draw(const TRect& aRect) const |
|
271 { |
|
272 DEBUG("CMIDTextEditorEdwin::Draw +"); |
|
273 |
|
274 // Part of transparency workaround. Set drawing active. |
|
275 iDrawInvoked = ETrue; |
|
276 |
|
277 // Background color is drawn before other content. |
|
278 // Note that in order this to work, the background drawing of CEikEdwin |
|
279 // needs to be suppressed. Custom drawer cannot be used due to flickering |
|
280 // problems. Currently it just handles the selection color. |
|
281 CWindowGc& gc = SystemGc(); |
|
282 |
|
283 // If scaling is on, clip to canvas rect is needed. |
|
284 if (iIsScalingOn) |
|
285 { |
|
286 gc.SetClippingRect(iOnScreenCanvasRect); |
|
287 } |
|
288 |
|
289 // Draw background with alpha. |
|
290 gc.SetBrushColor(iBackgroundColor); |
|
291 gc.Clear(aRect); |
|
292 |
|
293 // Now draw the content of the editor. |
|
294 CEikEdwin::Draw(aRect); |
|
295 |
|
296 // cancel of clip |
|
297 if (iIsScalingOn) |
|
298 { |
|
299 gc.CancelClippingRect(); |
|
300 } |
|
301 |
|
302 // Part of transparency workaround. Set drawing not active. |
|
303 iDrawInvoked = EFalse; |
|
304 |
|
305 DEBUG("CMIDTextEditorEdwin::Draw -"); |
|
306 } |
|
307 |
|
308 // --------------------------------------------------------------------------- |
|
309 // CMIDTextEditorEdwin::DrawOngoing |
|
310 // Part of transparency workaround. Returns the current draw status |
|
311 // of this editor window. |
|
312 // --------------------------------------------------------------------------- |
|
313 // |
|
314 TBool CMIDTextEditorEdwin::DrawOngoing() const |
|
315 { |
|
316 return iDrawInvoked; |
|
317 } |
|
318 |
|
319 // --------------------------------------------------------------------------- |
|
320 // CMIDTextEditorEdwin::Redraw |
|
321 // Part of transparency workaround. Returns the current draw status |
|
322 // of this editor window. |
|
323 // --------------------------------------------------------------------------- |
|
324 // |
|
325 void CMIDTextEditorEdwin::Redraw() const |
|
326 { |
|
327 // Do not redraw if draw is already ongoing. |
|
328 if (iDrawInvoked || !iParent) |
|
329 { |
|
330 return; |
|
331 } |
|
332 |
|
333 // If the editor has a transaprent background, the parent |
|
334 // needs to be redrawn in that case. Note that DrawNow |
|
335 // is not applicable here because this is used from the |
|
336 // custom draw which may invoke this method during CTextView |
|
337 // redraw causing a panic to occur. |
|
338 if (IsTransparent()) |
|
339 { |
|
340 iParent->DrawDeferred(); |
|
341 } |
|
342 else |
|
343 { |
|
344 // No transparency. Draw this control only. |
|
345 DrawDeferred(); |
|
346 } |
|
347 } |
|
348 |
|
349 // --------------------------------------------------------------------------- |
|
350 // CMIDTextEditorEdwin::IsTransparent |
|
351 // (other items were commented in the header file) |
|
352 // --------------------------------------------------------------------------- |
|
353 // |
|
354 TBool CMIDTextEditorEdwin::IsTransparent() const |
|
355 { |
|
356 return (iBackgroundColor.Alpha() < KColorOpaque); |
|
357 } |
|
358 |
|
359 // --------------------------------------------------------------------------- |
|
360 // CMIDTextEditorEdwin::FocusChanged |
|
361 // (other items were commented in the header file) |
|
362 // --------------------------------------------------------------------------- |
|
363 // |
|
364 void CMIDTextEditorEdwin::FocusChanged(TDrawNow aDrawNow) |
|
365 { |
|
366 DEBUG("CMIDTextEditorEdwin::FocusChanged +"); |
|
367 |
|
368 CEikEdwin::FocusChanged(aDrawNow); |
|
369 |
|
370 // Apply initial input mode change when the editor has been focused. |
|
371 // Note that initial input mode change must be applied only when |
|
372 // an editing session starts (according to MIDP specification). |
|
373 // See CMIDEdwin::HandleCurrentL() |
|
374 |
|
375 if (IsFocused() && |
|
376 (IsConstraintSet(MMIDTextField::EAny) || |
|
377 IsConstraintSet(MMIDTextField::EMailAddr) || |
|
378 IsConstraintSet(MMIDTextField::EUrl))) |
|
379 { |
|
380 // Set current language. |
|
381 if (iInitialCurrentLanguage) |
|
382 { |
|
383 DEBUG("CMIDTextEditorEdwin::FocusChanged, \ |
|
384 applying current language"); |
|
385 |
|
386 SetAknEditorLocalLanguage(iInitialCurrentLanguage); |
|
387 |
|
388 if (iInitialCurrentInputMode == 0) |
|
389 { |
|
390 DEBUG("CMIDTextEditorEdwin::FocusChanged, null input mode"); |
|
391 |
|
392 // Clears any number mode used previously |
|
393 SetAknEditorCurrentInputMode(EAknEditorNullInputMode); |
|
394 } |
|
395 } |
|
396 |
|
397 // Set current input mode. |
|
398 if (iInitialCurrentInputMode) |
|
399 { |
|
400 DEBUG("CMIDTextEditorEdwin::FocusChanged, \ |
|
401 applying current input mode"); |
|
402 |
|
403 SetAknEditorCurrentInputMode(iInitialCurrentInputMode); |
|
404 } |
|
405 |
|
406 // Set current case. |
|
407 if (iInitialCurrentCase) |
|
408 { |
|
409 DEBUG("CMIDTextEditorEdwin::FocusChanged, \ |
|
410 applying current case"); |
|
411 |
|
412 TInt initialCurrentCase = iInitialCurrentCase; |
|
413 |
|
414 if ((iConstraints & MMIDTextField::EPassword || |
|
415 IsConstraintSet(MMIDTextField::EMailAddr) || |
|
416 IsConstraintSet(MMIDTextField::EUrl)) && |
|
417 iInitialCurrentCase == EAknEditorTextCase) |
|
418 { |
|
419 // Text case is not used in passwords, emailaddrs and urls |
|
420 initialCurrentCase = EAknEditorLowerCase; |
|
421 } |
|
422 |
|
423 SetAknEditorCurrentCase(initialCurrentCase); |
|
424 SetAknEditorCase(initialCurrentCase); |
|
425 } |
|
426 } |
|
427 |
|
428 DEBUG("CMIDTextEditorEdwin::FocusChanged -"); |
|
429 } |
|
430 |
|
431 // --------------------------------------------------------------------------- |
|
432 // CMIDTextEditorEdwin::PositionChanged |
|
433 // (other items were commented in the header file) |
|
434 // --------------------------------------------------------------------------- |
|
435 // |
|
436 void CMIDTextEditorEdwin::PositionChanged() |
|
437 { |
|
438 DEBUG("CMIDTextEditorEdwin::PositionChanged +"); |
|
439 |
|
440 CCoeControl::PositionChanged(); |
|
441 |
|
442 // Text view may have not been created yet. |
|
443 if (iTextView) |
|
444 { |
|
445 // Adjust the view rect to the text view |
|
446 iTextView->SetViewRect(Rect()); |
|
447 } |
|
448 |
|
449 DEBUG("CMIDTextEditorEdwin::PositionChanged -"); |
|
450 } |
|
451 |
|
452 // --------------------------------------------------------------------------- |
|
453 // CMIDTextEditorEdwin::PositionChanged |
|
454 // (other items were commented in the header file) |
|
455 // --------------------------------------------------------------------------- |
|
456 // |
|
457 void CMIDTextEditorEdwin::OverrideColorL(TInt aLogicalColor, TRgb aColor) |
|
458 { |
|
459 CCoeControl::OverrideColorL(aLogicalColor, aColor); |
|
460 |
|
461 if (aLogicalColor == EColorControlBackground) |
|
462 { |
|
463 iBackgroundColor = aColor; |
|
464 } |
|
465 |
|
466 // Suppress background drawing if the editor is transparent. |
|
467 SetSuppressBackgroundDrawing(IsTransparent()); |
|
468 } |
|
469 |
|
470 // --------------------------------------------------------------------------- |
|
471 // CMIDTextEditorEdwin::CreateCustomDrawL |
|
472 // (other items were commented in the header file) |
|
473 // --------------------------------------------------------------------------- |
|
474 // |
|
475 CLafEdwinCustomDrawBase* CMIDTextEditorEdwin::CreateCustomDrawL() |
|
476 { |
|
477 DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL +"); |
|
478 |
|
479 // First create the parent custom draw that handles the drawing of |
|
480 // text and other related components. |
|
481 const MFormCustomDraw* customDraw = CEikEdwin::CreateCustomDrawL(); |
|
482 |
|
483 // Create text editor specific custom draw that handles the |
|
484 // setting of selection color. |
|
485 CLafEdwinCustomDrawBase* ret = new(ELeave)CMIDTextEditorEdwinCustomDraw( |
|
486 iEikonEnv->LafEnv(), *customDraw, *this); |
|
487 |
|
488 DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL -"); |
|
489 |
|
490 return ret; |
|
491 } |
|
492 |
|
493 // --------------------------------------------------------------------------- |
|
494 // CMIDTextEditorEdwin::HandleTextPastedL |
|
495 // (other items were commented in the header file) |
|
496 // --------------------------------------------------------------------------- |
|
497 // |
|
498 void CMIDTextEditorEdwin::HandleTextPastedL(TInt aStartPos, TInt& aLength) |
|
499 { |
|
500 DEBUG_INT2( |
|
501 "CMIDTextEditorEdwin::HandleTextPastedL +, aStartPos=%d, aLength=%d", |
|
502 aStartPos, aLength); |
|
503 |
|
504 HBufC* content = GetTextInHBufL(); // May return NULL |
|
505 if (!content) |
|
506 { |
|
507 // For guaranteeing that this method does not crash in any case. |
|
508 return; |
|
509 } |
|
510 |
|
511 CleanupStack::PushL(content); |
|
512 |
|
513 // Check that the pasted text is valid for the given set of constraints. |
|
514 if (!iEdwinUtils.ConstraintsValidForText( |
|
515 content->Des(), iConstraints, ETrue)) |
|
516 { |
|
517 DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \ |
|
518 constraints not valid"); |
|
519 |
|
520 // Remove pasted content from the text and set it back. |
|
521 iText->DeleteL(aStartPos, aLength); |
|
522 // Notify about the change. |
|
523 HandleTextChangedL(); |
|
524 } |
|
525 // Convert breaks if needed if constraints that do not allow line breaks. |
|
526 // Note that numeric, decimal and phonenumber do not allow line breaks |
|
527 // and are checked before this so no need to check here again. |
|
528 else if (!IsWrapEnabled() || |
|
529 iConstraints & MMIDTextField::EPassword || |
|
530 IsConstraintSet(MMIDTextField::EUrl) || |
|
531 IsConstraintSet(MMIDTextField::EMailAddr)) |
|
532 { |
|
533 DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \ |
|
534 cropping to single line"); |
|
535 |
|
536 TPtr ptr = content->Des(); |
|
537 iEdwinUtils.CropToSingleLine(ptr); |
|
538 CEikEdwin::SetTextL(content); |
|
539 // Notify about content change. |
|
540 HandleTextChangedL(); |
|
541 } |
|
542 |
|
543 CleanupStack::PopAndDestroy(content); |
|
544 |
|
545 DEBUG("CMIDTextEditorEdwin::HandleTextPastedL -"); |
|
546 } |
|
547 |
|
548 // --------------------------------------------------------------------------- |
|
549 // CMIDTextEditorEdwin::HandleTextChangedL |
|
550 // (other items were commented in the header file) |
|
551 // --------------------------------------------------------------------------- |
|
552 // |
|
553 void CMIDTextEditorEdwin::HandleTextChangedL() |
|
554 { |
|
555 DEBUG("CMIDTextEditorEdwin::HandleTextChangedL +"); |
|
556 |
|
557 // Call edwin's method to format the text and redraw. |
|
558 CEikEdwin::HandleTextChangedL(); |
|
559 |
|
560 // Report edwin event. |
|
561 ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate); |
|
562 |
|
563 DEBUG("CMIDTextEditorEdwin::HandleTextChangedL -"); |
|
564 } |
|
565 |
|
566 // --------------------------------------------------------------------------- |
|
567 // CMIDTextEditorEdwin::HandleResourceChangeL |
|
568 // (other items were commented in the header file) |
|
569 // --------------------------------------------------------------------------- |
|
570 // |
|
571 void CMIDTextEditorEdwin::HandleResourceChange(TInt aType) |
|
572 { |
|
573 CEikEdwin::HandleResourceChange(aType); |
|
574 // Notification about language change |
|
575 if (aType == KEikInputLanguageChange) |
|
576 { |
|
577 if (iObserver) |
|
578 { |
|
579 TInt event = MMIDTextEditorObserver::EActionLanguageChange; |
|
580 TAknLayoutId currentLayoutId; |
|
581 CAknEnv::Static()->GetCurrentLayoutId(currentLayoutId); |
|
582 if (iDirection != currentLayoutId) |
|
583 { |
|
584 iDirection = currentLayoutId; |
|
585 event |= MMIDTextEditorObserver::EActionDirectionChange; |
|
586 } |
|
587 iObserver->NotifyInputAction(event); |
|
588 } |
|
589 } |
|
590 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
591 if ((aType == KAknSplitInputEnabled)) |
|
592 { |
|
593 // Partial screen keyboard is opened |
|
594 CEikStatusPane* pane = GetStatusPane(); |
|
595 if (!iPartialVKBOpen || pane->IsVisible()) |
|
596 { |
|
597 // Hide status pane and resize displayable |
|
598 iDisplayable->HandleSplitScreenKeyboard(ETrue); |
|
599 // Preventing from notification when pane is visible, but VKB is |
|
600 // already opened |
|
601 if (iObserver && !iPartialVKBOpen) |
|
602 { |
|
603 iObserver->NotifyInputAction( |
|
604 MMIDTextEditorObserver::EActionPartialInputEnabled); |
|
605 } |
|
606 iPartialVKBOpen = ETrue; |
|
607 } |
|
608 } |
|
609 else if ((aType == KAknSplitInputDisabled) && (iPartialVKBOpen)) |
|
610 { |
|
611 HandlePartialVKBDisable(); |
|
612 } |
|
613 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
614 } |
|
615 |
|
616 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
617 // --------------------------------------------------------------------------- |
|
618 // CMIDTextEditorEdwin::FocusLost |
|
619 // (other items were commented in the header file) |
|
620 // --------------------------------------------------------------------------- |
|
621 // |
|
622 void CMIDTextEditorEdwin::FocusLost() |
|
623 { |
|
624 if (iPartialVKBOpen) |
|
625 { |
|
626 DEBUG("Focus LOST - disable VKB"); |
|
627 CloseVKB(); |
|
628 } |
|
629 } |
|
630 |
|
631 // --------------------------------------------------------------------------- |
|
632 // CMIDTextEditorEdwin::FocusLost |
|
633 // (other items were commented in the header file) |
|
634 // --------------------------------------------------------------------------- |
|
635 // |
|
636 void CMIDTextEditorEdwin::CloseVKB() |
|
637 { |
|
638 CCoeFep* fep = iCoeEnv->Fep(); |
|
639 if (fep) |
|
640 { |
|
641 fep->HandleDestructionOfFocusedItem(); |
|
642 } |
|
643 } |
|
644 |
|
645 // --------------------------------------------------------------------------- |
|
646 // CMIDTextEditorEdwin::DisablePartialVKB |
|
647 // (other items were commented in the header file) |
|
648 // --------------------------------------------------------------------------- |
|
649 // |
|
650 void CMIDTextEditorEdwin::HandlePartialVKBDisable() |
|
651 { |
|
652 // Partial screen keyboard is closed |
|
653 iPartialVKBOpen = EFalse; |
|
654 // Show status pane if not in fullscreen and resize displayable |
|
655 iDisplayable->HandleSplitScreenKeyboard(EFalse); |
|
656 if (iObserver) |
|
657 { |
|
658 iObserver->NotifyInputAction( |
|
659 MMIDTextEditorObserver::EActionPartialInputDisabled); |
|
660 } |
|
661 } |
|
662 |
|
663 // --------------------------------------------------------------------------- |
|
664 // CMIDTextEditorEdwin::GetStatusPane |
|
665 // (other items were commented in the header file) |
|
666 // --------------------------------------------------------------------------- |
|
667 // |
|
668 CEikStatusPane* CMIDTextEditorEdwin::GetStatusPane() |
|
669 { |
|
670 if (!iJavaAppUi) |
|
671 { |
|
672 iJavaAppUi = java::ui::CoreUiAvkonLcdui:: |
|
673 getInstance().getJavaAknAppUi(); |
|
674 } |
|
675 CEikStatusPane* pane = iJavaAppUi->StatusPane(); |
|
676 return pane; |
|
677 } |
|
678 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
679 |
|
680 // --------------------------------------------------------------------------- |
|
681 // CMIDTextEditorEdwin::GetStatusPane |
|
682 // (other items were commented in the header file) |
|
683 // --------------------------------------------------------------------------- |
|
684 // |
|
685 TInt CMIDTextEditorEdwin::ScrollBarEvent() |
|
686 { |
|
687 TInt event = 0; |
|
688 TInt newVisiblecontentHeight = VisibleContentPosition(); |
|
689 |
|
690 // Check if cursor has moved. This must be done because |
|
691 // currently edwin does not report cursor position movement |
|
692 // when text is changed due to user input. |
|
693 if (iVisibleContentHeight != newVisiblecontentHeight) |
|
694 { |
|
695 event |= MMIDTextEditorObserver::EActionScrollbarChange; |
|
696 // Reported, reset here to avoid multiple notifications. |
|
697 iVisibleContentHeight = newVisiblecontentHeight; |
|
698 } |
|
699 return event; |
|
700 } |
|
701 |
|
702 // --------------------------------------------------------------------------- |
|
703 // CMIDTextEditorEdwin::HandleEdwinEventL |
|
704 // (other items were commented in the header file) |
|
705 // --------------------------------------------------------------------------- |
|
706 // |
|
707 void CMIDTextEditorEdwin::HandleEdwinEventL( |
|
708 CEikEdwin* /*aEdwin*/, |
|
709 TEdwinEvent aEventType) |
|
710 { |
|
711 DEBUG_INT("CMIDTextEditorEdwin::HandleEdwinEventL +, aEventType=%d", |
|
712 aEventType); |
|
713 |
|
714 if (aEventType == EEventTextUpdate && ( |
|
715 IsConstraintSet(MMIDTextField::EDecimal) || |
|
716 IsConstraintSet(MMIDTextField::ENumeric))) |
|
717 { |
|
718 // Do not report events if the content was invalid. |
|
719 if (RemoveInvalidNumericContentL()) |
|
720 { |
|
721 return; |
|
722 } |
|
723 } |
|
724 |
|
725 // Notify observer if set. |
|
726 if (iObserver) |
|
727 { |
|
728 switch (aEventType) |
|
729 { |
|
730 case EEventNavigation: |
|
731 { |
|
732 TInt event = MMIDTextEditorObserver::EActionCaretMove; |
|
733 event |= ScrollBarEvent(); |
|
734 iObserver->NotifyInputAction(event); |
|
735 break; |
|
736 } |
|
737 case EEventFormatChanged: // Fallthrough |
|
738 case EEventTextUpdate: |
|
739 { |
|
740 TInt event = MMIDTextEditorObserver::EActionContentChange; |
|
741 |
|
742 // Check if cursor has moved. This must be done because |
|
743 // currently edwin does not report cursor position movement |
|
744 // when text is changed due to user input. |
|
745 if (iCursorPosForAction != KErrNotFound && |
|
746 iCursorPosForAction != CursorPos()) |
|
747 { |
|
748 event |= MMIDTextEditorObserver::EActionCaretMove; |
|
749 // Reported, reset here to avoid multiple notifications. |
|
750 iCursorPosForAction = KErrNotFound; |
|
751 } |
|
752 event |= ScrollBarEvent(); |
|
753 iObserver->NotifyInputAction(event); |
|
754 break; |
|
755 } |
|
756 case EEventScroll: |
|
757 { |
|
758 break; |
|
759 } |
|
760 default: |
|
761 { |
|
762 // Not handled. |
|
763 break; |
|
764 } |
|
765 } |
|
766 } |
|
767 |
|
768 DEBUG("CMIDTextEditorEdwin::HandleEdwinEventL -"); |
|
769 } |
|
770 |
|
771 // --------------------------------------------------------------------------- |
|
772 // CMIDTextEditorEdwin::HandlePointerEventL |
|
773 // (other items were commented in the header file) |
|
774 // --------------------------------------------------------------------------- |
|
775 // |
|
776 #ifdef RD_SCALABLE_UI_V2 |
|
777 void CMIDTextEditorEdwin::HandlePointerEventL( |
|
778 const TPointerEvent &aPointerEvent) |
|
779 { |
|
780 DEBUG("CMIDTextEditorEdwin::HandlePointerEventL +"); |
|
781 if (AknLayoutUtils::PenEnabled()) |
|
782 { |
|
783 CEikEdwin::HandlePointerEventL(aPointerEvent); |
|
784 } |
|
785 DEBUG("CMIDTextEditorEdwin::HandlePointerEventL -"); |
|
786 } |
|
787 #endif // RD_SCALABLE_UI_V2 |
|
788 |
|
789 |
|
790 // --------------------------------------------------------------------------- |
|
791 // CMIDTextEditorEdwin::HandleSpecialKEyEventsL |
|
792 // (other items were commented in the header file) |
|
793 // --------------------------------------------------------------------------- |
|
794 // |
|
795 TKeyResponse CMIDTextEditorEdwin::HandleSpecialKeyEventsL( |
|
796 const TKeyEvent& aKeyEvent, |
|
797 TEventCode aType) |
|
798 { |
|
799 DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL +"); |
|
800 |
|
801 TKeyResponse response = EKeyWasNotConsumed; |
|
802 |
|
803 // Do not handle anything if text's maximum lenght has been reached |
|
804 // or if the editor is set to read only state. |
|
805 if (TextLength() >= MaxLength() || IsReadOnly()) |
|
806 { |
|
807 DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL -, \ |
|
808 max size reached or is read only"); |
|
809 return response; |
|
810 } |
|
811 |
|
812 TUint sc = aKeyEvent.iScanCode; |
|
813 |
|
814 DEBUG_INT2("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \ |
|
815 scanCode=0x%x, iConstraints=0x%x", sc, iConstraints); |
|
816 |
|
817 TBool dec = IsConstraintSet(MMIDTextField::EDecimal); |
|
818 TBool num = IsConstraintSet(MMIDTextField::ENumeric); |
|
819 |
|
820 // Try to handle minus and full stop characters separately. |
|
821 // Other than EEventKey events are ignored. |
|
822 |
|
823 if ((dec || num) && |
|
824 (aType == EEventKey) && |
|
825 (sc == EStdKeyMinus || sc == EStdKeyNkpMinus || |
|
826 sc == EStdKeyFullStop || sc == EStdKeyNkpFullStop || |
|
827 sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW)) |
|
828 { |
|
829 DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \ |
|
830 handling special"); |
|
831 |
|
832 TInt cursorPos = CursorPos(); |
|
833 TPtrC content = Read(); |
|
834 |
|
835 // Toggle minus character. Decimal editor uses SCT so do not toggle |
|
836 // from asterisk key in that case. |
|
837 if ((sc == EStdKeyMinus || sc == EStdKeyNkpMinus) || |
|
838 ((sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW) |
|
839 && num)) |
|
840 { |
|
841 DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \ |
|
842 toggle minus"); |
|
843 |
|
844 if (content.Find(KMinusChar) == KErrNotFound) |
|
845 { |
|
846 iText->InsertL(0, KMinusChar); |
|
847 cursorPos++; |
|
848 } |
|
849 else |
|
850 { |
|
851 iText->DeleteL(0, 1); |
|
852 cursorPos--; |
|
853 } |
|
854 |
|
855 HandleTextChangedL(); |
|
856 ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate); |
|
857 SetCursorPosL(cursorPos, EFalse); |
|
858 |
|
859 response = EKeyWasConsumed; |
|
860 } |
|
861 else if (dec && (sc == EStdKeyFullStop || |
|
862 sc == EStdKeyNkpFullStop)) |
|
863 { |
|
864 TLocale locale; |
|
865 TChar decimalSeparator(locale.DecimalSeparator()); |
|
866 |
|
867 if (content.Locate(decimalSeparator) == KErrNotFound) |
|
868 { |
|
869 DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \ |
|
870 inserting full stop"); |
|
871 |
|
872 // Insert full stop sign into to cursor's current position. |
|
873 iText->InsertL(cursorPos, decimalSeparator); |
|
874 HandleTextChangedL(); |
|
875 ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate); |
|
876 SetCursorPosL(cursorPos + 1, EFalse); |
|
877 |
|
878 response = EKeyWasConsumed; |
|
879 } |
|
880 } |
|
881 } |
|
882 |
|
883 DEBUG_INT("CMIDTextEditorEdwin::HandleSpecialKeyEventsL - response=%d", |
|
884 response); |
|
885 |
|
886 return response; |
|
887 } |
|
888 |
|
889 // --------------------------------------------------------------------------- |
|
890 // CMIDTextEditorEdwin::SetTopParent |
|
891 // (other items are commented in the header file) |
|
892 // --------------------------------------------------------------------------- |
|
893 // |
|
894 void CMIDTextEditorEdwin::SetTopParent(CCoeControl* aControl) |
|
895 { |
|
896 iParent = aControl; |
|
897 } |
|
898 |
|
899 // --------------------------------------------------------------------------- |
|
900 // CMIDTextEditorEdwin::SetObserver |
|
901 // (other items are commented in the header file) |
|
902 // --------------------------------------------------------------------------- |
|
903 // |
|
904 void CMIDTextEditorEdwin::SetObserver(MMIDTextEditorObserver* aObserver) |
|
905 { |
|
906 DEBUG("CMIDTextEditorEdwin::SetObserver +"); |
|
907 |
|
908 iObserver = aObserver; |
|
909 |
|
910 DEBUG("CMIDTextEditorEdwin::SetObserver -"); |
|
911 } |
|
912 |
|
913 // --------------------------------------------------------------------------- |
|
914 // CMIDTextEditorEdwin::SetEditingStateIndicator |
|
915 // (other items were commented in the header file) |
|
916 // --------------------------------------------------------------------------- |
|
917 // |
|
918 void CMIDTextEditorEdwin::SetEditingStateIndicator( |
|
919 CMIDEditingStateIndicator* aIndicator) |
|
920 { |
|
921 DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator +"); |
|
922 |
|
923 // Indicator can be set to NULL. |
|
924 iIndicator = aIndicator; |
|
925 |
|
926 DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator -"); |
|
927 } |
|
928 |
|
929 // --------------------------------------------------------------------------- |
|
930 // CMIDTextEditorEdwin::SetConstraintsL |
|
931 // (other items were commented in the header file) |
|
932 // --------------------------------------------------------------------------- |
|
933 // |
|
934 void CMIDTextEditorEdwin::SetConstraintsL(TUint aConstraints) |
|
935 { |
|
936 DEBUG("CMIDTextEditorEdwin::SetConstraintsL +"); |
|
937 |
|
938 // Note that this method cannot be 100% leave-safe due to the current |
|
939 // CEikEdwin implementation. |
|
940 |
|
941 __ASSERT_DEBUG(iText, User::Invariant()); |
|
942 |
|
943 // Apply document content. |
|
944 CGlobalText* newText = NULL; |
|
945 CGlobalText* oldText = static_cast< CGlobalText* >(iText); |
|
946 |
|
947 const CParaFormatLayer* paraFormatLayer = |
|
948 oldText->GlobalParaFormatLayer(); |
|
949 |
|
950 const CCharFormatLayer* charFormatLayer = |
|
951 oldText->GlobalCharFormatLayer(); |
|
952 |
|
953 TBool enableCcpuSupport = ETrue; |
|
954 |
|
955 // Create password text if mode is password (non-restrictive). |
|
956 if (aConstraints & MMIDTextField::EPassword) |
|
957 { |
|
958 DEBUG( |
|
959 "CMIDTextEditorEdwin::SetConstraintsL, creating password text"); |
|
960 |
|
961 // Password editors must not use CCPU support according to |
|
962 // S60 Editing specification. |
|
963 enableCcpuSupport = EFalse; |
|
964 |
|
965 CPasswordBoxGlobalText* text = new(ELeave)CPasswordBoxGlobalText( |
|
966 paraFormatLayer, charFormatLayer, *this); |
|
967 |
|
968 CleanupStack::PushL(text); |
|
969 text->ConstructL(); |
|
970 CleanupStack::Pop(text); |
|
971 |
|
972 newText = text; |
|
973 } |
|
974 else // Default, no password. |
|
975 { |
|
976 // Use default global text in the editor. |
|
977 newText = CGlobalText::NewL(paraFormatLayer, charFormatLayer); |
|
978 } |
|
979 |
|
980 CleanupStack::PushL(newText); |
|
981 SetDocumentContentL(newText); |
|
982 |
|
983 // Disable or enable CCPU support here. |
|
984 EnableCcpuSupportL(enableCcpuSupport); |
|
985 |
|
986 // Store constraints here. Rest of the method is leave-safe |
|
987 // and RestoreDefaultInputState uses the capabilities. |
|
988 iConstraints = aConstraints; |
|
989 |
|
990 // Restore default input state before making any modifications. This |
|
991 // ensures that the next input constraints are set correctly and |
|
992 // that the previous constraints do not affect on the new input modes. |
|
993 // This should be done in CMIDEdwinUtils::SetFEPModeAndCharFormat() |
|
994 // but it does not reset all the necessary input parameters. |
|
995 RestoreDefaultInputState(); |
|
996 |
|
997 // Set uneditable if set as current mode. |
|
998 SetReadOnly(aConstraints & MMIDTextField::EUneditable); |
|
999 |
|
1000 // Use edwin utils to set the FEP mode and character format. |
|
1001 iEdwinUtils.SetFEPModeAndCharFormat(aConstraints, this); |
|
1002 |
|
1003 // Publish MIDP constraints via input capabilities of CEikEdwin. |
|
1004 CAknExtendedInputCapabilities* caps = AknInputCaps(); |
|
1005 if (caps) |
|
1006 { |
|
1007 DEBUG( |
|
1008 "CMIDTextEditorEdwin::SetConstraintsL, setting MIDP constaints"); |
|
1009 |
|
1010 caps->SetMIDPConstraints(aConstraints); |
|
1011 } |
|
1012 |
|
1013 // CMIDEdwinUtils modify the multiline state of the editor |
|
1014 // thus it needs the be set again here. Passwords are always |
|
1015 // single line editors. |
|
1016 if (!(aConstraints & MMIDTextField::EPassword)) |
|
1017 { |
|
1018 SetWordWrapL(iMultiline); |
|
1019 } |
|
1020 else |
|
1021 { |
|
1022 SetWordWrapL(EFalse); |
|
1023 } |
|
1024 CleanupStack::Pop(newText); |
|
1025 |
|
1026 DEBUG("CMIDTextEditorEdwin::SetConstraintsL +"); |
|
1027 } |
|
1028 |
|
1029 // --------------------------------------------------------------------------- |
|
1030 // CMIDTextEditorEdwin::SetInitialInputModeL |
|
1031 // (other items were commented in the header file) |
|
1032 // --------------------------------------------------------------------------- |
|
1033 // |
|
1034 void CMIDTextEditorEdwin::SetInitialInputModeL( |
|
1035 const TDesC& aCharacterSubset) |
|
1036 { |
|
1037 DEBUG_STR( |
|
1038 "CMIDTextEditorEdwin::SetInitialInputModeL +, aCharacterSubset=%S", |
|
1039 aCharacterSubset); |
|
1040 |
|
1041 // Set initial input mode. Note that the change is performed |
|
1042 // after the next editing session starts. See MIDP specification. |
|
1043 // See CMIDEdwin::SetInitialInputModeL |
|
1044 |
|
1045 iEdwinUtils.SetInitialInputModeL( |
|
1046 aCharacterSubset, |
|
1047 iConstraints, |
|
1048 iInitialCurrentCase, |
|
1049 iInitialCurrentInputMode, |
|
1050 iInitialCurrentLanguage); |
|
1051 |
|
1052 // Set permitted case modes for edwin in lowercase or uppercase mode. |
|
1053 if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0 || |
|
1054 aCharacterSubset.Compare(KMidpLowercaseLatin) == 0) |
|
1055 { |
|
1056 DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL, latin"); |
|
1057 |
|
1058 // MIDP_UPPERCASE_LATIN or MIDP_LOWERCASE_LATIN are ignored if |
|
1059 // INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY. |
|
1060 if (!(iConstraints & MMIDTextField::EInitialCapsWordSentence || |
|
1061 iConstraints & MMIDTextField::EInitialCapsWord) || |
|
1062 !IsConstraintSet(MMIDTextField::EAny)) |
|
1063 { |
|
1064 // If initial input mode is uppercase or lowercase then permit |
|
1065 // only explicit case mode changes, automatic changes are not |
|
1066 // allowed. |
|
1067 SetAknEditorPermittedCaseModes( |
|
1068 EAknEditorUpperCase | EAknEditorLowerCase); |
|
1069 } |
|
1070 } |
|
1071 else |
|
1072 { |
|
1073 SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes); |
|
1074 } |
|
1075 |
|
1076 DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL -"); |
|
1077 } |
|
1078 |
|
1079 // --------------------------------------------------------------------------- |
|
1080 // CMIDTextEditorEdwin::RestoreDefaultInputState |
|
1081 // (other items were commented in the header file) |
|
1082 // --------------------------------------------------------------------------- |
|
1083 // |
|
1084 void CMIDTextEditorEdwin::RestoreDefaultInputState() |
|
1085 { |
|
1086 DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState +"); |
|
1087 |
|
1088 // Restore the default input state. It is not possible to directly |
|
1089 // call CAknEditorState object from CEikEdwin since it is currently |
|
1090 // used internally only. The default state set here is the same |
|
1091 // that is set when CAknEditorState is constructed. See |
|
1092 // CAknEditorState::CAknEditorState in aknedsts.cpp for details. |
|
1093 |
|
1094 SetAknEditorCase(EAknEditorTextCase); |
|
1095 SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes); |
|
1096 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
1097 SetAknEditorFlags(EAknEditorFlagEnablePartialScreen); |
|
1098 #else |
|
1099 SetAknEditorFlags(EAknEditorFlagDefault); |
|
1100 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
1101 SetAknEditorSpecialCharacterTable(KErrNotFound); |
|
1102 SetAknEditorInputMode(EAknEditorTextInputMode); |
|
1103 SetAknEditorAllowedInputModes(EAknEditorAllInputModes); |
|
1104 SetAknEditorCurrentInputMode(EAknEditorTextInputMode); |
|
1105 SetAknEditorCurrentCase(EAknEditorTextCase); |
|
1106 SetAknEditorNumericKeymap(EAknEditorAlphanumericNumberModeKeymap); |
|
1107 SetAknEditorLocalLanguage( |
|
1108 CAknEnv::Static()->SettingCache().InputLanguage()); |
|
1109 |
|
1110 // Enable SCT in other than numeric editors. Note that asterisk toggles |
|
1111 // the minus character so the SCT must not be enabled because of that. |
|
1112 if (!IsConstraintSet(MMIDTextField::ENumeric)) |
|
1113 { |
|
1114 CAknExtendedInputCapabilities* caps = AknInputCaps(); |
|
1115 if (caps) |
|
1116 { |
|
1117 DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState,\ |
|
1118 disable SCT"); |
|
1119 |
|
1120 caps->SetCapabilities( |
|
1121 caps->Capabilities() & |
|
1122 ~CAknExtendedInputCapabilities::EDisableSCT); |
|
1123 } |
|
1124 } |
|
1125 |
|
1126 // Reset initial input mode also. |
|
1127 iInitialCurrentCase = 0; |
|
1128 iInitialCurrentInputMode = 0; |
|
1129 iInitialCurrentLanguage = ELangTest; |
|
1130 |
|
1131 DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState -"); |
|
1132 } |
|
1133 |
|
1134 // --------------------------------------------------------------------------- |
|
1135 // CMIDTextEditorEdwin::SetCursorPosL |
|
1136 // (other items were commented in the header file) |
|
1137 // --------------------------------------------------------------------------- |
|
1138 // |
|
1139 void CMIDTextEditorEdwin::SetCursorPosL( |
|
1140 TInt aCursorPosition, |
|
1141 TBool aSelect) |
|
1142 { |
|
1143 DEBUG_INT("CMIDTextEditorEdwin::SetCursorPosL +, aCursorPosition=%d", |
|
1144 aCursorPosition); |
|
1145 |
|
1146 // Set cursor if the editor has a valid parent. |
|
1147 if (IsInitialized()) |
|
1148 { |
|
1149 CEikEdwin::SetCursorPosL(aCursorPosition, aSelect); |
|
1150 } |
|
1151 // Do not deliver event if the position actually does not change. |
|
1152 else if (CursorPos() != aCursorPosition) |
|
1153 { |
|
1154 // Event has to be delivered to the registered observer |
|
1155 // even if the editor window has not been initialized. |
|
1156 ReportEdwinEventL(MEikEdwinObserver::EEventNavigation); |
|
1157 } |
|
1158 |
|
1159 if (aSelect) |
|
1160 { |
|
1161 // CEikEdwin does not store selection if not initialized. |
|
1162 // Store it in order to avoid errors when setting selection |
|
1163 // before parent is stored. |
|
1164 iSelection.SetSelection(iCursorPosition, aCursorPosition); |
|
1165 } |
|
1166 else // Clear selection. |
|
1167 { |
|
1168 iSelection.SetSelection(0, 0); |
|
1169 } |
|
1170 |
|
1171 // Editor window does not know the position yet because it has not |
|
1172 // been activated. Store the position to a member variable. Note that |
|
1173 // this must be set when the editor is activated. |
|
1174 // Cursor needs to be stored all the time because change of the |
|
1175 // parent object may cause the cursor to be changed in CEikEdwin. |
|
1176 iCursorPosition = aCursorPosition; |
|
1177 |
|
1178 DEBUG("CMIDTextEditorEdwin::SetCursorPosL -"); |
|
1179 } |
|
1180 |
|
1181 // --------------------------------------------------------------------------- |
|
1182 // CMIDTextEditorEdwin::CursorPos |
|
1183 // (other items are commented in the header file) |
|
1184 // --------------------------------------------------------------------------- |
|
1185 // |
|
1186 TInt CMIDTextEditorEdwin::CursorPos() const |
|
1187 { |
|
1188 DEBUG("CMIDTextEditorEdwin::CursorPos +"); |
|
1189 |
|
1190 // The control may have not been initialized yet (i.e. SetParentL has |
|
1191 // not been called). Do not get cursor position in that case because |
|
1192 // it crashes due to missing text view in the CEikEdwin. |
|
1193 TInt cursorPosition( |
|
1194 (IsInitialized() ? CEikEdwin::CursorPos() : iCursorPosition)); |
|
1195 |
|
1196 DEBUG_INT("CMIDTextEditorEdwin::CursorPos -, cursorPosition=%d", |
|
1197 cursorPosition); |
|
1198 |
|
1199 return cursorPosition; |
|
1200 } |
|
1201 |
|
1202 // --------------------------------------------------------------------------- |
|
1203 // CMIDTextEditorEdwin::Selection |
|
1204 // (other items were commented in the header file) |
|
1205 // --------------------------------------------------------------------------- |
|
1206 // |
|
1207 TCursorSelection CMIDTextEditorEdwin::Selection() |
|
1208 { |
|
1209 DEBUG("CMIDTextEditorEdwin::Selection +"); |
|
1210 |
|
1211 TCursorSelection selection(iSelection); |
|
1212 |
|
1213 // Selection is not returned correctly if the editor has not been |
|
1214 // initialized. |
|
1215 if (IsInitialized()) |
|
1216 { |
|
1217 selection = CEikEdwin::Selection(); |
|
1218 } |
|
1219 |
|
1220 DEBUG("CMIDTextEditorEdwin::Selection -"); |
|
1221 |
|
1222 return selection; |
|
1223 } |
|
1224 |
|
1225 // --------------------------------------------------------------------------- |
|
1226 // CMIDTextEditorEdwin::SetWordWrapL |
|
1227 // (other items were commented in the header file) |
|
1228 // --------------------------------------------------------------------------- |
|
1229 // |
|
1230 void CMIDTextEditorEdwin::SetWordWrapL(TBool aWrapIsOn) |
|
1231 { |
|
1232 DEBUG_INT("CMIDTextEditorEdwin::SetWordWrapL +, aWrapIsOn=%d", |
|
1233 aWrapIsOn); |
|
1234 |
|
1235 // CEikEdwin crashes when setting word wrap before it |
|
1236 // has a valid container window. Multiline state is set |
|
1237 // in InitializeL() method again when called. |
|
1238 if (IsInitialized()) |
|
1239 { |
|
1240 CEikEdwin::SetWordWrapL(aWrapIsOn); |
|
1241 |
|
1242 // Apply line and paragraph breaks. |
|
1243 if (!aWrapIsOn) |
|
1244 { |
|
1245 AddFlagToUserFlags(CEikEdwin::ENoLineOrParaBreaks); |
|
1246 } |
|
1247 else |
|
1248 { |
|
1249 RemoveFlagFromUserFlags(CEikEdwin::ENoLineOrParaBreaks); |
|
1250 } |
|
1251 } |
|
1252 |
|
1253 iMultiline = aWrapIsOn; |
|
1254 |
|
1255 DEBUG("CMIDTextEditorEdwin::SetCursorPosL -"); |
|
1256 } |
|
1257 |
|
1258 // --------------------------------------------------------------------------- |
|
1259 // CMIDTextEditorEdwin::IsWrapEnabled |
|
1260 // (other items were commented in the header file) |
|
1261 // --------------------------------------------------------------------------- |
|
1262 // |
|
1263 TBool CMIDTextEditorEdwin::IsWrapEnabled() const |
|
1264 { |
|
1265 return iMultiline; |
|
1266 } |
|
1267 |
|
1268 // --------------------------------------------------------------------------- |
|
1269 // CMIDTextEditorEdwin::SetSize |
|
1270 // (other items were commented in the header file) |
|
1271 // --------------------------------------------------------------------------- |
|
1272 // |
|
1273 void CMIDTextEditorEdwin::SetSize(TInt aWidth, TInt aHeight) |
|
1274 { |
|
1275 DEBUG("CMIDTextEditorEdwin::SetSize +"); |
|
1276 |
|
1277 // Set the width of the editor window. Note that EWidthInPixels is set |
|
1278 // so this method uses the parameter as pixels instead of chars. |
|
1279 CalculateWidth(aWidth); |
|
1280 // Set minimum and maximum height to the same value. |
|
1281 SetMinimumHeight(aHeight); |
|
1282 SetMaximumHeight(aHeight); |
|
1283 |
|
1284 TSize size(aWidth, aHeight); |
|
1285 // Set size of the UI control if container has been set. Otherwise |
|
1286 // this will panic the editor window at some point. |
|
1287 if (IsInitialized()) |
|
1288 { |
|
1289 CCoeControl::SetSize(size); |
|
1290 } |
|
1291 |
|
1292 // Store the size for later use when set parent has been called. |
|
1293 iSize = size; |
|
1294 |
|
1295 DEBUG("CMIDTextEditorEdwin::SetSize -"); |
|
1296 } |
|
1297 |
|
1298 // --------------------------------------------------------------------------- |
|
1299 // CMIDTextEditorEdwin::Size |
|
1300 // (other items were commented in the header file) |
|
1301 // --------------------------------------------------------------------------- |
|
1302 // |
|
1303 TSize CMIDTextEditorEdwin::Size() const |
|
1304 { |
|
1305 DEBUG("CMIDTextEditorEdwin::Size +"); |
|
1306 |
|
1307 TSize size(iSize); |
|
1308 |
|
1309 // Check if editor has been initialized. |
|
1310 if (IsInitialized()) |
|
1311 { |
|
1312 size = CCoeControl::Size(); |
|
1313 } |
|
1314 |
|
1315 DEBUG("CMIDTextEditorEdwin::Size -"); |
|
1316 |
|
1317 return size; |
|
1318 } |
|
1319 |
|
1320 // --------------------------------------------------------------------------- |
|
1321 // CMIDTextEditorEdwin::IsInitialized |
|
1322 // (other items were commented in the header file) |
|
1323 // --------------------------------------------------------------------------- |
|
1324 // |
|
1325 TBool CMIDTextEditorEdwin::IsInitialized() const |
|
1326 { |
|
1327 DEBUG_INT("CMIDTextEditorEdwin::IsInitialized, iInitialized=%d", |
|
1328 iInitialized); |
|
1329 |
|
1330 // Currently, the text editor is considered as constructed when the text |
|
1331 // view has been created and the editor window has been activated. |
|
1332 return iInitialized; |
|
1333 } |
|
1334 |
|
1335 // --------------------------------------------------------------------------- |
|
1336 // CMIDTextEditorEdwin::InitializeL |
|
1337 // (other items were commented in the header file) |
|
1338 // --------------------------------------------------------------------------- |
|
1339 // |
|
1340 void CMIDTextEditorEdwin::InitializeL(CMIDDisplayable* aDisplayable) |
|
1341 { |
|
1342 DEBUG("CMIDTextEditorEdwin::InitializeL +"); |
|
1343 |
|
1344 if (!iInitialized) |
|
1345 { |
|
1346 |
|
1347 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
1348 iDisplayable = aDisplayable; |
|
1349 #else |
|
1350 (void)aDisplayable; // Just to remove a compiler warning |
|
1351 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
1352 |
|
1353 CreateTextViewL(); |
|
1354 ActivateL(); |
|
1355 |
|
1356 // Set colors here in order to avoid crash when parent |
|
1357 // has not been set by CMIDTextEditor. |
|
1358 SetBackgroundColorL(iBackgroundColor); |
|
1359 iTextView->SetBackgroundColor(iBackgroundColor); |
|
1360 |
|
1361 // Set selection set before initialization. |
|
1362 CEikEdwin::SetCursorPosL(iCursorPosition, EFalse); |
|
1363 |
|
1364 // Selection overrides cursor's position |
|
1365 if (iSelection.Length() > 0) |
|
1366 { |
|
1367 CEikEdwin::SetCursorPosL(iSelection.LowerPos(), EFalse); |
|
1368 CEikEdwin::SetCursorPosL(iSelection.HigherPos(), ETrue); |
|
1369 } |
|
1370 |
|
1371 // By default, editor is unfocused and not visible. Note |
|
1372 // that hide and show cannot be called before set parent. |
|
1373 SetFocus(EFalse); |
|
1374 MakeVisible(EFalse); |
|
1375 // Apply current size. |
|
1376 CCoeControl::SetSize(iSize); |
|
1377 iInitialized = true; |
|
1378 // Apply current multiline status. iInitialized must be true here. |
|
1379 SetWordWrapL(iMultiline); |
|
1380 } |
|
1381 |
|
1382 DEBUG("CMIDTextEditorEdwin::InitializeL -"); |
|
1383 } |
|
1384 |
|
1385 // --------------------------------------------------------------------------- |
|
1386 // CMIDTextEditorEdwin::Uninitialize |
|
1387 // (other items were commented in the header file) |
|
1388 // --------------------------------------------------------------------------- |
|
1389 // |
|
1390 void CMIDTextEditorEdwin::Uninitialize() |
|
1391 { |
|
1392 DEBUG("CMIDTextEditorEdwin::Uninitialize +"); |
|
1393 |
|
1394 if (iInitialized) |
|
1395 { |
|
1396 #ifdef RD_JAVA_S60_RELEASE_9_2 |
|
1397 iDisplayable = NULL; |
|
1398 #endif // RD_JAVA_S60_RELEASE_9_2 |
|
1399 // Remove focus and hide the editor. |
|
1400 SetFocus(EFalse); |
|
1401 MakeVisible(EFalse); |
|
1402 // Store cursor's current position. |
|
1403 iCursorPosition = CEikEdwin::CursorPos(); |
|
1404 |
|
1405 iInitialized = false; |
|
1406 iParent = NULL; |
|
1407 } |
|
1408 |
|
1409 DEBUG("CMIDTextEditorEdwin::Uninitialize -"); |
|
1410 } |
|
1411 |
|
1412 // --------------------------------------------------------------------------- |
|
1413 // CMIDTextEditorEdwin::EditorWindowHeight |
|
1414 // (other items were commented in the header file) |
|
1415 // --------------------------------------------------------------------------- |
|
1416 // |
|
1417 TInt CMIDTextEditorEdwin::EditorWindowHeight() const |
|
1418 { |
|
1419 DEBUG("CMIDTextEditorEdwin::EditorWindowHeight +"); |
|
1420 |
|
1421 TInt minimumHeight = iSize.iHeight; |
|
1422 if (iNumberOfLines == 0) |
|
1423 { |
|
1424 if (MinimumHeight() > 0) |
|
1425 { |
|
1426 minimumHeight = MinimumHeight(); |
|
1427 } |
|
1428 } |
|
1429 else |
|
1430 { |
|
1431 minimumHeight = (LineHeight() * iNumberOfLines) |
|
1432 + iBorder.SizeDelta().iHeight |
|
1433 + iMargins.iTop |
|
1434 + iMargins.iBottom; |
|
1435 } |
|
1436 |
|
1437 DEBUG_INT("CMIDTextEditorEdwin::EditorWindowHeight - , height=%d", |
|
1438 minimumHeight); |
|
1439 |
|
1440 return minimumHeight; |
|
1441 } |
|
1442 |
|
1443 // --------------------------------------------------------------------------- |
|
1444 // CMIDTextEditorEdwin::NumberOfLines |
|
1445 // (other items were commented in the header file) |
|
1446 // --------------------------------------------------------------------------- |
|
1447 // |
|
1448 TInt CMIDTextEditorEdwin::NumberOfLines() const |
|
1449 { |
|
1450 __ASSERT_DEBUG(iLayout, User::Invariant()); |
|
1451 |
|
1452 return iLayout->NumFormattedLines(); |
|
1453 } |
|
1454 |
|
1455 // --------------------------------------------------------------------------- |
|
1456 // CMIDTextEditorEdwin::LineHeight |
|
1457 // (other items were commented in the header file) |
|
1458 // --------------------------------------------------------------------------- |
|
1459 // |
|
1460 TInt CMIDTextEditorEdwin::LineHeight() const |
|
1461 { |
|
1462 __ASSERT_DEBUG(iLayout, User::Invariant()); |
|
1463 |
|
1464 TInt lineHeight = iLayout->FormattedHeightInPixels(); |
|
1465 const TInt docLength = iLayout->DocumentLength(); |
|
1466 if (docLength > 0) |
|
1467 { |
|
1468 const TInt numFormattedLines = iLayout->NumFormattedLines(); |
|
1469 lineHeight = lineHeight / numFormattedLines; |
|
1470 } |
|
1471 |
|
1472 return lineHeight; |
|
1473 } |
|
1474 |
|
1475 // --------------------------------------------------------------------------- |
|
1476 // CMIDTextEditorEdwin::VisibleContentPosition |
|
1477 // (other items were commented in the header file) |
|
1478 // --------------------------------------------------------------------------- |
|
1479 // |
|
1480 TInt CMIDTextEditorEdwin::VisibleContentPosition() const |
|
1481 { |
|
1482 DEBUG("CMIDTextEditorEdwin::VisibleContentPosition +"); |
|
1483 |
|
1484 __ASSERT_DEBUG(iLayout, User::Invariant()); |
|
1485 |
|
1486 DEBUG_INT("CMIDTextEditorEdwin::VisibleContentPosition -, pos=%d", |
|
1487 iLayout->PixelsAboveBand()); |
|
1488 |
|
1489 return iLayout->PixelsAboveBand(); |
|
1490 } |
|
1491 |
|
1492 // --------------------------------------------------------------------------- |
|
1493 // CMIDTextEditorEdwin::Read |
|
1494 // (other items were commented in the header file) |
|
1495 // --------------------------------------------------------------------------- |
|
1496 // |
|
1497 const TPtrC CMIDTextEditorEdwin::Read() const |
|
1498 { |
|
1499 if (iConstraints & MMIDTextField::EPassword) |
|
1500 { |
|
1501 return static_cast< CPasswordBoxGlobalText* >(iText)->ClearText(); |
|
1502 } |
|
1503 |
|
1504 return iText->Read(0, TextLength()); |
|
1505 } |
|
1506 |
|
1507 // --------------------------------------------------------------------------- |
|
1508 // CMIDTextEditorEdwin::MopSupplyObject |
|
1509 // (other items were commented in the header file) |
|
1510 // --------------------------------------------------------------------------- |
|
1511 // |
|
1512 TTypeUid::Ptr CMIDTextEditorEdwin::MopSupplyObject(TTypeUid aId) |
|
1513 { |
|
1514 // Try supplying custom indicator. |
|
1515 TTypeUid::Ptr id(( |
|
1516 iIndicator ? iIndicator->SupplyIndicatorMopObject(aId) |
|
1517 : TTypeUid::Null())); |
|
1518 |
|
1519 // Indicator was not supplied. Try supplying from CEikEdwin. |
|
1520 if (!(id.Pointer())) |
|
1521 { |
|
1522 return CEikEdwin::MopSupplyObject(aId); |
|
1523 } |
|
1524 |
|
1525 return id; |
|
1526 } |
|
1527 |
|
1528 // --------------------------------------------------------------------------- |
|
1529 // CMIDTextEditorEdwin::SetDocumentContentL |
|
1530 // (other items were commented in the header file) |
|
1531 // --------------------------------------------------------------------------- |
|
1532 // |
|
1533 void CMIDTextEditorEdwin::SetDocumentContentL(CGlobalText* aText) |
|
1534 { |
|
1535 DEBUG("CMIDTextEditorEdwin::SetDocumentContentL +"); |
|
1536 |
|
1537 // Even though the method takes a reference in it, the ownership |
|
1538 // is still transferred to CEikEdwin. And current iText is simply |
|
1539 // left ignored. Store it locally and delete after successful |
|
1540 // operation |
|
1541 CPlainText* temp = iText; |
|
1542 TRAPD(err, CEikEdwin::SetDocumentContentL( |
|
1543 *aText, CEikEdwin::EUseText)); |
|
1544 |
|
1545 if (err != KErrNone) |
|
1546 { |
|
1547 // Failed but the ownership was transferred... State has been changed |
|
1548 // but we avoid leaking any memory at this point which is better. |
|
1549 // Restore the text back. This is not bulletproof, but leaves |
|
1550 // the text state as it was before trying to set the new text. |
|
1551 delete iText; |
|
1552 iText = temp; |
|
1553 User::Leave(err); |
|
1554 } |
|
1555 |
|
1556 // Everything went fine. Delete the old iText. |
|
1557 delete temp; |
|
1558 |
|
1559 DEBUG("CMIDTextEditorEdwin::SetDocumentContentL -"); |
|
1560 } |
|
1561 |
|
1562 // --------------------------------------------------------------------------- |
|
1563 // CMIDTextEditorEdwin::AknInputCaps |
|
1564 // (other items were commented in the header file) |
|
1565 // --------------------------------------------------------------------------- |
|
1566 // |
|
1567 CAknExtendedInputCapabilities* CMIDTextEditorEdwin::AknInputCaps() const |
|
1568 { |
|
1569 CAknExtendedInputCapabilities* caps = NULL; |
|
1570 |
|
1571 TCoeInputCapabilities inputCapabilities = InputCapabilities(); |
|
1572 if (inputCapabilities != TCoeInputCapabilities::ENone) |
|
1573 { |
|
1574 DEBUG("CMIDTextEditorEdwin::AknInputCaps, editor has input caps"); |
|
1575 |
|
1576 // Get input capabilities object provider. |
|
1577 MObjectProvider* provider = inputCapabilities.ObjectProvider(); |
|
1578 if (provider) |
|
1579 { |
|
1580 DEBUG( |
|
1581 "CMIDTextEditorEdwin::AknInputCaps, object provider found"); |
|
1582 |
|
1583 // MopGetObjects needs a reference to a pointer to an object |
|
1584 // of a type that is to be retrieved. NULL is OK here. |
|
1585 caps = provider->MopGetObject(caps); |
|
1586 } |
|
1587 } |
|
1588 |
|
1589 return caps; |
|
1590 } |
|
1591 |
|
1592 // --------------------------------------------------------------------------- |
|
1593 // CMIDTextEditorEdwin::RemoveInvalidNumericContentL |
|
1594 // (other items were commented in the header file) |
|
1595 // --------------------------------------------------------------------------- |
|
1596 // |
|
1597 TBool CMIDTextEditorEdwin::RemoveInvalidNumericContentL() |
|
1598 { |
|
1599 DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL +"); |
|
1600 |
|
1601 TBool textChanged = EFalse; |
|
1602 TPtrC content = Read(); |
|
1603 |
|
1604 // Handle content change in numeric and decimal editors if the |
|
1605 // content is not valid for the given set of constraints. |
|
1606 if (!iEdwinUtils.ConstraintsValidForText(content, iConstraints, ETrue)) |
|
1607 { |
|
1608 DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL, \ |
|
1609 content not valid"); |
|
1610 |
|
1611 TLocale locale; |
|
1612 TChar decimal(locale.DecimalSeparator()); |
|
1613 TChar minus(KCharMinus); |
|
1614 |
|
1615 TInt cursorPos = CursorPos(); |
|
1616 TInt minusPos = content.Locate(minus); |
|
1617 TInt decimalPos = content.Locate(decimal); |
|
1618 |
|
1619 // Validate that minus character has been entered correctly |
|
1620 // First cases in which there is only minus and separator. |
|
1621 if (content.Length() == 1 && |
|
1622 ((decimalPos == 0) || (minusPos == 0))) |
|
1623 { |
|
1624 iText->DeleteL(0, 1); |
|
1625 cursorPos = 0; |
|
1626 } |
|
1627 else if (content.Length() == 2 && |
|
1628 ((minusPos == 0) && (decimalPos == 1))) |
|
1629 { |
|
1630 iText->DeleteL(0, 2); |
|
1631 cursorPos = 0; |
|
1632 } |
|
1633 else |
|
1634 { |
|
1635 // Other cases. Minus and decimal somewhere in the content. |
|
1636 if (minusPos != KErrNotFound) |
|
1637 { |
|
1638 // The first is valid. Remove all other minus chars. |
|
1639 minusPos = content.LocateReverse(minus); |
|
1640 while (minusPos != 0 && minusPos != KErrNotFound) |
|
1641 { |
|
1642 iText->DeleteL(minusPos, 1); |
|
1643 minusPos = content.LocateReverse(minus); |
|
1644 cursorPos--; |
|
1645 } |
|
1646 } |
|
1647 |
|
1648 // Decimal position may have changed. |
|
1649 decimalPos = content.Locate(decimal); |
|
1650 |
|
1651 if (decimalPos != KErrNotFound) |
|
1652 { |
|
1653 // The first is valid. Remove all other separators. |
|
1654 TInt secondPos = content.LocateReverse(decimal); |
|
1655 while (secondPos != decimalPos) |
|
1656 { |
|
1657 iText->DeleteL(secondPos, 1); |
|
1658 secondPos = content.LocateReverse(decimal); |
|
1659 cursorPos--; |
|
1660 } |
|
1661 } |
|
1662 } |
|
1663 |
|
1664 // Do not report event again so call base class' method. |
|
1665 CEikEdwin::HandleTextChangedL(); |
|
1666 // Restore cursor's original position. |
|
1667 SetCursorPosL(cursorPos, EFalse); |
|
1668 textChanged = ETrue; |
|
1669 } |
|
1670 |
|
1671 DEBUG_INT( |
|
1672 "CMIDTextEditorEdwin::RemoveInvalidNumericContentL -, textChanged=%d", |
|
1673 textChanged); |
|
1674 |
|
1675 return textChanged; |
|
1676 } |
|
1677 |
|
1678 // End of file |