javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/ercp/swt/mobile/TextExtension.java
changeset 21 2a9601315dfc
child 35 85266cc22c7f
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2004, 2008 Nokia Corporation and/or its subsidiary(-ies)..
       
     3  * All rights reserved. This program and the accompanying materials 
       
     4  * are made available under the terms of the Eclipse Public License v1.0
       
     5  * which accompanies this distribution, and is available at
       
     6  * http://www.eclipse.org/legal/epl-v10.html
       
     7  * 
       
     8  * Contributors:
       
     9  *     Yu You (Nokia Corp.) - initial API specification
       
    10  *     Nokia Corporation - S60 implementation
       
    11  *     Nokia Corporation - QT implementation
       
    12  *******************************************************************************/
       
    13 package org.eclipse.ercp.swt.mobile;
       
    14 
       
    15 import org.eclipse.swt.*;
       
    16 import org.eclipse.swt.graphics.Point;
       
    17 import org.eclipse.swt.internal.qt.OS;
       
    18 import org.eclipse.swt.internal.qt.PackageProxy;
       
    19 import org.eclipse.swt.internal.qt.QObjectDeleteWrapper;
       
    20 import org.eclipse.swt.internal.qt.SWTExtension;
       
    21 import org.eclipse.swt.internal.qt.TextUtils;
       
    22 import org.eclipse.swt.internal.qt.WidgetState;
       
    23 import org.eclipse.swt.widgets.*;
       
    24 
       
    25 
       
    26 /**
       
    27  * This class contains methods for extending the functionality of the Text
       
    28  * control. The functionality is specific to non-full keyboard devices.
       
    29  * Applications can request certain text input modes when a TextExtension
       
    30  * control gets focused. The effective input mode takes into account two style
       
    31  * aspects. One aspect is based on the content semantics. The other is based on
       
    32  * the content character set.
       
    33  * </p>
       
    34  * <p>
       
    35  * The editing behavior and appearance are otherwise identical to the
       
    36  * <code>Text</code> control. The differences in TextExtension are to ease the
       
    37  * possible switch of initial input modes, such as to enable/disable predictive
       
    38  * input, changing initial casing styles and particular input modes of some
       
    39  * languages. The initial input mode does not persist if changed by the end-user
       
    40  * during editing. Whether the mode will be persist during the application
       
    41  * life-cycle is implementation-dependent.
       
    42  * </p>
       
    43  * 
       
    44  * <dl>
       
    45  * <dt><b>TextExtension Styles: </b></dt>
       
    46  * <dl>
       
    47  * <dt><b>Content Styles (exclusive): </b></dt>
       
    48  * <dd>EMAILADDRESS: an e-mail address</dd>
       
    49  * <dd>URL: a web address</dd>
       
    50  * <p>
       
    51  * These are different semantic styles but basically all characters are allowed
       
    52  * in each style. The implementation may use the content style to implement a
       
    53  * device-dependent UI for assisting user input, for example, providing a UI to
       
    54  * access the device's PIM or browser bookmarks, if available.
       
    55  * </p>
       
    56  * <dt><b>Input Modifier Styles: </b></dt>
       
    57  * <dd>NON_PREDICTIVE: hint for turning off possible predictive text input. By
       
    58  * default any predictive input facilities should be turned on if available
       
    59  * </dd>
       
    60  * <dd>LATIN_INPUT_ONLY: force that locale specific input modes should not be
       
    61  * available. This is used in some situations when only Latin characters are
       
    62  * allowed, for example, password text field</dd>
       
    63  * </dl>
       
    64  * </dl>
       
    65  * <dl>
       
    66  * <dt><b>Casing Modifiers (exclusive): </b> Casing modifiers define which case modes
       
    67  * are available for input. Only one casing modifier may be specified.</dt>
       
    68  * <dd>UPPERCASE: The capital letters of a typeface</dd>
       
    69  * <dd>LOWERCASE: The small letters of a typeface, as opposed to the capital
       
    70  * letters, or uppercase letters</dd>
       
    71  * <dd>TEXTCASE: The first word of a sentence is capitalized. Note:
       
    72  * Determination of where a sentence ends is implementation-dependent.</dd>
       
    73  * <dd>TITLECASE: Every word is capitalized.</dd>
       
    74  * </dl>
       
    75  * <dl>
       
    76  * <dt><b>Events: </b></dt>
       
    77  * <dd>(none)</dd>
       
    78  * </dl>
       
    79  * <p>
       
    80  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
       
    81  * </p>
       
    82  */
       
    83 public class TextExtension extends Text {
       
    84 
       
    85 /**
       
    86  * E-mail address.
       
    87  */
       
    88 public static final int EMAILADDRESS = 1 << 1;
       
    89 
       
    90 /**
       
    91  * Uniform Resource Locator.
       
    92  */
       
    93 public static final int URL = 1 << 2;
       
    94 
       
    95 /**
       
    96  * Hint for turning off predictive text input. By default any predictive
       
    97  * input facilities should be turned on if available.
       
    98  */
       
    99 public static final int NON_PREDICTIVE = 1 << 3;
       
   100 
       
   101 /**
       
   102  * Force that locale specific input modes should not be available.
       
   103  */
       
   104 public static final int LATIN_INPUT_ONLY = 1 << 4;
       
   105 
       
   106 /**
       
   107  * The capital letters of a typeface.
       
   108  */
       
   109 public static final int UPPERCASE = 1;
       
   110 
       
   111 /**
       
   112  * The lower case letters of a typeface.
       
   113  */
       
   114 public static final int LOWERCASE = 2;
       
   115 
       
   116 /**
       
   117  * The first word of each sentence is capitalized.
       
   118  */
       
   119 public static final int TEXTCASE = 3;
       
   120 
       
   121 /**
       
   122  * Every word is capitalized.
       
   123  */
       
   124 public static final int TITLECASE = 4;
       
   125 
       
   126 
       
   127 
       
   128 /*
       
   129  * Input mode.
       
   130  */
       
   131 static final String UCB_BASIC_LATIN = "UCB_BASIC_LATIN";
       
   132 static final String UCB_GREEK = "UCB_GREEK";
       
   133 static final String UCB_CYRILLIC = "UCB_CYRILLIC";
       
   134 static final String UCB_ARMENIAN = "UCB_ARMENIAN";
       
   135 static final String UCB_HEBREW = "UCB_HEBREW";
       
   136 static final String UCB_ARABIC = "UCB_ARABIC";
       
   137 static final String UCB_DEVANAGARI = "UCB_DEVANAGARI";
       
   138 static final String UCB_BENGALI = "UCB_BENGALI";
       
   139 static final String UCB_THAI = "UCB_THAI";
       
   140 static final String UCB_HIRAGANA = "UCB_HIRAGANA";
       
   141 static final String UCB_KATAKANA = "UCB_KATAKANA";
       
   142 static final String UCB_HANGUL_SYLLABLES = "UCB_HANGUL_SYLLABLES";
       
   143 
       
   144 static final String IS_FULLWIDTH_DIGITS = "IS_FULLWIDTH_DIGITS";
       
   145 static final String IS_FULLWIDTH_LATIN = "IS_FULLWIDTH_LATIN";
       
   146 static final String IS_HALFWIDTH_KATAKANA = "HALFWIDTH_KATAKANA";
       
   147 static final String IS_HANJA = "IS_HANJA";
       
   148 static final String IS_KANJI = "IS_KANJI";
       
   149 static final String IS_LATIN = "IS_LATIN";
       
   150 static final String IS_LATIN_DIGITS = "IS_LATIN_DIGITS";
       
   151 static final String IS_SIMPLIFIED_HANZI = "IS_SIMPLIFIED_HANZI";
       
   152 static final String IS_TRADITIONAL_HANZI = "IS_TRADITIONAL_HANZI"; 
       
   153 
       
   154 static final String emailScheme = "mailto:";
       
   155 int inputContext; 
       
   156 private int inputFlags;
       
   157 
       
   158 private boolean serviceDone;
       
   159 private String[] returnedData;
       
   160 
       
   161 
       
   162 /*
       
   163  * Used to store the position and length of selected text
       
   164  */
       
   165 Point lastSelection;
       
   166 
       
   167 static final class TextExtensionPackageProxy extends PackageProxy {
       
   168 public boolean qt_event_keypress( int widgetHandle, int key, int modifier, int character, int nativeScanCode ) {
       
   169     return ((TextExtension)w).qt_event_keypress(widgetHandle, key, modifier, character, nativeScanCode);
       
   170 }
       
   171 public boolean qt_event_keyrelease(int widgetHandle, int key, int modifier, int character, int nativeScanCode) {
       
   172     return ((TextExtension)w).qt_event_keyrelease(widgetHandle, key, modifier, character, nativeScanCode);
       
   173 }
       
   174 public void createHandle (int index) {
       
   175     ((TextExtension)w).createHandle(index);
       
   176 }
       
   177 public void qt_signal_requestCompleted( int value ) {
       
   178     ((TextExtension)w).qt_signal_requestCompleted(value);
       
   179 }
       
   180 public void qt_signal_text_cursorPositionChanged(int oldPos, int newPos) {
       
   181     ((TextExtension)w).qt_signal_text_cursorPositionChanged(oldPos, newPos);
       
   182 }
       
   183 public void qt_signal_text_selectionChanged() {
       
   184     ((TextExtension)w).qt_signal_text_selectionChanged();
       
   185 }
       
   186 public void hookEvents() {
       
   187     ((TextExtension)w).hookEvents();
       
   188 }
       
   189 public String getPhoneNumber() {
       
   190     return ((TextExtension)w).getPhoneNumber();
       
   191 }
       
   192 
       
   193 }
       
   194     
       
   195 /**
       
   196  * Constructs a new instance of <code>Text</code> class when specific
       
   197  * styles are not used.
       
   198  * <p>
       
   199  * The <code>style</code> value is either one of the style constants defined in class
       
   200  * <code>SWT</code> which is applicable to instances of this class, or
       
   201  * must be built by <em>bitwise OR</em> 'ing together (that is, using the
       
   202  * <code>int</code> "|" operator) two or more of those <code>SWT</code>
       
   203  * style constants. Style bits are also inherited from superclasses.
       
   204  * </p>
       
   205  * 
       
   206  * @param parent
       
   207  *            a composite control which will be the parent of the new
       
   208  *            instance (cannot be null)
       
   209  * @param style
       
   210  *            the style of control to construct
       
   211  * 
       
   212  * @exception IllegalArgumentException
       
   213  *                <ul>
       
   214  *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
       
   215  *                </ul>
       
   216  * @exception SWTException
       
   217  *                <ul>
       
   218  *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
       
   219  *                thread that created the parent</li>
       
   220  *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
       
   221  *                allowed subclass</li>
       
   222  *                </ul>
       
   223  * 
       
   224  * @see SWT#SINGLE
       
   225  * @see SWT#MULTI
       
   226  * @see SWT#READ_ONLY
       
   227  * @see SWT#WRAP
       
   228  * @see org.eclipse.swt.widgets.Text#Text(Composite, int)
       
   229  */
       
   230 public TextExtension(Composite parent, int style) {
       
   231     this(parent, style, 0);
       
   232 }
       
   233 
       
   234 /**
       
   235  * Constructs a new instance of this class given its parent, a style value
       
   236  * describing behaviour and appearance, and an additional style specifying
       
   237  * the text types defined above.
       
   238  * <p>
       
   239  * The <code>style</code> value is either one of the style constants defined 
       
   240  * in class <code>SWT</code> which is applicable to instances of this class, or
       
   241  * must be built by <em>bitwise OR</em> 'ing together (that is, using the
       
   242  * <code>int</code> "|" operator) two or more of those <code>SWT</code>
       
   243  * style constants. Style bits are also inherited from superclasses.
       
   244  * </p>
       
   245  * <p>
       
   246  * The <code>extensionStyle</code> value is a <em>bitwise OR</em> 'ing of 
       
   247  * EMAILADDRESS, URL, NON_PREDICTIVE, and LATIN_INPUT_ONLY. EMAILADDRESS and 
       
   248  * URL may not be both specified. The <code>extensionStyle</code> value is ignored 
       
   249  * when <code>SWT.READ_ONLY</code> is specified in the <code>style</code> value.
       
   250  * </p>
       
   251  * 
       
   252  * @param parent
       
   253  *            a composite control which is the parent of the new instance
       
   254  *            (cannot be null)
       
   255  * @param style
       
   256  *            the style of control to construct
       
   257  * @param extensionStyle
       
   258  *            the TextExtension specific style.
       
   259  * 
       
   260  * @exception IllegalArgumentException
       
   261  *                <ul>
       
   262  *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
       
   263  *                <li>ERROR_INVALID_ARGUMENT - if either the style or the
       
   264  *                extensionStyle is invalid</li>
       
   265  *                </ul>
       
   266  * @exception SWTException
       
   267  *                <ul>
       
   268  *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
       
   269  *                thread that created the parent</li>
       
   270  *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
       
   271  *                allowed subclass</li>
       
   272  *                </ul>
       
   273  * @see SWT#SINGLE
       
   274  * @see SWT#MULTI
       
   275  * @see SWT#READ_ONLY
       
   276  * @see SWT#WRAP
       
   277  * @see org.eclipse.swt.widgets.Text#Text(Composite, int)
       
   278  */
       
   279 public TextExtension(Composite parent, int style, int extensionStyle) {
       
   280     this(parent, style, extensionStyle, false);
       
   281 }
       
   282 
       
   283 /**
       
   284  * <p>
       
   285  * <b>IMPORTANT:</b> This constructor is <em>not</em> part of the SWT
       
   286  * public API. It should never be referenced from application code. 
       
   287  * </p>
       
   288  */
       
   289 protected TextExtension(Composite parent, int style, int extensionStyle, boolean isExtended) {
       
   290     super(parent, checkStyle(style, extensionStyle), extensionStyle, 
       
   291             new TextExtensionPackageProxy(), isExtended);
       
   292     if ((extraStyle() & LATIN_INPUT_ONLY) != 0) {
       
   293             // create a new latin input context
       
   294             // because the default input context can be something else
       
   295             int newInputContext = OS.QInputContextFactory_create(
       
   296                     OS.QINPUTCONTEXT_COEFEP, topHandle());
       
   297             OS.QWidget_setInputContext(topHandle(), newInputContext);
       
   298             inputContext = newInputContext;
       
   299         } else {
       
   300             int handle = Internal_PackageSupport.handle(this);
       
   301             OS.QWidget_setAttribute(handle, OS.QT_WA_INPUTMETHODENABLED, true);
       
   302         }
       
   303    
       
   304     if ((extraStyle() & NON_PREDICTIVE) != 0) {
       
   305     	inputFlags |= OS.QT_IMHNOPREDICTIVETEXT;
       
   306         }
       
   307 
       
   308     String cmdTxt = null;
       
   309     if ((extraStyle() & EMAILADDRESS) != 0) {
       
   310         cmdTxt = SWT.getMessage("fetch_email");
       
   311         inputFlags |= OS.QT_IMHEMAILCHARACTERSONLY;
       
   312         addCommand(cmdTxt);
       
   313     } else if ((extraStyle() & URL) != 0) {
       
   314         cmdTxt = SWT.getMessage("fetch_url");
       
   315         inputFlags |= OS.QT_IMHURLCHARACTERSONLY;
       
   316         addCommand(cmdTxt);
       
   317     } 
       
   318     
       
   319     if ((extraStyle() & ( NON_PREDICTIVE | URL | EMAILADDRESS)) != 0) {
       
   320     	inputFlags |= OS.QT_IMHNOPREDICTIVETEXT;
       
   321     	OS.QWidget_setInputMethodHints(topHandle(), inputFlags);
       
   322     }
       
   323 }
       
   324 
       
   325 void addCommand(String str) {
       
   326     Command cmd = new Command(this, Command.GENERAL, 0);
       
   327     cmd.setText(str);
       
   328     cmd.addListener(SWT.Selection, new Listener() {
       
   329         public void handleEvent(Event event) {
       
   330             if ((extraStyle() & EMAILADDRESS) != 0) {
       
   331                 String email = fetchEmail();
       
   332                 if (email != null) {
       
   333                     setText(email);
       
   334                 }
       
   335             } else if ((extraStyle() & URL) != 0) {
       
   336                 fetchUrl();
       
   337             }
       
   338         }
       
   339     });
       
   340 }
       
   341 
       
   342 String fetchEmail() {
       
   343 
       
   344     int serviceRequest = OS.XQServiceRequest_new(
       
   345             "com.nokia.services.phonebookservices.Fetch",
       
   346             "fetch(QString,QString,QString)", false);
       
   347     if (serviceRequest <= 0) {
       
   348         return null;
       
   349     }
       
   350     OS.XQServiceRequest_swt_setArgumentsForFetchEmail(serviceRequest,
       
   351                     SWT.getMessage("fetch_email"), OS.CNT_ACTIONALL,
       
   352                     OS.CNT_DISPLAYALL);
       
   353     Display display = Internal_PackageSupport.display(this);
       
   354     int handler = OS.SignalHandler_new(topHandle(), display,
       
   355             OS.QSIGNAL_REQUESTCOMPLETED);
       
   356 
       
   357     OS.QObject_connectOrThrow(serviceRequest, "requestCompleted(QVariant)",
       
   358             handler, "widgetSignal(QVariant)", OS.QT_AUTOCONNECTION);
       
   359     boolean success = OS.XQServiceRequest_send(serviceRequest);
       
   360     if (success) {
       
   361         serviceDone = false;
       
   362         while (!serviceDone) {
       
   363             if (display.readAndDispatch() == false) {
       
   364                 display.sleep();
       
   365             }
       
   366         }
       
   367         if (returnedData != null) {
       
   368             String email = returnedData[2];
       
   369             returnedData = null;
       
   370             QObjectDeleteWrapper.deleteSafely(handler);
       
   371             QObjectDeleteWrapper.deleteSafely(serviceRequest);
       
   372             return email;
       
   373         }
       
   374     }
       
   375     QObjectDeleteWrapper.deleteSafely(handler);
       
   376     QObjectDeleteWrapper.deleteSafely(serviceRequest);
       
   377     return null;
       
   378 }
       
   379 
       
   380 String getPhoneNumber() {
       
   381 
       
   382     int serviceRequest = OS.XQServiceRequest_new(
       
   383             "com.nokia.services.phonebookservices.Fetch",
       
   384             "fetch(QString,QString,QString)", false);
       
   385     if (serviceRequest <= 0) {
       
   386         return null;
       
   387     }
       
   388     OS.XQServiceRequest_swt_setArgumentsForFetchEmail(serviceRequest,
       
   389                     SWT.getMessage("fetch_phonenumber"), OS.CNT_ACTIONALL,
       
   390                     OS.CNT_DISPLAYALL);
       
   391     Display display = Internal_PackageSupport.display(this);
       
   392     int handler = OS.SignalHandler_new(topHandle(), display,
       
   393             OS.QSIGNAL_REQUESTCOMPLETED);
       
   394 
       
   395     OS.QObject_connectOrThrow(serviceRequest, "requestCompleted(QVariant)",
       
   396             handler, "widgetSignal(QVariant)", OS.QT_AUTOCONNECTION);
       
   397     boolean success = OS.XQServiceRequest_send(serviceRequest);
       
   398     if (success) {
       
   399         serviceDone = false;
       
   400         while (!serviceDone) {
       
   401             if (display.readAndDispatch() == false) {
       
   402                 display.sleep();
       
   403             }
       
   404         }
       
   405         if (returnedData != null) {
       
   406             String email = returnedData[1];
       
   407             returnedData = null;
       
   408             QObjectDeleteWrapper.deleteSafely(handler);
       
   409             QObjectDeleteWrapper.deleteSafely(serviceRequest);
       
   410             return email;
       
   411         }
       
   412     }
       
   413     QObjectDeleteWrapper.deleteSafely(handler);
       
   414     QObjectDeleteWrapper.deleteSafely(serviceRequest);
       
   415     return null;
       
   416 }
       
   417 
       
   418 
       
   419 private void fetchUrl(){
       
   420 // TODO: implement fetching bookmarks when relevant service is available.
       
   421 }
       
   422 
       
   423 private static int checkStyle(int style, int extensionStyle) {
       
   424     if ((style & SWT.READ_ONLY) != 0) {
       
   425         // ignore extension styles
       
   426         extensionStyle = 0;
       
   427     }
       
   428 
       
   429     // Check extension style is only made of valid bits
       
   430     if ((extensionStyle & ~(EMAILADDRESS | URL | NON_PREDICTIVE | LATIN_INPUT_ONLY)) != 0) {
       
   431         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
   432     }
       
   433     // Cannot have EMAILADDRESS and URL at the same time
       
   434     if ((extensionStyle & (EMAILADDRESS | URL)) == (EMAILADDRESS | URL)) {
       
   435         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
   436     }
       
   437     // EMAILADDRES or URL force single line
       
   438     if ((extensionStyle & (EMAILADDRESS | URL)) != 0) {
       
   439         style |= SWT.SINGLE;
       
   440     }
       
   441 
       
   442     return style;
       
   443 }
       
   444 
       
   445 void createHandle (int index) {
       
   446     if(isExtended()) {
       
   447         lastSelection = new Point(0,0);
       
   448     }
       
   449     
       
   450     // QT's single line editor is not capable of handling char formatting
       
   451     int variant = (getStyle() & SWT.PASSWORD) != 0 ? TextUtils.LINE_EDIT : TextUtils.TEXT_EDIT;
       
   452     Internal_PackageSupport.setVariant(this, variant);
       
   453     
       
   454     Internal_PackageSupport.createHandle(this, index);
       
   455 }
       
   456 
       
   457 void hookEvents () {
       
   458     Internal_PackageSupport.hookEvents(this);
       
   459     if(isExtended()) {
       
   460         Display display = Internal_PackageSupport.display(this);
       
   461         int handler1 = OS.SignalHandler_new(topHandle(), display, OS.QSIGNAL_TEXT_CURSORPOSITIONCHANGED);
       
   462         String s;
       
   463         if(Internal_PackageSupport.variant(this) == TextUtils.LINE_EDIT) {
       
   464         	s = "cursorPositionChanged(int, int)";         	
       
   465         } else {
       
   466         	s = "cursorPositionChanged()"; 
       
   467         }
       
   468         OS.QObject_connectOrThrow(topHandle(), s,
       
   469             handler1, "widgetSignal()", OS.QT_AUTOCONNECTION);
       
   470         int handler2 = OS.SignalHandler_new(topHandle(), display, OS.QSIGNAL_TEXT_SELECTIONCHANGED);
       
   471         OS.QObject_connectOrThrow(topHandle(), "selectionChanged()",
       
   472             handler2, "widgetSignal()", OS.QT_AUTOCONNECTION);
       
   473     }
       
   474 }
       
   475 
       
   476 String inputContextKey(String mode) {
       
   477     if (mode == null || mode.length() < 1)
       
   478         return null;
       
   479     String strMode = mode.trim().toUpperCase();
       
   480     String key = null;
       
   481     if (strMode.equals(UCB_BASIC_LATIN)) {
       
   482         key = OS.QINPUTCONTEXT_COEFEP;
       
   483     } else if (mode.equals(IS_FULLWIDTH_DIGITS)) {
       
   484         key = OS.QINPUTCONTEXT_COEFEP;
       
   485     } else if (mode.equals(IS_FULLWIDTH_LATIN)) {
       
   486         key = OS.QINPUTCONTEXT_COEFEP;
       
   487     } else if (strMode.equals(IS_LATIN)) {
       
   488         key = OS.QINPUTCONTEXT_COEFEP;
       
   489     } else if (mode.equals(IS_LATIN_DIGITS)) {
       
   490         key = OS.QINPUTCONTEXT_COEFEP;
       
   491     } else {
       
   492         String lang = language(strMode);
       
   493         if (lang != null) {
       
   494             key = OS.QInputContextFactory_swt_key(lang);
       
   495         }
       
   496     }
       
   497     return key;
       
   498 }
       
   499 
       
   500 private final boolean isExtended() {
       
   501     return ((Internal_PackageSupport.state(this) & WidgetState.IS_EXTENDED) != 0);
       
   502 }
       
   503 
       
   504 String language(String mode) {
       
   505     String lang = null;
       
   506     if (mode.equals(UCB_GREEK)) {
       
   507         lang = "el";
       
   508     } else if (mode.equals(UCB_CYRILLIC)) {
       
   509         lang = "sr";
       
   510     } else if (mode.equals(UCB_ARMENIAN)) {
       
   511         lang = "hy";
       
   512     } else if (mode.equals(UCB_HEBREW)) {
       
   513         lang = "he";
       
   514     } else if (mode.equals(UCB_ARABIC)) {
       
   515         lang = "ar";
       
   516     } else if (mode.equals(UCB_DEVANAGARI)) {
       
   517         lang = "hi";
       
   518     } else if (mode.equals(UCB_BENGALI)) {
       
   519         lang = "bn";
       
   520     } else if (mode.equals(UCB_THAI)) {
       
   521         lang = "th";
       
   522     } else if (mode.equals(UCB_HIRAGANA)) {
       
   523         lang = "ja";
       
   524     } else if (mode.equals(UCB_KATAKANA)) {
       
   525         lang = "ja";
       
   526     } else if (mode.equals(UCB_HANGUL_SYLLABLES)) {
       
   527         lang = "ko";
       
   528     } else if (mode.equals(IS_HALFWIDTH_KATAKANA)) {
       
   529         lang = "ja";
       
   530     } else if (mode.equals(IS_HANJA)) {
       
   531         lang = "ko";
       
   532     } else if (mode.equals(IS_KANJI)) {
       
   533         lang = "ja";
       
   534     } else if (mode.equals(IS_SIMPLIFIED_HANZI)) {
       
   535         lang = "zh-CN;zh-SG";
       
   536     } else if (mode.equals(IS_TRADITIONAL_HANZI)) {
       
   537         lang = "zh-TW;zh-HK";
       
   538     }
       
   539     return lang;
       
   540 }
       
   541 
       
   542 /**
       
   543  * Hints to the implementation as to the input mode that should be used when
       
   544  * the user initiates editing of this control.
       
   545  * 
       
   546  * <h3>Input mode string format</h3>
       
   547  * <p>
       
   548  * The initial input mode is specified as a string and can be null. A
       
   549  * "Unicode character block" may be specified by adding the prefix "UCB_" to
       
   550  * the names of Unicode character blocks as defined in the J2SE class
       
   551  * <code>java.lang.Character.UnicodeBlock</code>. Any Unicode character
       
   552  * block can be named in this fashion. For convenience, the most common
       
   553  * Unicode character blocks are listed below.
       
   554  * </p>
       
   555  * <blockquote><code>
       
   556  * UCB_BASIC_LATIN<br>UCB_GREEK<br>UCB_CYRILLIC<br>UCB_ARMENIAN<br>UCB_HEBREW<br>
       
   557  * UCB_ARABIC<br>UCB_DEVANAGARI<br>UCB_BENGALI<br>UCB_THAI<br>UCB_HIRAGANA<br>UCB_KATAKANA<br>
       
   558  * UCB_HANGUL_SYLLABLES<br></code> </blockquote>
       
   559  * 
       
   560  * <p>
       
   561  * An "Input subset" may be specified by adding the prefix "IS_" to the name
       
   562  * of input subsets as defined by the J2SE class
       
   563  * <code>java.awt.im.InputSubset</code>. Any defined input subset can be
       
   564  * used. For convenience, the names of the currently defined input subsets
       
   565  * are listed below.
       
   566  * </p>
       
   567  * <blockquote><code>
       
   568  * IS_FULLWIDTH_DIGITS<BR>IS_FULLWIDTH_LATIN<BR>IS_HALFWIDTH_KATAKANA<BR>IS_HANJA<br>
       
   569  * IS_KANJI<BR>IS_LATIN<BR>IS_LATIN_DIGITS<BR>IS_SIMPLIFIED_HANZI<BR>IS_TRADITIONAL_HANZI
       
   570  * </code> </blockquote>
       
   571  * <p>
       
   572  * Note: Implementations need not compile in support for all the strings
       
   573  * listed above. Instead, they need only to compile in the strings that name
       
   574  * Unicode character subsets that they support. If the subset name passed by
       
   575  * the application is not known by the implementation, the request is
       
   576  * gracefully ignored, and a default input mode based on current locale
       
   577  * configuration is used.
       
   578  * </p>
       
   579  * 
       
   580  * @param mode
       
   581  *            a string naming a Unicode character block, input subset, or
       
   582  *            null
       
   583  * 
       
   584  * @param casingModifier
       
   585  *            an int value. Must be one of UPPERCASE, LOWERCASE, TEXTCASE or
       
   586  *            TITLECASE.
       
   587  * 
       
   588  * @exception IllegalArgumentException
       
   589  *                <ul>
       
   590  *                <li>ERROR_INVALID_ARGUMENT - if the casingModifer is not
       
   591  *                one of UPPERCASE, LOWERCASE, TEXTCASE or TITLECASE</li>
       
   592  *                </ul>
       
   593  * @exception SWTException
       
   594  *                <ul>
       
   595  *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
       
   596  *                disposed</li>
       
   597  *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
       
   598  *                thread that created the receiver</li>
       
   599  *                </ul>
       
   600  */
       
   601 public void setInitialInputMode(int casingModifier, String mode) {
       
   602     checkWidget();
       
   603     if ((Internal_PackageSupport.style(this) & SWT.READ_ONLY) != 0)
       
   604         return;
       
   605 
       
   606     if ((extraStyle() & LATIN_INPUT_ONLY) == 0) {
       
   607         String key = inputContextKey(mode);
       
   608         int newInputContext = 0;
       
   609         if (key != null) {
       
   610             newInputContext = OS.QInputContextFactory_create(key,
       
   611                     topHandle());
       
   612         }
       
   613         if (newInputContext != 0 || inputContext != 0) {
       
   614             // OS.QWidget_setInputContext also deletes input context
       
   615             // which was set previously
       
   616             OS.QWidget_setInputContext(topHandle(),
       
   617                     newInputContext);
       
   618         }
       
   619         inputContext = newInputContext;
       
   620     }
       
   621 
       
   622     if (variant() == TextUtils.LINE_EDIT) {
       
   623         return;
       
   624     }
       
   625 
       
   626     switch (casingModifier) {
       
   627     case LOWERCASE:
       
   628         inputFlags |= OS.QT_IMHPREFERLOWERCASE;
       
   629         break;
       
   630     case UPPERCASE:
       
   631         inputFlags |= OS.QT_IMHPREFERUPPERCASE;
       
   632         break;
       
   633     case TEXTCASE:
       
   634 //        nativeCasing = OS.QFONT_MIXEDCASE;
       
   635         break;
       
   636     case TITLECASE:
       
   637 //        inputFlags |= OS.QT_IMHNOAUTOUPPERCASE;
       
   638         break;
       
   639     default:
       
   640         SWT.error(SWT.ERROR_INVALID_ARGUMENT);
       
   641         break;
       
   642     }
       
   643     
       
   644     OS.QWidget_setInputMethodHints(topHandle(), inputFlags);
       
   645 }
       
   646 
       
   647 boolean qt_event_keypress(int widgetHandle, int key, int modifier, int character, int nativeScanCode) {
       
   648     return Internal_PackageSupport.qt_event_keypress(this, widgetHandle, key, modifier, character, nativeScanCode);
       
   649 }
       
   650 
       
   651 boolean qt_event_keyrelease(int widgetHandle, int key, int modifier, int character, int nativeScanCode) {
       
   652     if ((getStyle() & SWT.SINGLE) != 0 && (key == OS.QT_KEY_RETURN || key == OS.QT_KEY_ENTER)) {
       
   653         Internal_PackageSupport.sendEvent(this, SWT.DefaultSelection);
       
   654     }
       
   655     return Internal_PackageSupport.qt_event_keyrelease(this, widgetHandle, key, modifier, character, nativeScanCode);
       
   656 }
       
   657 
       
   658 
       
   659 void qt_signal_requestCompleted( int value ) {
       
   660     
       
   661     if (value < 1) {
       
   662         serviceDone = true;
       
   663         return;
       
   664     }
       
   665     returnedData = OS.CntServicesContactList_swt_contacts(value);
       
   666     serviceDone = true;
       
   667 }
       
   668 
       
   669 /*
       
   670  * Extended TextExtension sends CaretMoved events
       
   671  */ 
       
   672 void qt_signal_text_cursorPositionChanged(int oldPos, int newPos) {
       
   673     if(isExtended()) {
       
   674         // For QTextEdit the signature for cursorPositionChanged is 
       
   675         // cursorPositionChanged(), so we cannot rely on the information in the
       
   676         // signal
       
   677         Event event = new Event();
       
   678         event.x = TextUtils.getCaretPosition(variant(), topHandle());
       
   679         Internal_PackageSupport.sendEvent(this, SWTExtension.CaretMoved, event);
       
   680     }
       
   681     Internal_PackageSupport.qt_signal_text_cursorPositionChanged(this, oldPos, newPos);
       
   682 }
       
   683 
       
   684 /*
       
   685  * Extended TextExtension sends ContentSelected events
       
   686  */ 
       
   687 void qt_signal_text_selectionChanged() {
       
   688     if(isExtended()) {
       
   689         Point selection = TextUtils.getSelection(variant(), topHandle());
       
   690         int length = selection.y - selection.x;
       
   691         
       
   692         // Qt sends selectionChanged signals when user drags on the text, even
       
   693         // if there the selection content does not change. Filter out excessive 
       
   694         // events here.
       
   695         if (lastSelection.y - lastSelection.x != length) {
       
   696             lastSelection = selection;
       
   697     
       
   698             Event event = new Event();
       
   699             event.x = selection.x;
       
   700             event.count = length;
       
   701             Internal_PackageSupport.sendEvent(this, SWTExtension.ContentSelected, event);
       
   702         }
       
   703     }
       
   704     Internal_PackageSupport.qt_signal_text_selectionChanged(this);
       
   705 }
       
   706 
       
   707 
       
   708 private final int topHandle() {
       
   709     return Internal_PackageSupport.topHandle(this);
       
   710 }
       
   711 
       
   712 private final int extraStyle() {
       
   713     return Internal_PackageSupport.extraStyle(this);    
       
   714 }
       
   715 
       
   716 private final int variant() {
       
   717     return Internal_PackageSupport.variant(this);
       
   718 }
       
   719 }