javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/swt/widgets/Text.java
changeset 21 2a9601315dfc
child 35 85266cc22c7f
equal deleted inserted replaced
18:e8e63152f320 21:2a9601315dfc
       
     1 /*******************************************************************************
       
     2  * Copyright (c) 2000, 2007 IBM Corporation and others.
       
     3  * Portion Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     4  * All rights reserved. This program and the accompanying materials
       
     5  * are made available under the terms of the Eclipse Public License v1.0
       
     6  * which accompanies this distribution, and is available at
       
     7  * http://www.eclipse.org/legal/epl-v10.html
       
     8  *
       
     9  * Contributors:
       
    10  *     IBM Corporation - initial API and implementation
       
    11  *     Nokia Corporation - Qt implementation
       
    12  *******************************************************************************/
       
    13 package org.eclipse.swt.widgets;
       
    14 
       
    15 
       
    16 import org.eclipse.swt.SWT;
       
    17 import org.eclipse.swt.internal.qt.OS;
       
    18 import org.eclipse.swt.internal.qt.TextUtils;
       
    19 import org.eclipse.swt.internal.qt.WidgetConstant;
       
    20 import org.eclipse.swt.internal.qt.WidgetState;
       
    21 import org.eclipse.swt.graphics.Image;
       
    22 import org.eclipse.swt.graphics.Point;
       
    23 import org.eclipse.swt.graphics.Rectangle;
       
    24 import org.eclipse.swt.events.ModifyListener;
       
    25 import org.eclipse.swt.events.SelectionListener;
       
    26 import org.eclipse.swt.events.VerifyListener;
       
    27 
       
    28 /**
       
    29  * Instances of this class are selectable user interface
       
    30  * objects that allow the user to enter and modify text.
       
    31  * <p>
       
    32  * <dl>
       
    33  * <dt><b>Styles:</b></dt>
       
    34  * <dd>CANCEL, CENTER, LEFT, MULTI, PASSWORD, SEARCH, SINGLE, RIGHT, READ_ONLY, WRAP</dd>
       
    35  * <dt><b>Events:</b></dt>
       
    36  * <dd>DefaultSelection, Modify, Verify</dd>
       
    37  * </dl>
       
    38  * <p>
       
    39  * Note: Only one of the styles MULTI and SINGLE may be specified,
       
    40  * and only one of the styles LEFT, CENTER, and RIGHT may be specified.
       
    41  * </p><p>
       
    42  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
       
    43  * </p>
       
    44  */
       
    45 public class Text extends Scrollable {
       
    46 
       
    47     /*
       
    48      *  The text limit set by the application. In MULTI case limiting for the text length 
       
    49      *  is implemented on Java side as QTextEdit does not have support for it. 
       
    50      */
       
    51     private int textLimit;
       
    52     
       
    53     /*
       
    54      * The double click enabled flag.
       
    55      */
       
    56     private boolean doubleClick;
       
    57     
       
    58     int variant;
       
    59         
       
    60     /**
       
    61     * The maximum number of characters that can be entered
       
    62     * into a text widget.
       
    63     * <p>
       
    64     * Note that this value is platform dependent, based upon
       
    65     * the native widget implementation.
       
    66     * </p>
       
    67     */
       
    68     public final static int LIMIT;
       
    69     
       
    70     /**
       
    71     * The delimiter used by multi-line text widgets.  When text
       
    72     * is queried and from the widget, it will be delimited using
       
    73     * this delimiter.
       
    74     */
       
    75     public final static String DELIMITER;
       
    76     
       
    77     /*
       
    78     * These values can be different on different platforms.
       
    79     * Therefore they are not initialized in the declaration
       
    80     * to stop the compiler from inlining.
       
    81     */
       
    82     static {
       
    83         LIMIT = 0x7FFFFFFF;
       
    84         DELIMITER = "\n";
       
    85     }
       
    86 
       
    87 /**
       
    88  * Constructs a new instance of this class given its parent
       
    89  * and a style value describing its behavior and appearance.
       
    90  * <p>
       
    91  * The style value is either one of the style constants defined in
       
    92  * class <code>SWT</code> which is applicable to instances of this
       
    93  * class, or must be built by <em>bitwise OR</em>'ing together 
       
    94  * (that is, using the <code>int</code> "|" operator) two or more
       
    95  * of those <code>SWT</code> style constants. The class description
       
    96  * lists the style constants that are applicable to the class.
       
    97  * Style bits are also inherited from superclasses.
       
    98  * </p>
       
    99  *
       
   100  * @param parent a composite control which will be the parent of the new instance (cannot be null)
       
   101  * @param style the style of control to construct
       
   102  *
       
   103  * @exception IllegalArgumentException <ul>
       
   104  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
       
   105  * </ul>
       
   106  * @exception SWTException <ul>
       
   107  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
       
   108  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
       
   109  * </ul>
       
   110  *
       
   111  * @see SWT#SINGLE
       
   112  * @see SWT#MULTI
       
   113  * @see SWT#READ_ONLY
       
   114  * @see SWT#WRAP
       
   115  * @see Widget#checkSubclass
       
   116  * @see Widget#getStyle
       
   117  */
       
   118 public Text (Composite parent, int style) {
       
   119     this(parent, style, 0, null, false);
       
   120 }
       
   121 
       
   122 /**
       
   123  * <p>
       
   124  * <b>IMPORTANT:</b> This constructor is <em>not</em> part of the SWT
       
   125  * public API. It should never be referenced from application code. 
       
   126  * </p>
       
   127  */
       
   128 protected Text (Composite parent, int style, int extraStyle, Object packageProxy, boolean isExtended) {
       
   129     super (parent, checkStyle (style), extraStyle, packageProxy, isExtended);
       
   130 }
       
   131 
       
   132 static int checkStyle (int style) {
       
   133     if ((style & SWT.SINGLE) != 0 && (style & SWT.MULTI) != 0) {
       
   134         style &= ~SWT.MULTI;
       
   135     }
       
   136     style = checkBits (style, SWT.LEFT, SWT.CENTER, SWT.RIGHT, 0, 0, 0);
       
   137     if ((style & SWT.SINGLE) != 0) style &= ~(SWT.H_SCROLL | SWT.V_SCROLL | SWT.WRAP);
       
   138     if ((style & SWT.WRAP) != 0) {
       
   139         style |= SWT.MULTI;
       
   140         style &= ~SWT.H_SCROLL;
       
   141     }
       
   142     if ((style & SWT.MULTI) != 0) style &= ~SWT.PASSWORD;
       
   143     if ((style & (SWT.SINGLE | SWT.MULTI)) != 0) return style;
       
   144     if ((style & (SWT.H_SCROLL | SWT.V_SCROLL)) != 0) return style | SWT.MULTI;
       
   145     return style | SWT.SINGLE;
       
   146 }
       
   147 
       
   148 void createHandle_pp (int index) {
       
   149     if(variant == 0) {
       
   150         variant = ((getStyle() & SWT.SINGLE) != 0 ? TextUtils.LINE_EDIT : TextUtils.TEXT_EDIT);
       
   151     }
       
   152     
       
   153     int alignment = OS.QT_ALIGNLEFT;
       
   154     if ((style & SWT.CENTER) != 0) { 
       
   155         alignment = OS.QT_ALIGNHCENTER; 
       
   156     } else if ((style & SWT.RIGHT) != 0) {
       
   157         alignment = OS.QT_ALIGNRIGHT;
       
   158     }
       
   159     
       
   160     if (variant == TextUtils.LINE_EDIT) {
       
   161         
       
   162         scrollAreaHandle = 0;
       
   163         topHandle = handle = OS.QLineEdit_new();
       
   164         
       
   165         OS.QLineEdit_setAlignment(handle, alignment | OS.QT_ALIGNVCENTER);
       
   166         OS.QLineEdit_setMaxLength(handle, LIMIT);
       
   167         
       
   168         if ((style & SWT.PASSWORD) != 0) {
       
   169             OS.QLineEdit_setEchoMode(handle, OS.QLINEEDIT_ECHOMODE_PASSWORD);
       
   170         }
       
   171         
       
   172     } else {
       
   173         
       
   174         frameHandle = topHandle = scrollAreaHandle = OS.QTextEdit_new();
       
   175         handle = OS.QAbstractScrollArea_viewPort(scrollAreaHandle);
       
   176         
       
   177         OS.QTextEdit_setAlignment(scrollAreaHandle, alignment);
       
   178         
       
   179         forceTextLayout();
       
   180     }
       
   181     
       
   182     OS.QWidget_setGeometry(topHandle, 0, 0, 0, 0);
       
   183     
       
   184     state |= WidgetState.HANDLE;
       
   185     
       
   186     if ((style & SWT.READ_ONLY) != 0) {
       
   187         setEditable(false);
       
   188     }
       
   189 }
       
   190 
       
   191 void createWidget (int index) {
       
   192     super.createWidget(index);
       
   193     doubleClick = true;
       
   194     textLimit = 0;
       
   195 }
       
   196 
       
   197 /**
       
   198  * Adds the listener to the collection of listeners who will
       
   199  * be notified when the receiver's text is modified, by sending
       
   200  * it one of the messages defined in the <code>ModifyListener</code>
       
   201  * interface.
       
   202  *
       
   203  * @param listener the listener which should be notified
       
   204  *
       
   205  * @exception IllegalArgumentException <ul>
       
   206  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
       
   207  * </ul>
       
   208  * @exception SWTException <ul>
       
   209  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   210  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   211  * </ul>
       
   212  *
       
   213  * @see ModifyListener
       
   214  * @see #removeModifyListener
       
   215  */
       
   216 public void addModifyListener(ModifyListener listener) {
       
   217     checkWidget();
       
   218     if (listener == null) {
       
   219         error(SWT.ERROR_NULL_ARGUMENT);
       
   220     }
       
   221     TypedListener typedListener = new TypedListener(listener);
       
   222     addListener(SWT.Modify, typedListener);
       
   223 }
       
   224 
       
   225 /**
       
   226  * Adds the listener to the collection of listeners who will
       
   227  * be notified when the control is selected by the user, by sending
       
   228  * it one of the messages defined in the <code>SelectionListener</code>
       
   229  * interface.
       
   230  * <p>
       
   231  * <code>widgetSelected</code> is not called for texts.
       
   232  * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text,
       
   233  * or when ENTER is pressed in a search text. If the receiver has the <code>SWT.SEARCH | SWT.CANCEL</code> style
       
   234  * and the user cancels the search, the event object detail field contains the value <code>SWT.CANCEL</code>.
       
   235  * </p>
       
   236  *
       
   237  * @param listener the listener which should be notified when the control is selected by the user
       
   238  *
       
   239  * @exception IllegalArgumentException <ul>
       
   240  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
       
   241  * </ul>
       
   242  * @exception SWTException <ul>
       
   243  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   244  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   245  * </ul>
       
   246  *
       
   247  * @see SelectionListener
       
   248  * @see #removeSelectionListener
       
   249  * @see SelectionEvent
       
   250  */
       
   251 public void addSelectionListener(SelectionListener listener) {
       
   252     checkWidget ();
       
   253     if (listener == null) { 
       
   254         error(SWT.ERROR_NULL_ARGUMENT);
       
   255     }
       
   256     TypedListener typedListener = new TypedListener(listener);
       
   257     addListener(SWT.Selection,typedListener);
       
   258     addListener(SWT.DefaultSelection,typedListener);
       
   259 }
       
   260 
       
   261 /**
       
   262  * Adds the listener to the collection of listeners who will
       
   263  * be notified when the receiver's text is verified, by sending
       
   264  * it one of the messages defined in the <code>VerifyListener</code>
       
   265  * interface.
       
   266  *
       
   267  * @param listener the listener which should be notified
       
   268  *
       
   269  * @exception IllegalArgumentException <ul>
       
   270  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
       
   271  * </ul>
       
   272  * @exception SWTException <ul>
       
   273  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   274  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   275  * </ul>
       
   276  *
       
   277  * @see VerifyListener
       
   278  * @see #removeVerifyListener
       
   279  */
       
   280 public void addVerifyListener(VerifyListener listener) {
       
   281     checkWidget();
       
   282     if (listener == null) {
       
   283         error(SWT.ERROR_NULL_ARGUMENT);
       
   284     }
       
   285     TypedListener typedListener = new TypedListener(listener);
       
   286     addListener(SWT.Verify, typedListener);
       
   287 }
       
   288 
       
   289 /**
       
   290  * Appends a string.
       
   291  * <p>
       
   292  * The new text is appended to the text at
       
   293  * the end of the widget.
       
   294  * </p>
       
   295  *
       
   296  * @param string the string to be appended
       
   297  *
       
   298  * @exception IllegalArgumentException <ul>
       
   299  *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
   300  * </ul>
       
   301  * @exception SWTException <ul>
       
   302  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   303  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   304  * </ul>
       
   305  */
       
   306 public void append (String string) {
       
   307     checkWidget();
       
   308     TextUtils.append(variant, topHandle, string, textLimit, this);
       
   309 }
       
   310 
       
   311 void checkBorder_pp () {
       
   312     super.checkBorder_pp();
       
   313     if (variant == TextUtils.LINE_EDIT) {
       
   314         OS.QLineEdit_setFrame(topHandle, (style & SWT.BORDER) != 0);
       
   315     }
       
   316 }
       
   317 
       
   318 /**
       
   319  * Clears the selection.
       
   320  *
       
   321  * @exception SWTException <ul>
       
   322  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   323  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   324  * </ul>
       
   325  */
       
   326 public void clearSelection () {
       
   327     checkWidget();
       
   328     TextUtils.clearSelection(variant, topHandle);
       
   329 }
       
   330 
       
   331     public Point computeSize(int wHint, int hHint, boolean changed) {
       
   332         checkWidget();
       
   333 
       
   334         if (changed) {
       
   335             OS.QWidget_updateGeometry(topHandle);
       
   336         }
       
   337 
       
   338         if (wHint != SWT.DEFAULT && wHint < 0)
       
   339             wHint = SWT.DEFAULT;
       
   340         if (hHint != SWT.DEFAULT && hHint < 0)
       
   341             hHint = SWT.DEFAULT;
       
   342 
       
   343         Point preferredSize;
       
   344         if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT) {
       
   345             preferredSize = new Point(wHint, hHint);
       
   346         } else if (variant == TextUtils.LINE_EDIT) {
       
   347 
       
   348             if (wHint == SWT.DEFAULT && hHint == SWT.DEFAULT) {
       
   349                 preferredSize = getPreferredSingleLineClientAreaSize();
       
   350             } else if (hHint == SWT.DEFAULT) {
       
   351                 preferredSize = new Point(wHint,
       
   352                         getPreferredSingleLineClientAreaSize().y);
       
   353             } else {
       
   354                 preferredSize = new Point(
       
   355                         getPreferredSingleLineClientAreaSize().x, hHint);
       
   356             }
       
   357         } else {
       
   358             if (wHint == SWT.DEFAULT && hHint == SWT.DEFAULT) {
       
   359                 preferredSize = getPreferredClientAreaSize(-1);
       
   360             } else if (hHint == SWT.DEFAULT) {
       
   361                 preferredSize = new Point(wHint, getPreferredClientAreaSize(wHint).y);
       
   362             } else {
       
   363                 preferredSize = new Point(getPreferredClientAreaSize(hHint).y, hHint);
       
   364             }
       
   365         }
       
   366 
       
   367         Rectangle trim = computeTrim(0, 0, preferredSize.x, preferredSize.y);
       
   368 
       
   369         return new Point(trim.width, trim.height);
       
   370     }
       
   371 
       
   372 
       
   373 public Rectangle computeTrim(int x, int y, int width, int height) {
       
   374     checkWidget();
       
   375     
       
   376     if (variant == TextUtils.LINE_EDIT) {
       
   377         if ((style & SWT.BORDER) != 0) {
       
   378             int border = OS.QLineEdit_swt_getBorderWidth(topHandle);
       
   379             x -= border;
       
   380             y -= border;
       
   381             width += 2 * border;
       
   382             height += 2 * border;
       
   383         } 
       
   384         return new Rectangle(x, y, width, height);
       
   385     } else {
       
   386         return super.computeTrim(x, y, width, height);
       
   387     }
       
   388 }
       
   389 
       
   390 /**
       
   391  * Copies the selected text.
       
   392  * <p>
       
   393  * The current selection is copied to the clipboard.
       
   394  * </p>
       
   395  *
       
   396  * @exception SWTException <ul>
       
   397  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   398  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   399  * </ul>
       
   400  */
       
   401 public void copy () {
       
   402     checkWidget();
       
   403     TextUtils.copy(variant, topHandle);
       
   404 }
       
   405 
       
   406 /**
       
   407  * Cuts the selected text.
       
   408  * <p>
       
   409  * The current selection is first copied to the
       
   410  * clipboard and then deleted from the widget.
       
   411  * </p>
       
   412  *
       
   413  * @exception SWTException <ul>
       
   414  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   415  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   416  * </ul>
       
   417  */
       
   418 public void cut () {
       
   419     checkWidget();
       
   420     TextUtils.cut(variant, topHandle, this);
       
   421 }
       
   422 
       
   423 void deregister_pp () {  
       
   424     super.deregister_pp ();
       
   425     if (variant == TextUtils.TEXT_EDIT) {
       
   426         display.removeWidget(scrollAreaHandle);
       
   427     }
       
   428 }
       
   429 
       
   430 void forceTextLayout() {
       
   431     // Hack: Qt does not do the layouting of the QTextDocument until QTextEdit comes visible on the screen.
       
   432     // Need to force the layouting of the invisible QTextEdit/QTextDocument here by changing the line wrap mode.
       
   433     // (Qt's default is QTEXTEDIT_WIDGETWIDTH).
       
   434     // This is needed in order that method's like getLineHeight(), getCaretLineNumber(), getCaretLocation(),
       
   435     // setTopIndex, etc. work correctly also for invisble text widgets.
       
   436     if (isVisible()) return;
       
   437     OS.QTextEdit_setLineWrapMode(scrollAreaHandle, OS.QTEXTEDIT_NOWRAP);
       
   438     if ((style & SWT.WRAP) != 0) {
       
   439         OS.QTextEdit_setLineWrapMode(scrollAreaHandle, OS.QTEXTEDIT_WIDGETWIDTH);
       
   440     }
       
   441 }
       
   442 
       
   443 public int getBorderWidth () {
       
   444    checkWidget(); 
       
   445    if (variant == TextUtils.LINE_EDIT) {
       
   446        return (style & SWT.BORDER) != 0 ? OS.QLineEdit_swt_getBorderWidth(topHandle) : 0;
       
   447    } else {
       
   448        return super.getBorderWidth();
       
   449    }
       
   450 }
       
   451 
       
   452 /**
       
   453  * Returns the line number of the caret.
       
   454  * <p>
       
   455  * The line number of the caret is returned.
       
   456  * </p>
       
   457  *
       
   458  * @return the line number
       
   459  *
       
   460  * @exception SWTException <ul>
       
   461  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   462  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   463  * </ul>
       
   464  */
       
   465 public int getCaretLineNumber () {
       
   466     checkWidget();
       
   467     if (variant == TextUtils.LINE_EDIT) {
       
   468         return 0;
       
   469     } else {
       
   470         return OS.QTextEdit_swt_getCaretLineNumber(topHandle);
       
   471     }
       
   472 }
       
   473 
       
   474 /**
       
   475  * Returns a point describing the receiver's location relative
       
   476  * to its parent (or its display if its parent is null).
       
   477  * <p>
       
   478  * The location of the caret is returned.
       
   479  * </p>
       
   480  *
       
   481  * @return a point, the location of the caret
       
   482  *
       
   483  * @exception SWTException <ul>
       
   484  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   485  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   486  * </ul>
       
   487  */
       
   488 public Point getCaretLocation () {
       
   489     checkWidget();
       
   490     if (variant == TextUtils.LINE_EDIT) {
       
   491         // Not supported in Qt
       
   492         return new Point(0, 0);
       
   493     } else {
       
   494         Rectangle cursorRect = OS.QTextEdit_cursorRect(topHandle);  
       
   495         return new Point(cursorRect.x, cursorRect.y);
       
   496     }
       
   497 }
       
   498 
       
   499 /**
       
   500  * Returns the character position of the caret.
       
   501  * <p>
       
   502  * Indexing is zero based.
       
   503  * </p>
       
   504  *
       
   505  * @return the position of the caret
       
   506  *
       
   507  * @exception SWTException <ul>
       
   508  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   509  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   510  * </ul>
       
   511  */
       
   512 public int getCaretPosition () {
       
   513     checkWidget();
       
   514     return TextUtils.getCaretPosition(variant, topHandle);
       
   515 }
       
   516 
       
   517 /**
       
   518  * Returns the number of characters.
       
   519  *
       
   520  * @return number of characters in the widget
       
   521  *
       
   522  * @exception SWTException <ul>
       
   523  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   524  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   525  * </ul>
       
   526  */
       
   527 public int getCharCount () {
       
   528     checkWidget();
       
   529     return TextUtils.getCharCount(variant, topHandle);
       
   530 }
       
   531 
       
   532 /**
       
   533  * Returns the double click enabled flag.
       
   534  * <p>
       
   535  * The double click flag enables or disables the
       
   536  * default action of the text widget when the user
       
   537  * double clicks.
       
   538  * </p>
       
   539  * 
       
   540  * @return whether or not double click is enabled
       
   541  *
       
   542  * @exception SWTException <ul>
       
   543  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   544  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   545  * </ul>
       
   546  */
       
   547 public boolean getDoubleClickEnabled () {
       
   548     checkWidget ();
       
   549     return doubleClick;
       
   550 }
       
   551 
       
   552 /**
       
   553  * Returns the echo character.
       
   554  * <p>
       
   555  * The echo character is the character that is
       
   556  * displayed when the user enters text or the
       
   557  * text is changed by the programmer.
       
   558  * </p>
       
   559  * 
       
   560  * @return the echo character
       
   561  *
       
   562  * @exception SWTException <ul>
       
   563  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   564  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   565  * </ul>
       
   566  * 
       
   567  * @see #setEchoChar
       
   568  */
       
   569 public char getEchoChar () {
       
   570     checkWidget ();
       
   571     
       
   572     if (variant == TextUtils.LINE_EDIT) {
       
   573         int echoMode = OS.QLineEdit_echoMode(topHandle);
       
   574         if (echoMode == OS.QLINEEDIT_ECHOMODE_PASSWORD || 
       
   575             echoMode == OS.QLINEEDIT_ECHOMODE_PASSWORDECHOONEDIT) {
       
   576             return '*';
       
   577         }
       
   578     } 
       
   579     
       
   580     return '\0';
       
   581 }
       
   582 
       
   583 /**
       
   584  * Returns the editable state.
       
   585  *
       
   586  * @return whether or not the receiver is editable
       
   587  * 
       
   588  * @exception SWTException <ul>
       
   589  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   590  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   591  * </ul>
       
   592  */
       
   593 public boolean getEditable () {
       
   594     checkWidget();
       
   595     return !TextUtils.getReadOnly(variant, topHandle);
       
   596 }
       
   597 
       
   598 /**
       
   599  * Returns the number of lines.
       
   600  *
       
   601  * @return the number of lines in the widget
       
   602  *
       
   603  * @exception SWTException <ul>
       
   604  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   605  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   606  * </ul>
       
   607  */
       
   608 public int getLineCount () {
       
   609     checkWidget();
       
   610     if (variant == TextUtils.LINE_EDIT) {
       
   611         return 1;
       
   612     } else {
       
   613         forceTextLayout();
       
   614         return OS.QTextEdit_swt_getLineCount(topHandle);
       
   615     }
       
   616 }
       
   617 
       
   618 /**
       
   619  * Returns the line delimiter.
       
   620  *
       
   621  * @return a string that is the line delimiter
       
   622  *
       
   623  * @exception SWTException <ul>
       
   624  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   625  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   626  * </ul>
       
   627  * 
       
   628  * @see #DELIMITER
       
   629  */
       
   630 public String getLineDelimiter() {
       
   631     checkWidget();
       
   632     return DELIMITER;
       
   633 }
       
   634 
       
   635 /**
       
   636  * Returns the height of a line.
       
   637  *
       
   638  * @return the height of a row of text
       
   639  *
       
   640  * @exception SWTException <ul>
       
   641  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   642  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   643  * </ul>
       
   644  */
       
   645 public int getLineHeight () {
       
   646     checkWidget();
       
   647     if (variant == TextUtils.LINE_EDIT) {
       
   648         return OS.QWidget_QFontMetrics_lineSpacing(topHandle);
       
   649     } else {
       
   650         return OS.QTextEdit_swt_getLineHeight(topHandle);
       
   651     }
       
   652 }
       
   653 
       
   654 /**
       
   655  * Returns the orientation of the receiver, which will be one of the
       
   656  * constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
       
   657  *
       
   658  * @return the orientation style
       
   659  * 
       
   660  * @exception SWTException <ul>
       
   661  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   662  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   663  * </ul>
       
   664  * 
       
   665  * @since 2.1.2
       
   666  */
       
   667 public int getOrientation () {
       
   668     checkWidget();
       
   669     return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
       
   670 }
       
   671 
       
   672 /*
       
   673  * Gets the preferred size for client area
       
   674  */
       
   675 Point getPreferredClientAreaSize_pp() {
       
   676         if (variant == TextUtils.LINE_EDIT) {
       
   677             return getPreferredSingleLineClientAreaSize();
       
   678         } else {
       
   679             return getPreferredClientAreaSize(-1);
       
   680         }
       
   681 }
       
   682 
       
   683 
       
   684 /*
       
   685  * Gets the preferred size for QTextEdit client area
       
   686  */
       
   687 private Point getPreferredClientAreaSize(int wHint) {
       
   688         Point size = OS
       
   689                 .QTextEdit_swt_preferredClientSize(topHandle, wHint);
       
   690         if (size == null)
       
   691             return new Point(WidgetConstant.DEFAULT_WIDTH, WidgetConstant.DEFAULT_HEIGHT);
       
   692         if (size.x < 0)
       
   693             size.x = WidgetConstant.DEFAULT_WIDTH;
       
   694         if (size.y < 0)
       
   695             size.y = WidgetConstant.DEFAULT_HEIGHT;
       
   696         return size;
       
   697     }
       
   698 
       
   699 /*
       
   700  * Gets the preferred size for QLineEdit client area
       
   701  */
       
   702 private Point getPreferredSingleLineClientAreaSize() {
       
   703     Point size = OS.QLineEdit_swt_preferredClientSize(topHandle);
       
   704         if (size == null)
       
   705             return new Point(WidgetConstant.DEFAULT_WIDTH, WidgetConstant.DEFAULT_HEIGHT);
       
   706         if (size.x < 0)
       
   707             size.x = WidgetConstant.DEFAULT_WIDTH;
       
   708         if (size.y < 0)
       
   709             size.y = WidgetConstant.DEFAULT_HEIGHT;
       
   710         return size;
       
   711 }
       
   712 
       
   713 
       
   714 
       
   715 /**
       
   716  * Returns a <code>Point</code> whose x coordinate is the
       
   717  * character position representing the start of the selected
       
   718  * text, and whose y coordinate is the character position
       
   719  * representing the end of the selection. An "empty" selection
       
   720  * is indicated by the x and y coordinates having the same value.
       
   721  * <p>
       
   722  * Indexing is zero based.  The range of a selection is from
       
   723  * 0..N where N is the number of characters in the widget.
       
   724  * </p>
       
   725  *
       
   726  * @return a point representing the selection start and end
       
   727  *
       
   728  * @exception SWTException <ul>
       
   729  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   730  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   731  * </ul>
       
   732  */
       
   733 public Point getSelection () {
       
   734     checkWidget();
       
   735     return TextUtils.getSelection(variant, topHandle); 
       
   736 }
       
   737 
       
   738 /**
       
   739  * Returns the number of selected characters.
       
   740  *
       
   741  * @return the number of selected characters.
       
   742  *
       
   743  * @exception SWTException <ul>
       
   744  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   745  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   746  * </ul>
       
   747  */
       
   748 public int getSelectionCount () {
       
   749     checkWidget();
       
   750     Point selection = getSelection();
       
   751     return Math.abs(selection.y - selection.x);
       
   752 }
       
   753 
       
   754 /**
       
   755  * Gets the selected text, or an empty string if there is no current selection.
       
   756  *
       
   757  * @return the selected text
       
   758  * 
       
   759  * @exception SWTException <ul>
       
   760  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   761  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   762  * </ul>
       
   763  */
       
   764 public String getSelectionText () {
       
   765     checkWidget();
       
   766     return TextUtils.getSelectionText(variant, topHandle); 
       
   767 }
       
   768 
       
   769 /**
       
   770  * Returns the widget text.
       
   771  * <p>
       
   772  * The text for a text widget is the characters in the widget, or
       
   773  * an empty string if this has never been set.
       
   774  * </p>
       
   775  *
       
   776  * @return the widget text
       
   777  *
       
   778  * @exception SWTException <ul>
       
   779  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   780  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   781  * </ul>
       
   782  */
       
   783 public String getText () {
       
   784     checkWidget();
       
   785     return TextUtils.getText(variant, topHandle);
       
   786 }
       
   787 
       
   788 /**
       
   789  * Returns a range of text.  Returns an empty string if the
       
   790  * start of the range is greater than the end.
       
   791  * <p>
       
   792  * Indexing is zero based.  The range of
       
   793  * a selection is from 0..N-1 where N is
       
   794  * the number of characters in the widget.
       
   795  * </p>
       
   796  *
       
   797  * @param start the start of the range
       
   798  * @param end the end of the range
       
   799  * @return the range of text
       
   800  *
       
   801  * @exception SWTException <ul>
       
   802  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   803  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   804  * </ul>
       
   805  */
       
   806 public String getText (int start, int end) {
       
   807     checkWidget ();
       
   808     if (start > end || end < 0) {
       
   809         return "";
       
   810     }
       
   811     
       
   812     String text = getText();
       
   813     if (text != null) {
       
   814         if (start >= text.length()) {
       
   815             text = "";
       
   816         }
       
   817         else {
       
   818             start = Math.max(0, start);
       
   819             end = Math.min(end, text.length() - 1);
       
   820             text = text.substring(start, end + 1);
       
   821         }
       
   822     }
       
   823     return text;
       
   824 }
       
   825 
       
   826 /**
       
   827  * Returns the maximum number of characters that the receiver is capable of holding. 
       
   828  * <p>
       
   829  * If this has not been changed by <code>setTextLimit()</code>,
       
   830  * it will be the constant <code>Text.LIMIT</code>.
       
   831  * </p>
       
   832  * 
       
   833  * @return the text limit
       
   834  * 
       
   835  * @exception SWTException <ul>
       
   836  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   837  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   838  * </ul>
       
   839  * 
       
   840  * @see #LIMIT
       
   841  */
       
   842 public int getTextLimit () {
       
   843     checkWidget(); 
       
   844     if (variant == TextUtils.LINE_EDIT) {
       
   845         return OS.QLineEdit_maxLength(topHandle);
       
   846     } else {
       
   847         return textLimit > 0 ? textLimit : LIMIT;
       
   848     }
       
   849 }
       
   850 
       
   851 /**
       
   852  * Returns the zero-relative index of the line which is currently
       
   853  * at the top of the receiver.
       
   854  * <p>
       
   855  * This index can change when lines are scrolled or new lines are added or removed.
       
   856  * </p>
       
   857  *
       
   858  * @return the index of the top line
       
   859  *
       
   860  * @exception SWTException <ul>
       
   861  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   862  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   863  * </ul>
       
   864  */
       
   865 public int getTopIndex () {
       
   866     checkWidget ();
       
   867     if (variant == TextUtils.LINE_EDIT) {
       
   868         return 0;
       
   869     } else {  
       
   870         return OS.QTextEdit_swt_getTopIndex(topHandle);
       
   871     }
       
   872 }
       
   873 
       
   874 /**
       
   875  * Returns the top pixel.
       
   876  * <p>
       
   877  * The top pixel is the pixel position of the line
       
   878  * that is currently at the top of the widget.  On
       
   879  * some platforms, a text widget can be scrolled by
       
   880  * pixels instead of lines so that a partial line
       
   881  * is displayed at the top of the widget.
       
   882  * </p><p>
       
   883  * The top pixel changes when the widget is scrolled.
       
   884  * The top pixel does not include the widget trimming.
       
   885  * </p>
       
   886  *
       
   887  * @return the pixel position of the top line
       
   888  *
       
   889  * @exception SWTException <ul>
       
   890  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   891  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   892  * </ul>
       
   893  */
       
   894 public int getTopPixel () {
       
   895     checkWidget ();
       
   896     if (variant == TextUtils.LINE_EDIT) {
       
   897         return 0;
       
   898     } else {
       
   899         return OS.QScrollBar_value(OS.QAbstractScrollArea_verticalScrollBar(scrollAreaHandle));
       
   900     }
       
   901 }
       
   902 
       
   903 
       
   904 void hookEvents_pp () {  
       
   905     super.hookEvents_pp();
       
   906     int textChangedProxy = OS.SignalHandler_new(topHandle, display, OS.QSIGNAL_TEXT_CHANGED);
       
   907     
       
   908     if (variant == TextUtils.LINE_EDIT) {
       
   909         OS.QObject_connectOrThrow(topHandle, "textChanged(const QString&)",
       
   910                 textChangedProxy, "widgetSignal(const QString&)", OS.QT_AUTOCONNECTION);
       
   911 
       
   912         int returnPressedProxy = OS.SignalHandler_new(topHandle, display, OS.QSIGNAL_RETURN_PRESSED);
       
   913         OS.QObject_connectOrThrow(topHandle, "returnPressed()",
       
   914                 returnPressedProxy, "widgetSignal()", OS.QT_AUTOCONNECTION);
       
   915     } else {
       
   916         OS.QObject_connectOrThrow(topHandle, "textChanged()", 
       
   917                 textChangedProxy, "widgetSignal()", OS.QT_AUTOCONNECTION);
       
   918     }
       
   919 }
       
   920 
       
   921 
       
   922 /**
       
   923  * Inserts a string.
       
   924  * <p>
       
   925  * The old selection is replaced with the new text.
       
   926  * </p>
       
   927  *
       
   928  * @param string the string
       
   929  *
       
   930  * @exception IllegalArgumentException <ul>
       
   931  *    <li>ERROR_NULL_ARGUMENT - if the string is <code>null</code></li>
       
   932  * </ul>
       
   933  * @exception SWTException <ul>
       
   934  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   935  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   936  * </ul>
       
   937  */
       
   938 public void insert (String string) {
       
   939     checkWidget ();
       
   940     TextUtils.insert(variant, topHandle, string, textLimit, this);
       
   941 }
       
   942 
       
   943 /**
       
   944  * Pastes text from clipboard.
       
   945  * <p>
       
   946  * The selected text is deleted from the widget
       
   947  * and new text inserted from the clipboard.
       
   948  * </p>
       
   949  *
       
   950  * @exception SWTException <ul>
       
   951  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   952  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   953  * </ul>
       
   954  */
       
   955 public void paste () {
       
   956     TextUtils.paste(variant, topHandle, textLimit, this);
       
   957 }
       
   958 
       
   959 /**
       
   960  * Removes the listener from the collection of listeners who will
       
   961  * be notified when the receiver's text is modified.
       
   962  *
       
   963  * @param listener the listener which should no longer be notified
       
   964  *
       
   965  * @exception IllegalArgumentException <ul>
       
   966  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
       
   967  * </ul>
       
   968  * @exception SWTException <ul>
       
   969  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   970  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   971  * </ul>
       
   972  *
       
   973  * @see ModifyListener
       
   974  * @see #addModifyListener
       
   975  */
       
   976 public void removeModifyListener (ModifyListener listener) {
       
   977     checkWidget ();
       
   978     if (listener == null) {
       
   979         error(SWT.ERROR_NULL_ARGUMENT);
       
   980     }
       
   981     if (eventTable == null) {
       
   982         return;
       
   983     }
       
   984     eventTable.unhook(SWT.Modify, listener);    
       
   985 }
       
   986 
       
   987 /**
       
   988  * Removes the listener from the collection of listeners who will
       
   989  * be notified when the control is selected by the user.
       
   990  *
       
   991  * @param listener the listener which should no longer be notified
       
   992  *
       
   993  * @exception IllegalArgumentException <ul>
       
   994  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
       
   995  * </ul>
       
   996  * @exception SWTException <ul>
       
   997  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
   998  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
   999  * </ul>
       
  1000  *
       
  1001  * @see SelectionListener
       
  1002  * @see #addSelectionListener
       
  1003  */
       
  1004 public void removeSelectionListener(SelectionListener listener) {
       
  1005     checkWidget ();
       
  1006     if (listener == null) {
       
  1007         error(SWT.ERROR_NULL_ARGUMENT);
       
  1008     }
       
  1009     if (eventTable == null) {
       
  1010         return;
       
  1011     }
       
  1012     eventTable.unhook(SWT.Selection, listener);
       
  1013     eventTable.unhook(SWT.DefaultSelection,listener);   
       
  1014 }
       
  1015 
       
  1016 /**
       
  1017  * Removes the listener from the collection of listeners who will
       
  1018  * be notified when the control is verified.
       
  1019  *
       
  1020  * @param listener the listener which should no longer be notified
       
  1021  *
       
  1022  * @exception IllegalArgumentException <ul>
       
  1023  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
       
  1024  * </ul>
       
  1025  * @exception SWTException <ul>
       
  1026  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1027  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1028  * </ul>
       
  1029  *
       
  1030  * @see VerifyListener
       
  1031  * @see #addVerifyListener
       
  1032  */
       
  1033 public void removeVerifyListener (VerifyListener listener) {
       
  1034     checkWidget ();
       
  1035     if (listener == null) {
       
  1036         error(SWT.ERROR_NULL_ARGUMENT);
       
  1037     }
       
  1038     if (eventTable == null) {
       
  1039         return;
       
  1040     }
       
  1041     eventTable.unhook(SWT.Verify, listener);    
       
  1042 }
       
  1043 
       
  1044 /**
       
  1045  * Selects all the text in the receiver.
       
  1046  *
       
  1047  * @exception SWTException <ul>
       
  1048  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1049  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1050  * </ul>
       
  1051  */
       
  1052 public void selectAll () {
       
  1053     checkWidget();
       
  1054     TextUtils.selectAll(variant, topHandle);
       
  1055 }
       
  1056 
       
  1057 /**
       
  1058  * Sets the double click enabled flag.
       
  1059  * <p>
       
  1060  * The double click flag enables or disables the
       
  1061  * default action of the text widget when the user
       
  1062  * double clicks.
       
  1063  * </p><p>
       
  1064  * Note: This operation is a hint and is not supported on
       
  1065  * platforms that do not have this concept.
       
  1066  * </p>
       
  1067  * 
       
  1068  * @param doubleClick the new double click flag
       
  1069  *
       
  1070  * @exception SWTException <ul>
       
  1071  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1072  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1073  * </ul>
       
  1074  */
       
  1075 public void setDoubleClickEnabled (boolean doubleClick) {
       
  1076     checkWidget ();
       
  1077     this.doubleClick = doubleClick;
       
  1078 }
       
  1079 
       
  1080 /**
       
  1081  * Sets the echo character.
       
  1082  * <p>
       
  1083  * The echo character is the character that is
       
  1084  * displayed when the user enters text or the
       
  1085  * text is changed by the programmer. Setting
       
  1086  * the echo character to '\0' clears the echo
       
  1087  * character and redraws the original text.
       
  1088  * If for any reason the echo character is invalid,
       
  1089  * or if the platform does not allow modification
       
  1090  * of the echo character, the default echo character
       
  1091  * for the platform is used.
       
  1092  * </p>
       
  1093  *
       
  1094  * @param echo the new echo character
       
  1095  *
       
  1096  * @exception SWTException <ul>
       
  1097  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1098  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1099  * </ul>
       
  1100  */
       
  1101 public void setEchoChar(char echo) {  
       
  1102     checkWidget();
       
  1103     if (variant == TextUtils.LINE_EDIT) { 
       
  1104         int echoMode = (echo == '\0') ? OS.QLINEEDIT_ECHOMODE_NORMAL : 
       
  1105                                     OS.QLINEEDIT_ECHOMODE_PASSWORD;
       
  1106         OS.QLineEdit_setEchoMode(topHandle, echoMode);
       
  1107     }
       
  1108 }
       
  1109 
       
  1110 /**
       
  1111  * Sets the editable state.
       
  1112  *
       
  1113  * @param editable the new editable state
       
  1114  *
       
  1115  * @exception SWTException <ul>
       
  1116  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1117  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1118  * </ul>
       
  1119  */
       
  1120 public void setEditable (boolean editable) {
       
  1121     checkWidget();
       
  1122     style &= ~SWT.READ_ONLY;
       
  1123     if (!editable) {
       
  1124         style |= SWT.READ_ONLY;
       
  1125     }
       
  1126     TextUtils.setReadOnly(variant, topHandle, !editable);
       
  1127 } 
       
  1128 
       
  1129 /**
       
  1130  * Sets the orientation of the receiver, which must be one
       
  1131  * of the constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
       
  1132  * <p>
       
  1133  * Note: This operation is a hint and is not supported on
       
  1134  * platforms that do not have this concept.
       
  1135  * </p>
       
  1136  *
       
  1137  * @param orientation new orientation style
       
  1138  * 
       
  1139  * @exception SWTException <ul>
       
  1140  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1141  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1142  * </ul>
       
  1143  * 
       
  1144  * @since 2.1.2
       
  1145  */
       
  1146 public void setOrientation(int orientation) {
       
  1147     state &= ~WidgetState.FOLLOWS_SYSLANG_DIRECTION;
       
  1148     setOrientation(topHandle, orientation);
       
  1149 }
       
  1150 
       
  1151 /**
       
  1152  * Sets the selection.
       
  1153  * <p>
       
  1154  * Indexing is zero based.  The range of
       
  1155  * a selection is from 0..N where N is
       
  1156  * the number of characters in the widget.
       
  1157  * </p><p>
       
  1158  * Text selections are specified in terms of
       
  1159  * caret positions.  In a text widget that
       
  1160  * contains N characters, there are N+1 caret
       
  1161  * positions, ranging from 0..N.  This differs
       
  1162  * from other functions that address character
       
  1163  * position such as getText () that use the
       
  1164  * regular array indexing rules.
       
  1165  * </p>
       
  1166  *
       
  1167  * @param start new caret position
       
  1168  *
       
  1169  * @exception SWTException <ul>
       
  1170  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1171  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1172  * </ul>
       
  1173  */
       
  1174 public void setSelection(int start) {
       
  1175     checkWidget();
       
  1176     start = Math.min(Math.max(0, start), getCharCount());
       
  1177     setSelection(start, start);
       
  1178 }
       
  1179 
       
  1180 /**
       
  1181  * Sets the selection to the range specified
       
  1182  * by the given start and end indices.
       
  1183  * <p>
       
  1184  * Indexing is zero based.  The range of
       
  1185  * a selection is from 0..N where N is
       
  1186  * the number of characters in the widget.
       
  1187  * </p><p>
       
  1188  * Text selections are specified in terms of
       
  1189  * caret positions.  In a text widget that
       
  1190  * contains N characters, there are N+1 caret
       
  1191  * positions, ranging from 0..N.  This differs
       
  1192  * from other functions that address character
       
  1193  * position such as getText () that use the
       
  1194  * usual array indexing rules.
       
  1195  * </p>
       
  1196  *
       
  1197  * @param start the start of the range
       
  1198  * @param end the end of the range
       
  1199  *
       
  1200  * @exception SWTException <ul>
       
  1201  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1202  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1203  * </ul>
       
  1204  */
       
  1205 public void setSelection (int start, int end) {
       
  1206     checkWidget();
       
  1207     TextUtils.setSelection(variant, topHandle, start, end);
       
  1208 }
       
  1209 
       
  1210 /**
       
  1211  * Sets the selection to the range specified
       
  1212  * by the given point, where the x coordinate
       
  1213  * represents the start index and the y coordinate
       
  1214  * represents the end index.
       
  1215  * <p>
       
  1216  * Indexing is zero based.  The range of
       
  1217  * a selection is from 0..N where N is
       
  1218  * the number of characters in the widget.
       
  1219  * </p><p>
       
  1220  * Text selections are specified in terms of
       
  1221  * caret positions.  In a text widget that
       
  1222  * contains N characters, there are N+1 caret
       
  1223  * positions, ranging from 0..N.  This differs
       
  1224  * from other functions that address character
       
  1225  * position such as getText () that use the
       
  1226  * usual array indexing rules.
       
  1227  * </p>
       
  1228  *
       
  1229  * @param selection the point
       
  1230  *
       
  1231  * @exception IllegalArgumentException <ul>
       
  1232  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
       
  1233  * </ul>
       
  1234  * @exception SWTException <ul>
       
  1235  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1236  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1237  * </ul>
       
  1238  */
       
  1239 public void setSelection (Point selection) {
       
  1240     checkWidget ();
       
  1241     if (selection == null) {
       
  1242         error(SWT.ERROR_NULL_ARGUMENT);
       
  1243     }
       
  1244     setSelection(selection.x, selection.y);
       
  1245 }
       
  1246 
       
  1247 /**
       
  1248  * Sets the contents of the receiver to the given string. If the receiver has style
       
  1249  * SINGLE and the argument contains multiple lines of text, the result of this
       
  1250  * operation is undefined and may vary from platform to platform.
       
  1251  *
       
  1252  * @param string the new text
       
  1253  *
       
  1254  * @exception IllegalArgumentException <ul>
       
  1255  *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
       
  1256  * </ul>
       
  1257  * @exception SWTException <ul>
       
  1258  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1259  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1260  * </ul>
       
  1261  */
       
  1262 public void setText (String string) {
       
  1263     checkWidget();
       
  1264     TextUtils.setText(variant, topHandle, string, textLimit, this);
       
  1265     if(isDisposed()) return;
       
  1266     if (variant == TextUtils.TEXT_EDIT) {
       
  1267         OS.QScrollBar_setValue(OS.QAbstractScrollArea_verticalScrollBar(scrollAreaHandle), 0);
       
  1268     }
       
  1269 }
       
  1270 
       
  1271 /**
       
  1272  * Sets the maximum number of characters that the receiver
       
  1273  * is capable of holding to be the argument.
       
  1274  * <p>
       
  1275  * Instead of trying to set the text limit to zero, consider
       
  1276  * creating a read-only text widget.
       
  1277  * </p><p>
       
  1278  * To reset this value to the default, use <code>setTextLimit(Text.LIMIT)</code>.
       
  1279  * Specifying a limit value larger than <code>Text.LIMIT</code> sets the
       
  1280  * receiver's limit to <code>Text.LIMIT</code>.
       
  1281  * </p>
       
  1282  *
       
  1283  * @param limit new text limit
       
  1284  *
       
  1285  * @exception IllegalArgumentException <ul>
       
  1286  *    <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>
       
  1287  * </ul>
       
  1288  * @exception SWTException <ul>
       
  1289  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1290  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1291  * </ul>
       
  1292  * 
       
  1293  * @see #LIMIT
       
  1294  */
       
  1295 public void setTextLimit (int limit) {
       
  1296     checkWidget ();
       
  1297     if (limit == 0) {
       
  1298         error(SWT.ERROR_CANNOT_BE_ZERO);
       
  1299     }
       
  1300     
       
  1301     if (limit < 0 || limit > LIMIT) {
       
  1302         limit = LIMIT;
       
  1303     }
       
  1304     
       
  1305     if (variant == TextUtils.LINE_EDIT) {
       
  1306         OS.QLineEdit_setMaxLength(topHandle, limit);
       
  1307     } else {
       
  1308         textLimit = limit;
       
  1309         if (getCharCount() > limit) {
       
  1310             OS.QTextEdit_setPlainText(topHandle, getText().substring(0, limit));
       
  1311         }
       
  1312     }
       
  1313 }
       
  1314 
       
  1315 /**
       
  1316  * Sets the zero-relative index of the line which is currently
       
  1317  * at the top of the receiver. This index can change when lines
       
  1318  * are scrolled or new lines are added and removed.
       
  1319  *
       
  1320  * @param index the index of the top item
       
  1321  *
       
  1322  * @exception SWTException <ul>
       
  1323  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1324  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1325  * </ul>
       
  1326  */
       
  1327 public void setTopIndex (int index) {
       
  1328     checkWidget ();
       
  1329     if (variant == TextUtils.TEXT_EDIT) {
       
  1330         index = Math.min(Math.max(index, 0), OS.QTextEdit_swt_getLineCount(topHandle) - 1);
       
  1331         OS.QTextEdit_swt_setTopIndex(topHandle, index);
       
  1332     }
       
  1333 }
       
  1334 
       
  1335 /**
       
  1336  * Shows the selection.
       
  1337  * <p>
       
  1338  * If the selection is already showing
       
  1339  * in the receiver, this method simply returns.  Otherwise,
       
  1340  * lines are scrolled until the selection is visible.
       
  1341  * </p>
       
  1342  * 
       
  1343  * @exception SWTException <ul>
       
  1344  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
       
  1345  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
       
  1346  * </ul>
       
  1347  */
       
  1348 public void showSelection () {
       
  1349     checkWidget ();
       
  1350     if (variant == TextUtils.TEXT_EDIT) {
       
  1351         OS.QTextEdit_ensureCursorVisible(topHandle);
       
  1352     }
       
  1353 }
       
  1354 
       
  1355 boolean qt_event_keypress_pp(int widgetHandle, int key, int modifier, int character, int nativeScanCode) {
       
  1356     // In QTextEdit key events normally come with QTextEdit handle (=scrollAreaHandle).
       
  1357     // KeyPress events may come with viewport widget handle (=handle) when Display.post()
       
  1358     // is used to generate the event. In this case just let the event through so that it is 
       
  1359     // passed to QTextEdit in native side.
       
  1360     if (variant == TextUtils.TEXT_EDIT && widgetHandle != scrollAreaHandle) {
       
  1361         return false;
       
  1362     }
       
  1363     
       
  1364     if (super.qt_event_keypress_pp(widgetHandle, key, modifier, character, nativeScanCode)) {
       
  1365         return true;
       
  1366     }
       
  1367     
       
  1368     if ( !(hooks(SWT.Verify) || filters(SWT.Verify)) && textLimit <= 0 ) {
       
  1369         return false;
       
  1370     }
       
  1371     
       
  1372     Event keyEv = makeKeyEvent(key, modifier, character, nativeScanCode);
       
  1373     return TextUtils.handle_keypress(variant, widgetHandle,
       
  1374         key, modifier, character, keyEv, textLimit, this);
       
  1375 }
       
  1376 
       
  1377 boolean qt_event_mouseButtonDblClick_pp(int widgetHandle, int button, int x, int y, int state, int buttons) {
       
  1378     super.qt_event_mouseButtonDblClick_pp(widgetHandle, button, x, y, state, buttons);
       
  1379     return !doubleClick;
       
  1380 }
       
  1381 
       
  1382 void qt_signal_return_pressed_pp() {
       
  1383     sendEvent(SWT.DefaultSelection);
       
  1384 }
       
  1385 
       
  1386 void qt_signal_text_changed_pp(String text) {
       
  1387     sendEvent(SWT.Modify);
       
  1388 }
       
  1389   
       
  1390 void setTraversalFlags_pp(int type, int key, int modifier, int character) {    
       
  1391     traverseDoit = false;
       
  1392     traverseCancel = false;
       
  1393     
       
  1394     // If the system is about to traverse out of the Text because mnemonic
       
  1395     // shortcut of some widget was pressed then it is allowed.
       
  1396     // Note that if keys used to launch shortcuts overlap the keys that are used
       
  1397     // by Text then shortcut has priority over text with this implementation. 
       
  1398     // However, platforms usually define the shortucts in such a way that they
       
  1399     // don't overlap. E.g. in X11 Alt+something. 
       
  1400     if (type == SWT.TRAVERSE_MNEMONIC) {
       
  1401         traverseDoit = true;
       
  1402         return;
       
  1403     }
       
  1404     
       
  1405     switch(key) {
       
  1406         case OS.QT_KEY_ENTER:
       
  1407             // fall through
       
  1408         case OS.QT_KEY_RETURN:
       
  1409             traverseDoit = false;
       
  1410             // Cancel event in TextExtension case
       
  1411             if ((getStyle() & SWT.SINGLE) != 0 && variant == TextUtils.TEXT_EDIT) {
       
  1412                 traverseCancel = true;
       
  1413             }
       
  1414             break;
       
  1415         case OS.QT_KEY_TAB:
       
  1416             traverseDoit = (getStyle() & SWT.SINGLE) != 0 ; // intentionally not using variant()
       
  1417             break;
       
  1418         case OS.QT_KEY_UP:
       
  1419             if ( (modifier & OS.QT_SHIFTMODIFIER) == 0 &&
       
  1420                  (getCaretLineNumber() == 0) ) {
       
  1421                 traverseDoit = true;
       
  1422             }
       
  1423             break;
       
  1424         case OS.QT_KEY_DOWN:
       
  1425             if ( (modifier & OS.QT_SHIFTMODIFIER) == 0 &&
       
  1426                  (getCaretLineNumber() == getLineCount() - 1) ) {
       
  1427                 traverseDoit = true;
       
  1428             }
       
  1429             break;
       
  1430         case OS.QT_KEY_LEFT:
       
  1431         case OS.QT_KEY_RIGHT:
       
  1432             traverseDoit = false;
       
  1433             break;
       
  1434         default:
       
  1435             super.setTraversalFlags_pp(type, key, modifier, character);
       
  1436             break;
       
  1437     }
       
  1438 }
       
  1439 
       
  1440 void setBackground_pp () {
       
  1441     // MULTI uses QLineEdit and might have modified viewport background brush
       
  1442     // that needs to be restored to default.
       
  1443     if((style & SWT.MULTI) != 0) {
       
  1444         OS.QWidget_swt_unsetPalette(handle);
       
  1445     }
       
  1446     super.setBackground_pp();
       
  1447 }
       
  1448 
       
  1449 void backgroundImageApplied_pp(Image image) {
       
  1450     // There's a problem with scrolling QTextEdit when non-single-color
       
  1451     // backgrounds are used. Background can't be scrolled but needs to be
       
  1452     // redrawn. To fix this we detect when background image is taken into use
       
  1453     // with QTextEdit and temporarily set null background brush to viewport.
       
  1454     // Viewport will inherit the background from its parent and whole area is
       
  1455     // updated correctly.
       
  1456     
       
  1457     // Only MULTI uses QLineEdit
       
  1458     if((style & SWT.MULTI) == 0) return;
       
  1459     
       
  1460     int textPalette = 0;
       
  1461     try {
       
  1462         textPalette = OS.QWidget_swt_palette_new(handle);
       
  1463         int[] bkRoles = getBackgroundImageRoles();
       
  1464         for(int i = 0; i < bkRoles.length; ++i) {
       
  1465             OS.QPalette_swt_setBrush(textPalette, bkRoles[i], 0);
       
  1466         }
       
  1467         OS.QWidget_setPalette(handle, textPalette);
       
  1468     } finally {
       
  1469         OS.QPalette_delete(textPalette);
       
  1470     }
       
  1471 }
       
  1472 }