javauis/eswt_qt/org.eclipse.swt/Eclipse SWT/qt/org/eclipse/ercp/swt/mobile/ConstrainedText.java
/*******************************************************************************
* Copyright (c) 2004, 2008 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Yu You (Nokia Corp.)- initial API specification
* Nokia Corporation - S60 implementation
* Nokia Corporation - QT implementation
*******************************************************************************/
package org.eclipse.ercp.swt.mobile;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.internal.qt.OS;
import org.eclipse.swt.internal.qt.PackageProxy;
import org.eclipse.swt.internal.qt.SWTExtension;
import org.eclipse.swt.internal.qt.TextUtils;
import org.eclipse.swt.internal.qt.WidgetState;
import org.eclipse.swt.widgets.*;
/**
* A single-line Text control which constrains the user input by styles.
*
* <p>
* This control limits the characters that users can enter by the styles to make
* data entry more efficient. This capability is usually implemented by the
* underlying platform and applications are not allowed to change or override
* the constraints. An IllegalArgumentException will be thrown if illegal
* content is set programmatically by applications.
* </p>
* <dl>
* <dt><b>Constraint Styles (exclusive): </b></dt>
* <dd>NUMERIC: limit to digits and an optional minus sign in the beginning of
* the string</dd>
* <dd>DECIMAL: limit to digits, fractional separator and an optional minus
* sign in the beginning of the string</dd>
* <dd>PHONENUMBER: all dialling digitals: 0-9, *, #, +, A, B, C, D and
* modifier characters (", T P ! W @ ; > I i G g") (see the standard at <a
* href="http://www.3gpp.org/ftp/Specs/html-info/27007.htm">3GPP TS 27.007, ITU-T dial
* command </a></dd>
*
* <dt><b>Events: </b></dt>
* <dd>Selection, DefaultSelection, Modify</dd>
* </dl>
*/
public class ConstrainedText extends Control {
/**
* Numeric input style allows the input of numeric values.
*
* <P>
* Value <code>1</code> is assigned to <code>NUMERIC</code>.
* </P>
*
*/
public static final int NUMERIC = 1;
/**
* Decimal input style allows the input of numeric values with optional
* decimal fractions, for example, "-123", "0.123", or ".5" are all valid
* input.
*
* <P>
* Value <code>2</code> is assigned to <code>DECIMAL</code>.
* </P>
*
*/
public static final int DECIMAL = 2;
/**
* Phone number input style allows the input of numeric values with optional
* phone specific characters like "+", "* and "#".
*
* <P>
* Value <code>4</code> is assigned to <code>PHONENUMBER</code>.
* </P>
*
*/
public static final int PHONENUMBER = 4;
private int validator, variant;
/*
* Used to store the position and length of selected text
*/
Point lastSelection;
static final class ConstrainedTextPackageProxy extends PackageProxy {
public void createHandle(int index) {
((ConstrainedText)w).createHandle(index);
}
public void hookEvents() {
((ConstrainedText)w).hookEvents();
}
public void qt_signal_text_changed(String text) {
((ConstrainedText)w).qt_signal_text_changed(text);
}
public void checkBorder() {
((ConstrainedText)w).checkBorder();
}
public void setTraversalFlags(int type, int key, int modifier, int character) {
((ConstrainedText)w).setTraversalFlags(type, key, modifier, character);
}
public void qt_signal_text_cursorPositionChanged(int oldPos, int newPos) {
((ConstrainedText)w).qt_signal_text_cursorPositionChanged(oldPos, newPos);
}
public void qt_signal_text_selectionChanged() {
((ConstrainedText)w).qt_signal_text_selectionChanged();
}
public void qt_signal_return_pressed() {
((ConstrainedText)w).qt_signal_return_pressed();
}
}
/**
* Constructs a new instance of this class given its parent, a style value
* describing behaviour and appearance, and an additional constrained style
* specifying the input styles defined above.
* <p>
* The style value is either one of the style constants defined in class
* <code>SWT</code> which is applicable to instances of this class, or
* must be built by <em>bitwise OR</em> 'ing together (that is, using the
* <code>int</code> "|" operator) two or more of those <code>SWT</code>
* style constants. Style bits are also inherited from superclasses. The
* class description lists the constrained style constants that can be set
* in constrainedStyle.
* </p>
*
* @param parent
* a composite control which will be the parent of the new
* instance (cannot be null)
* @param style
* the style of control to construct
* @param constrainedStyle
* the constrained style
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
* </ul>
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if either the style or the
* constrainedStyle is invalid</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the parent</li>
* </ul>
*
* @see #NUMERIC
* @see #DECIMAL
* @see #PHONENUMBER
*/
public ConstrainedText(Composite parent, int style, int constrainedStyle) {
this(parent, checkStyle(style), checkConstrainedStyle(constrainedStyle), false);
}
/**
* <p>
* <b>IMPORTANT:</b> This constructor is <em>not</em> part of the SWT
* public API. It should never be referenced from application code.
* </p>
*/
protected ConstrainedText(Composite parent, int style, int constrainedStyle, boolean isExtended) {
super(parent, checkStyle(style), checkConstrainedStyle(constrainedStyle),
new ConstrainedTextPackageProxy(), isExtended);
}
/**
* Adds the listener to the collection of listeners who will be notified
* when the receiver's text is modified, by sending it one of the messages
* defined in the <code>ModifyListener</code> interface.
*
* @param listener
* the listener which should be notified
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*
* @see ModifyListener
* @see #removeModifyListener
*/
public void addModifyListener(ModifyListener listener) {
checkWidget ();
if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Modify, typedListener);
}
/**
* Adds the listener to the collection of listeners who will be notified
* when the control is selected, by sending it one of the messages defined
* in the <code>SelectionListener</code> interface.
* <p>
* <code>widgetSelected</code> is not called for this control. <br />
* <code>widgetDefaultSelected</code> is called when a selection key is
* pressed.
* </p>
*
* @param listener
* the listener which should be notified
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*
* @see SelectionListener
* @see #removeSelectionListener
* @see SelectionEvent
*/
public void addSelectionListener(SelectionListener listener) {
checkWidget ();
if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Selection,typedListener);
addListener (SWT.DefaultSelection,typedListener);
}
/**
* Appends a string.
* <p>
* The new text is appended to the text at the end of the widget. The
* excessive characters will be truncated if the length exceeds the maximum
* number of characters that the receiver is capable of holding.
* </p>
*
* @param string
* the string to be appended
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the string is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the string is invalid
* </li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void append(String string) {
checkWidget();
if (OS.QValidator_validate(validator, string)) {
TextUtils.append(variant, handle(), string, OS.QLineEdit_maxLength(handle()), null);
}
else {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
}
/**
* Clears the selection.
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void clearSelection() {
checkWidget();
TextUtils.clearSelection(variant, handle());
}
/**
* Copies the selected text.
* <p>
* The current selection is copied to the clipboard.
* </p>
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void copy() {
checkWidget();
TextUtils.copy(variant, handle());
}
/**
* Cuts the selected text.
* <p>
* The current selection is first copied to the clipboard and then deleted
* from the widget.
* </p>
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void cut() {
checkWidget();
TextUtils.cut(variant, handle(), this);
}
/**
* Gets the position of the caret.
* <p>
* The character position of the caret is returned.
* </p>
*
* @return the position of the caret
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public int getCaretPosition() {
checkWidget();
return TextUtils.getCaretPosition(variant, handle());
}
/**
* Gets the number of characters.
*
* @return number of characters in the widget
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public int getCharCount() {
checkWidget();
return TextUtils.getCharCount(variant, handle());
}
/**
* Gets the editable state.
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public boolean getEditable() {
checkWidget();
return !TextUtils.getReadOnly(variant, handle());
}
String getSelectionText () {
checkWidget();
return TextUtils.getSelectionText(variant, Internal_PackageSupport.topHandle(this));
}
/**
* Gets the widget text.
* <p>
* The text for a text widget is the characters in the widget.
* </p>
*
* @return the widget text
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public String getText() {
checkWidget();
return TextUtils.getText(variant, handle());
}
/**
* Returns the maximum number of characters that the receiver is capable of
* holding.
* <p>
* If this has not been changed by <code>setTextLimit()</code>, it will
* be the constant <code>Text.LIMIT</code>.
* </p>
*
* @return the text limit
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public int getTextLimit() {
checkWidget();
return OS.QLineEdit_maxLength(handle());
}
/**
* Inserts a string after the caret position.
* <p>
* The old selection is replaced with the new text. The excessive characters
* will be truncated if the length exceeds the maximum number of characters
* that the receiver is capable of holding.
* </p>
*
* @param string
* the string value.
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the string is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the string is invalid
* </li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void insert(String string) {
checkWidget();
if (OS.QValidator_validate(validator, string)) {
TextUtils.insert(variant, handle(), string, OS.QLineEdit_maxLength(handle()), null);
}
else {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
}
private final boolean isExtended() {
return ((Internal_PackageSupport.state(this) & WidgetState.IS_EXTENDED) != 0);
}
/**
* Pastes text from clipboard.
* <p>
* The selected text is deleted from the widget and new text inserted from
* the clipboard. The excessive characters will be truncated if the length
* exceeds the maximum number of characters that the receiver is capable of
* holding.
* </p>
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the string is invalid
* </li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void paste() {
checkWidget();
if (OS.QValidator_validate(validator, OS.QClipboard_text())) {
TextUtils.paste(variant, handle(), OS.QLineEdit_maxLength(handle()), null);
}
else {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
}
/**
* Removes the listener from the collection of listeners who will be
* notified when the receiver's text is modified.
*
* @param listener
* the listener which should no longer be notified
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*
* @see ModifyListener
* @see #addModifyListener
*/
public void removeModifyListener(ModifyListener listener) {
removeListener(SWT.Modify, listener);
}
/**
* Removes the listener from the collection of listeners who will be
* notified when the control is selected.
*
* @param listener
* the listener which should be notified
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*
* @see SelectionListener
* @see #addSelectionListener
*/
public void removeSelectionListener(SelectionListener listener) {
removeListener(SWT.Selection, listener);
removeListener(SWT.DefaultSelection, listener);
}
/**
* Selects all the text in the receiver.
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void selectAll() {
checkWidget();
TextUtils.selectAll(variant, handle());
}
/**
* Sets the editable state.
*
* @param editable
* the new editable state
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void setEditable (boolean editable) {
checkWidget();
setStyle(style() & ~SWT.READ_ONLY);
if (!editable) {
setStyle(style() | SWT.READ_ONLY);
}
TextUtils.setReadOnly(variant, handle(), !editable);
}
/**
* Sets the selection.
* <p>
* Indexing is zero based. The range of a selection is from 0..N where N is
* the number of characters in the widget.
* </p>
* <p>
* Text selections are specified in terms of caret positions. In a text
* widget that contains N characters, there are N+1 caret positions, ranging
* from 0..N. This differs from other functions that address character
* position such as getText () that use the regular array indexing rules.
* </p>
*
* @param start
* new caret position
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the start is less than
* zero.</li>
* <ul>
* <li>ERROR_INVALID_RANGE - if the start value is greater
* than N.</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void setSelection(int start) {
setSelection(start, start);
}
/**
* Sets the selection.
* <p>
* Indexing is zero based. The range of a selection is from 0..N where N is
* the number of characters in the widget.
* </p>
* <p>
* Text selections are specified in terms of caret positions. In a text
* widget that contains N characters, there are N+1 caret positions, ranging
* from 0..N. This differs from other functions that address character
* position such as getText () that use the usual array indexing rules.
* </p>
*
* @param start
* the start of the range
* @param end
* the end of the range
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the start or end values
* are less than zero.</li>
* <ul>
* <li>ERROR_INVALID_RANGE - if the start value is greater
* than the end value; or if the end value is greater than N.
* </li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void setSelection(int start, int end) {
checkWidget();
if (start < 0 || end < 0) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
if (start > end || end > TextUtils.getText(variant, handle()).length()) {
SWT.error(SWT.ERROR_INVALID_RANGE);
}
TextUtils.setSelection(variant, handle(), start, end);
}
/**
* Sets the initial contents of the receiver to the given string. If the
* argument contains multiple lines of text, the result of this operation is
* undefined and may vary from platform to platform.
* <p>
* It is not recommended to set the initial contents especially when the
* style is <em>PHONENUMBER</em> because an IllegalArgumentException will
* be thrown when the string format does not match the present
* locale-specific format.
* </p>
*
* @param text
* the new text
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_NULL_ARGUMENT - if the string is null</li>
* <li>ERROR_INVALID_ARGUMENT - if the string format is
* invalid</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void setText(String text) {
checkWidget();
if (OS.QValidator_validate(validator, text)) {
TextUtils.setText(variant, handle(), text, OS.QLineEdit_maxLength(handle()), null);
}
else {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
}
/**
* Sets the maximum number of characters that the receiver is capable of
* holding to be the argument.
* <p>
* Instead of trying to set the text limit to zero, consider creating a
* read-only text widget.
* </p>
* <p>
* To reset this value to the default, use
* <code>setTextLimit(Text.LIMIT)</code>.
* </p>
*
* @param limit
* new text limit
*
* @exception IllegalArgumentException
* <ul>
* <li>ERROR_INVALID_ARGUMENT - if the limit is lower or
* equal to zero, or greater than Text.LIMIT</li>
* </ul>
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
* @see org.eclipse.swt.widgets.Text#LIMIT
*/
public void setTextLimit(int limit) {
checkWidget();
if (limit <= 0 || limit > Text.LIMIT) SWT.error(SWT.ERROR_INVALID_ARGUMENT);
Internal_PackageSupport.sendEvent(this, SWT.Modify);
OS.QLineEdit_setMaxLength(handle(), limit);
}
/**
* Shows the selection.
* <p>
* If the selection is already showing in the receiver, this method simply
* returns. Otherwise, lines are scrolled until the selection is visible.
* </p>
*
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void showSelection() {
checkWidget();
}
void setTraversalFlags(int type, int key, int modifier, int character) {
Internal_PackageSupport.setTraverseDoIt(this, false);
Internal_PackageSupport.setTraverseCancel(this, false);
if (type == SWT.TRAVERSE_MNEMONIC) {
Internal_PackageSupport.setTraverseDoIt(this, true);
return;
}
switch (key) {
case OS.QT_KEY_ENTER:
case OS.QT_KEY_RETURN:
case OS.QT_KEY_UP:
case OS.QT_KEY_DOWN:
case OS.QT_KEY_TAB:
Internal_PackageSupport.setTraverseDoIt(this, true);
break;
case OS.QT_KEY_LEFT:
case OS.QT_KEY_RIGHT:
Internal_PackageSupport.setTraverseDoIt(this, false);
break;
default:
Internal_PackageSupport.setTraversalFlags(this, type, key, modifier, character);
break;
}
}
void checkBorder () {
Internal_PackageSupport.checkBorder(this);
OS.QLineEdit_setFrame(Internal_PackageSupport.topHandle(this), (style() & SWT.BORDER) != 0);
}
void createHandle (int index) {
if(isExtended()) {
lastSelection = new Point(0,0);
}
variant = TextUtils.LINE_EDIT;
int handle = OS.QLineEdit_new();
Internal_PackageSupport.setHandle(this, handle);
Internal_PackageSupport.setTopHandle(this, handle);
OS.QWidget_setGeometry(handle, 0, 0, 0, 0);
OS.QLineEdit_setMaxLength(handle, Text.LIMIT);
int alignment = OS.QT_ALIGNLEFT;
if ((style() & SWT.CENTER) != 0) {
alignment = OS.QT_ALIGNHCENTER;
} else if ((style() & SWT.RIGHT) != 0) {
alignment = OS.QT_ALIGNRIGHT;
}
OS.QLineEdit_setAlignment(handle, alignment | OS.QT_ALIGNVCENTER);
switch(Internal_PackageSupport.extraStyle(this)) {
case NUMERIC:
// Intermediate restriction: anything that builds up to a valid integer is allowed
// I.E.: You can have + alone, since it is the beginning of a positive integer
validator = OS.QRegExpValidator_new(handle, "[\\+\\-]?\\d*");
OS.QWidget_setInputMethodHints(handle, OS.QT_IMHDIGITSONLY);
break;
case DECIMAL:
// Intermediate restriction: anything that builds up to a valid real is allowed
// I.E.: You can have '-.' alone, since it is the beginning of a negative real but
// cannot have 'E' since a exponential notation needs a valid real before E
validator = OS.QRegExpValidator_new(handle, "[\\+\\-]?\\d*(\\.?(\\d+([eE][\\+\\-]?\\d*)?)?)?");
OS.QWidget_setInputMethodHints(handle, OS.QT_IMHFORMATTEDNUMBERSONLY);
break;
case PHONENUMBER:
// Very loose restriction: any of the chars in the set allowed in any order and amount
validator = OS.QRegExpValidator_new(handle, "[\\+\\d\\sABCD,TP!W@;>IiGg\\*\\#\\.\\(\\)\\/\\-]*");
OS.QWidget_setInputMethodHints(handle, OS.QT_IMHDIALABLECHARACTERSONLY);
break;
default:
// Impossible to fall here
break;
}
OS.QLineEdit_setValidator(handle, validator);
Internal_PackageSupport.setState(this, Internal_PackageSupport.state(this) | WidgetState.HANDLE);
}
void hookEvents () {
Internal_PackageSupport.hookEvents(this);
int handle = handle();
int handler = OS.SignalHandler_new(handle, OS.QSIGNAL_TEXT_CHANGED);
OS.QObject_connectOrThrow(handle, "textChanged(const QString&)",
handler, "widgetSignal(const QString&)", OS.QT_AUTOCONNECTION);
handler = OS.SignalHandler_new(handle, OS.QSIGNAL_RETURN_PRESSED);
OS.QObject_connectOrThrow(handle, "returnPressed()",
handler, "widgetSignal()", OS.QT_AUTOCONNECTION);
if(isExtended()) {
handler = OS.SignalHandler_new(handle, OS.QSIGNAL_TEXT_CURSORPOSITIONCHANGED);
OS.QObject_connectOrThrow(handle, "cursorPositionChanged(int, int)",
handler, "widgetSignal(int, int)", OS.QT_AUTOCONNECTION);
handler = OS.SignalHandler_new(handle, OS.QSIGNAL_TEXT_SELECTIONCHANGED);
OS.QObject_connectOrThrow(handle, "selectionChanged()",
handler, "widgetSignal()", OS.QT_AUTOCONNECTION);
}
}
void qt_signal_return_pressed() {
Internal_PackageSupport.sendEvent(this, SWT.DefaultSelection);
}
void qt_signal_text_changed(String text) {
Internal_PackageSupport.sendEvent(this, SWT.Modify);
}
/*
* Extended ConstrainedText sends CaretMoved events
*/
void qt_signal_text_cursorPositionChanged(int oldPos, int newPos) {
if(isExtended()) {
Event event = new Event();
event.x = newPos;
Internal_PackageSupport.sendEvent(this, SWTExtension.CaretMoved, event);
}
Internal_PackageSupport.qt_signal_text_cursorPositionChanged(this, oldPos, newPos);
}
/*
* Extended ConstrainedText sends ContentSelected events
*/
void qt_signal_text_selectionChanged() {
if(isExtended()) {
Point selection = TextUtils.getSelection(variant, Internal_PackageSupport.topHandle(this));
int length = selection.y - selection.x;
// Qt sends selectionChanged signals when user drags on the text, even
// if there the selection content does not change. Filter out excessive
// events here.
if (lastSelection.y - lastSelection.x != length) {
lastSelection = selection;
Event event = new Event();
event.x = selection.x;
event.count = length;
Internal_PackageSupport.sendEvent(this, SWTExtension.ContentSelected, event);
}
}
Internal_PackageSupport.qt_signal_text_selectionChanged(this);
}
static int checkStyle(int style) {
return style | SWT.SINGLE;
}
static int checkConstrainedStyle(int style) {
switch (style) {
case NUMERIC:
case DECIMAL:
case PHONENUMBER:
return style;
case 0:
default:
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
// Fall through
return NUMERIC;
}
}
private final int handle() {
return Internal_PackageSupport.handle(this);
}
private final int style() {
return Internal_PackageSupport.style(this);
}
private final void setStyle(int style) {
Internal_PackageSupport.setStyle(this, style);
}
}