/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.swt.widgets;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.internal.cocoa.*;
/**
* Instances of this class are controls that allow the user
* to choose an item from a list of items, or optionally
* enter a new value by typing it into an editable text
* field. Often, Combo
s are used in the same place
* where a single selection List
widget could
* be used but space is limited. A Combo
takes
* less space than a List
widget and shows
* similar information.
*
* Note: Since Combo
s can contain both a list
* and an editable text field, it is possible to confuse methods
* which access one versus the other (compare for example,
* clearSelection()
and deselectAll()
).
* The API documentation is careful to indicate either "the
* receiver's list" or the "the receiver's text field" to
* distinguish between the two cases.
*
* Note that although this class is a subclass of Composite
,
* it does not make sense to add children to it, or set a layout on it.
*
*
* - Styles:
* - DROP_DOWN, READ_ONLY, SIMPLE
* - Events:
* - DefaultSelection, Modify, Selection, Verify
*
*
* Note: Only one of the styles DROP_DOWN and SIMPLE may be specified.
*
* IMPORTANT: This class is not intended to be subclassed.
*
*
* @see List
* @see Combo snippets
* @see SWT Example: ControlExample
* @see Sample code and further information
*/
public class Combo extends Composite {
int textLimit = LIMIT;
/**
* the operating system limit for the number of characters
* that the text field in an instance of this class can hold
*/
public static final int LIMIT;
/*
* These values can be different on different platforms.
* Therefore they are not initialized in the declaration
* to stop the compiler from inlining.
*/
static {
LIMIT = 0x7FFFFFFF;
}
/**
* Constructs a new instance of this class given its parent
* and a style value describing its behavior and appearance.
*
* The style value is either one of the style constants defined in
* class SWT
which is applicable to instances of this
* class, or must be built by bitwise OR'ing together
* (that is, using the int
"|" operator) two or more
* of those SWT
style constants. The class description
* lists the style constants that are applicable to the class.
* Style bits are also inherited from superclasses.
*
*
* @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
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the parent is null
*
* @exception SWTException
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
* - ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
*
*
* @see SWT#DROP_DOWN
* @see SWT#READ_ONLY
* @see SWT#SIMPLE
* @see Widget#checkSubclass
* @see Widget#getStyle
*/
public Combo (Composite parent, int style) {
super (parent, checkStyle (style));
}
/**
* Adds the argument to the end of the receiver's list.
*
* @param string the new item
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the string is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #add(String,int)
*/
public void add (String string) {
checkWidget ();
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
NSString str = NSString.stringWith(string);
if ((style & SWT.READ_ONLY) != 0) {
NSMenu nsMenu = ((NSPopUpButton)view).menu();
NSMenuItem nsItem = (NSMenuItem)new NSMenuItem().alloc();
nsItem.initWithTitle(str, 0, NSString.stringWith(""));
nsMenu.addItem(nsItem);
nsItem.release();
} else {
((NSComboBox)view).addItemWithObjectValue(str);
}
}
/**
* Adds the argument to the receiver's list at the given
* zero-relative index.
*
* Note: To add an item at the end of the list, use the
* result of calling getItemCount()
as the
* index or use add(String)
.
*
*
* @param string the new item
* @param index the index for the item
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the string is null
* - ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #add(String)
*/
public void add (String string, int index) {
checkWidget ();
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
int count = getItemCount ();
if (0 > index || index > count) error (SWT.ERROR_INVALID_RANGE);
NSString str = NSString.stringWith(string);
if ((style & SWT.READ_ONLY) != 0) {
NSMenu nsMenu = ((NSPopUpButton)view).menu();
NSMenuItem nsItem = (NSMenuItem)new NSMenuItem().alloc();
nsItem.initWithTitle(str, 0, NSString.stringWith(""));
nsMenu.insertItem(nsItem, index);
nsItem.release();
} else {
((NSComboBox)view).insertItemWithObjectValue(str, index);
}
}
/**
* 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 ModifyListener
* interface.
*
* @param listener the listener which should be notified
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see ModifyListener
* @see #removeModifyListener
*/
public void addModifyListener (ModifyListener listener) {
checkWidget();
if (listener == null) 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 user changes the receiver's selection, by sending
* it one of the messages defined in the SelectionListener
* interface.
*
* widgetSelected
is called when the user changes the combo's list selection.
* widgetDefaultSelected
is typically called when ENTER is pressed the combo's text area.
*
*
* @param listener the listener which should be notified
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see SelectionListener
* @see #removeSelectionListener
* @see SelectionEvent
*/
public void addSelectionListener(SelectionListener listener) {
checkWidget();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Selection,typedListener);
addListener (SWT.DefaultSelection,typedListener);
}
/**
* Adds the listener to the collection of listeners who will
* be notified when the receiver's text is verified, by sending
* it one of the messages defined in the VerifyListener
* interface.
*
* @param listener the listener which should be notified
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see VerifyListener
* @see #removeVerifyListener
*
* @since 3.1
*/
public void addVerifyListener (VerifyListener listener) {
checkWidget();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
TypedListener typedListener = new TypedListener (listener);
addListener (SWT.Verify, typedListener);
}
static int checkStyle (int style) {
/*
* Feature in Windows. It is not possible to create
* a combo box that has a border using Windows style
* bits. All combo boxes draw their own border and
* do not use the standard Windows border styles.
* Therefore, no matter what style bits are specified,
* clear the BORDER bits so that the SWT style will
* match the Windows widget.
*
* The Windows behavior is currently implemented on
* all platforms.
*/
style &= ~SWT.BORDER;
/*
* Even though it is legal to create this widget
* with scroll bars, they serve no useful purpose
* because they do not automatically scroll the
* widget's client area. The fix is to clear
* the SWT style.
*/
style &= ~(SWT.H_SCROLL | SWT.V_SCROLL);
style = checkBits (style, SWT.DROP_DOWN, SWT.SIMPLE, 0, 0, 0, 0);
if ((style & SWT.SIMPLE) != 0) return style & ~SWT.READ_ONLY;
return style;
}
protected void checkSubclass () {
if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
}
/**
* Sets the selection in the receiver's text field to an empty
* selection starting just before the first character. If the
* text field is editable, this has the effect of placing the
* i-beam at the start of the text.
*
* Note: To clear the selected items in the receiver's list,
* use deselectAll()
.
*
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #deselectAll
*/
public void clearSelection () {
checkWidget();
if ((style & SWT.READ_ONLY) == 0) {
Point selection = getSelection ();
selection.y = selection.x;
setSelection (selection);
}
}
void comboBoxSelectionDidChange(int notification) {
sendSelection();
}
public Point computeSize (int wHint, int hHint, boolean changed) {
checkWidget ();
int width = 0, height = 0;
NSControl widget = (NSControl)view;
NSRect oldRect = widget.frame();
widget.sizeToFit();
NSRect newRect = widget.frame();
widget.setFrame (oldRect);
width = (int)newRect.width;
height = (int)newRect.height;
if (wHint != SWT.DEFAULT) width = wHint;
if (hHint != SWT.DEFAULT) height = hHint;
return new Point (width, height);
}
/**
* Copies the selected text.
*
* The current selection is copied to the clipboard.
*
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 2.1
*/
public void copy () {
checkWidget ();
Point selection = getSelection ();
if (selection.x == selection.y) return;
// copyToClipboard (getText (selection.x, selection.y));
}
void createHandle () {
if ((style & SWT.READ_ONLY) != 0) {
NSPopUpButton widget = (NSPopUpButton)new SWTPopUpButton().alloc();
widget.initWithFrame(new NSRect(), false);
widget.menu().setAutoenablesItems(false);
widget.setTarget(widget);
widget.setAction(OS.sel_sendSelection);
widget.setTag(jniRef);
view = widget;
parent.view.addSubview_(widget);
} else {
NSComboBox widget = (NSComboBox)new SWTComboBox().alloc();
widget.initWithFrame(new NSRect());
widget.setTag(jniRef);
widget.setDelegate(widget);
view = widget;
parent.contentView().addSubview_(widget);
}
}
/**
* Cuts the selected text.
*
* The current selection is first copied to the
* clipboard and then deleted from the widget.
*
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 2.1
*/
public void cut () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) return;
// Point selection = getSelection ();
// if (selection.x == selection.y) return;
// int start = selection.x, end = selection.y;
// String text = getText ();
// String leftText = text.substring (0, start);
// String rightText = text.substring (end, text.length ());
// String oldText = text.substring (start, end);
// String newText = "";
// if (hooks (SWT.Verify) || filters (SWT.Verify)) {
// newText = verifyText (newText, start, end, null);
// if (newText == null) return;
// }
// char [] buffer = new char [oldText.length ()];
// oldText.getChars (0, buffer.length, buffer, 0);
// copyToClipboard (buffer);
// setText (leftText + newText + rightText, false);
// start += newText.length ();
// setSelection (new Point (start, start));
// sendEvent (SWT.Modify);
}
Color defaultBackground () {
return display.getSystemColor (SWT.COLOR_LIST_BACKGROUND);
}
Color defaultForeground () {
return display.getSystemColor (SWT.COLOR_LIST_FOREGROUND);
}
/**
* Deselects the item at the given zero-relative index in the receiver's
* list. If the item at the index was already deselected, it remains
* deselected. Indices that are out of range are ignored.
*
* @param index the index of the item to deselect
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void deselect (int index) {
checkWidget ();
if (index == -1) return;
if (index == getSelectionIndex ()) {
if ((style & SWT.READ_ONLY) != 0) {
((NSPopUpButton)view).selectItem(null);
sendEvent (SWT.Modify);
} else {
((NSComboBox)view).deselectItemAtIndex(index);
}
}
}
/**
* Deselects all selected items in the receiver's list.
*
* Note: To clear the selection in the receiver's text field,
* use clearSelection()
.
*
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #clearSelection
*/
public void deselectAll () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) {
((NSPopUpButton)view).selectItem(null);
sendEvent (SWT.Modify);
} else {
setText ("");
}
}
int getCharCount() {
NSString str;
if ((style & SWT.READ_ONLY) != 0) {
str = ((NSPopUpButton)view).titleOfSelectedItem();
} else {
str = new NSCell(((NSComboBox)view).cell()).title();
}
return str.length();
}
/**
* Returns the item at the given, zero-relative index in the
* receiver's list. Throws an exception if the index is out
* of range.
*
* @param index the index of the item to return
* @return the item at the given index
*
* @exception IllegalArgumentException
* - ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public String getItem (int index) {
checkWidget ();
int count = getItemCount ();
if (0 > index || index >= count) error (SWT.ERROR_INVALID_RANGE);
NSString str;
if ((style & SWT.READ_ONLY) != 0) {
str = ((NSPopUpButton)view).itemTitleAtIndex(index);
} else {
str = new NSString(((NSComboBox)view).itemObjectValueAtIndex(index));
}
if (str == null) error(SWT.ERROR_CANNOT_GET_ITEM);
char[] buffer = new char[str.length()];
str.getCharacters_(buffer);
return new String (buffer);
}
/**
* Returns the number of items contained in the receiver's list.
*
* @return the number of items
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public int getItemCount () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) {
return ((NSPopUpButton)view).numberOfItems();
} else {
return ((NSComboBox)view).numberOfItems();
}
}
/**
* Returns the height of the area which would be used to
* display one of the items in the receiver's list.
*
* @return the height of one item
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public int getItemHeight () {
checkWidget ();
//TODO - not supported by the OS
return 26;
}
/**
* Returns a (possibly empty) array of String
s which are
* the items in the receiver's list.
*
* Note: This is not the actual structure used by the receiver
* to maintain its list of items, so modifying the array will
* not affect the receiver.
*
*
* @return the items in the receiver's list
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public String [] getItems () {
checkWidget ();
int count = getItemCount ();
String [] result = new String [count];
for (int i=0; i
* ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 2.1.2
*/
public int getOrientation () {
checkWidget();
return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
}
/**
* Returns a Point
whose x coordinate is the
* character position representing the start of the selection
* in the receiver's text field, and whose y coordinate is the
* character position representing the end of the selection.
* An "empty" selection is indicated by the x and y coordinates
* having the same value.
*
* Indexing is zero based. The range of a selection is from
* 0..N where N is the number of characters in the widget.
*
*
* @return a point representing the selection start and end
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public Point getSelection () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) {
return new Point (0, getCharCount ());
} else {
// ControlEditTextSelectionRec selection;
// if (this.selection != null) {
// selection = this.selection;
// } else {
// selection = new ControlEditTextSelectionRec ();
// OS.GetControlData (handle, (short) OS.kHIComboBoxEditTextPart, OS.kControlEditTextSelectionTag, 4, selection, null);
// }
// return new Point (selection.selStart, selection.selEnd);
return null;
}
}
/**
* Returns the zero-relative index of the item which is currently
* selected in the receiver's list, or -1 if no item is selected.
*
* @return the index of the selected item
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public int getSelectionIndex () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) {
return ((NSPopUpButton)view).indexOfSelectedItem();
} else {
return ((NSComboBox)view).indexOfSelectedItem();
}
}
/**
* Returns a string containing a copy of the contents of the
* receiver's text field, or an empty string if there are no
* contents.
*
* @return the receiver's text
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public String getText () {
checkWidget ();
return getText(0, -1);
}
String getText (int start, int end) {
NSString str;
if ((style & SWT.READ_ONLY) != 0) {
str = ((NSPopUpButton)view).titleOfSelectedItem();
} else {
str = new NSCell(((NSComboBox)view).cell()).title();
}
if (str == null) return "";
int length = str.length();
char[] buffer = new char[length];
str.getCharacters_(buffer);
String string = new String(buffer);
if (end == -1) end = length;
start = Math.max(0, Math.min(start, length));
end = Math.max(0, Math.min(end, length));
return string.substring(start, end);
}
/**
* Returns the height of the receivers's text field.
*
* @return the text height
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public int getTextHeight () {
checkWidget();
//TODO - not supported by the OS
return 26;
}
/**
* Returns the maximum number of characters that the receiver's
* text field is capable of holding. If this has not been changed
* by setTextLimit()
, it will be the constant
* Combo.LIMIT
.
*
* @return the text limit
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #LIMIT
*/
public int getTextLimit () {
checkWidget();
return textLimit;
}
/**
* Gets the number of items that are visible in the drop
* down portion of the receiver's list.
*
* Note: This operation is a hint and is not supported on
* platforms that do not have this concept.
*
*
* @return the number of items that are visible
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 3.0
*/
public int getVisibleItemCount () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) {
return getItemCount ();
} else {
return ((NSComboBox)view).numberOfVisibleItems();
}
}
/**
* Searches the receiver's list starting at the first item
* (index 0) until an item is found that is equal to the
* argument, and returns the index of that item. If no item
* is found, returns -1.
*
* @param string the search item
* @return the index of the item
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the string is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public int indexOf (String string) {
return indexOf (string, 0);
}
/**
* Searches the receiver's list starting at the given,
* zero-relative index until an item is found that is equal
* to the argument, and returns the index of that item. If
* no item is found or the starting index is out of range,
* returns -1.
*
* @param string the search item
* @param start the zero-relative index at which to begin the search
* @return the index of the item
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the string is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public int indexOf (String string, int start) {
checkWidget();
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
int count = getItemCount ();
if (!(0 <= start && start < count)) return -1;
for (int i=start; i
* The selected text is deleted from the widget
* and new text inserted from the clipboard.
*
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 2.1
*/
public void paste () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) return;
// Point selection = getSelection ();
// int start = selection.x, end = selection.y;
// String text = getText ();
// String leftText = text.substring (0, start);
// String rightText = text.substring (end, text.length ());
// String newText = getClipboardText ();
// if (hooks (SWT.Verify) || filters (SWT.Verify)) {
// newText = verifyText (newText, start, end, null);
// if (newText == null) return;
// }
// if (textLimit != LIMIT) {
// int charCount = text.length ();
// if (charCount - (end - start) + newText.length() > textLimit) {
// newText = newText.substring(0, textLimit - charCount + (end - start));
// }
// }
// setText (leftText + newText + rightText, false);
// start += newText.length ();
// setSelection (new Point (start, start));
// sendEvent (SWT.Modify);
}
/**
* Removes the item from the receiver's list at the given
* zero-relative index.
*
* @param index the index for the item
*
* @exception IllegalArgumentException
* - ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void remove (int index) {
checkWidget ();
if (index == -1) error (SWT.ERROR_INVALID_RANGE);
int count = getItemCount ();
if (0 > index || index >= count) error (SWT.ERROR_INVALID_RANGE);
if ((style & SWT.READ_ONLY) != 0) {
((NSPopUpButton)view).removeItemAtIndex(index);
} else {
((NSComboBox)view).removeItemAtIndex(index);
}
}
/**
* Removes the items from the receiver's list which are
* between the given zero-relative start and end
* indices (inclusive).
*
* @param start the start of the range
* @param end the end of the range
*
* @exception IllegalArgumentException
* - ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void remove (int start, int end) {
checkWidget();
if (start > end) return;
int count = getItemCount ();
if (!(0 <= start && start <= end && end < count)) {
error (SWT.ERROR_INVALID_RANGE);
}
int newEnd = Math.min (end, count - 1);
for (int i=newEnd; i>=start; i--) {
remove(i);
}
}
/**
* Searches the receiver's list starting at the first item
* until an item is found that is equal to the argument,
* and removes that item from the list.
*
* @param string the item to remove
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the string is null
* - ERROR_INVALID_ARGUMENT - if the string is not found in the list
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void remove (String string) {
checkWidget ();
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
int index = indexOf (string, 0);
if (index == -1) error (SWT.ERROR_INVALID_ARGUMENT);
remove (index);
}
/**
* Removes all of the items from the receiver's list and clear the
* contents of receiver's text field.
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void removeAll () {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) {
((NSPopUpButton)view).removeAllItems();
} else {
setText ("", true);
((NSComboBox)view).removeAllItems();
}
}
/**
* 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
* - ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see ModifyListener
* @see #addModifyListener
*/
public void removeModifyListener (ModifyListener listener) {
checkWidget();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
if (eventTable == null) return;
eventTable.unhook (SWT.Modify, listener);
}
/**
* Removes the listener from the collection of listeners who will
* be notified when the user changes the receiver's selection.
*
* @param listener the listener which should no longer be notified
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see SelectionListener
* @see #addSelectionListener
*/
public void removeSelectionListener (SelectionListener listener) {
checkWidget();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
if (eventTable == null) return;
eventTable.unhook (SWT.Selection, listener);
eventTable.unhook (SWT.DefaultSelection,listener);
}
/**
* Removes the listener from the collection of listeners who will
* be notified when the control is verified.
*
* @param listener the listener which should no longer be notified
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the listener is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see VerifyListener
* @see #addVerifyListener
*
* @since 3.1
*/
public void removeVerifyListener (VerifyListener listener) {
checkWidget();
if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
if (eventTable == null) return;
eventTable.unhook (SWT.Verify, listener);
}
/**
* Selects the item at the given zero-relative index in the receiver's
* list. If the item at the index was already selected, it remains
* selected. Indices that are out of range are ignored.
*
* @param index the index of the item to select
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void select (int index) {
checkWidget ();
int count = getItemCount ();
if (0 <= index && index < count) {
if ((style & SWT.READ_ONLY) != 0) {
((NSPopUpButton)view).selectItemAtIndex(index);
sendEvent (SWT.Modify);
} else {
((NSComboBox)view).selectItemAtIndex(index);
}
}
}
//boolean sendKeyEvent (int type, Event event) {
// if (!super.sendKeyEvent (type, event)) {
// return false;
// }
// if (type != SWT.KeyDown) return true;
// if ((style & SWT.READ_ONLY) != 0) return true;
// if (event.character == 0) return true;
// if ((event.stateMask & SWT.COMMAND) != 0) return true;
// String oldText = "", newText = "";
// if (hooks (SWT.Verify) || filters (SWT.Verify)) {
// int charCount = getCharCount ();
// Point selection = getSelection ();
// int start = selection.x, end = selection.y;
// switch (event.character) {
// case SWT.BS:
// if (start == end) {
// if (start == 0) return true;
// start = Math.max (0, start - 1);
// }
// break;
// case SWT.DEL:
// if (start == end) {
// if (start == charCount) return true;
// end = Math.min (end + 1, charCount);
// }
// break;
// case SWT.CR:
// return true;
// default:
// if (event.character != '\t' && event.character < 0x20) return true;
// oldText = new String (new char [] {event.character});
// }
// newText = verifyText (oldText, start, end, event);
// if (newText == null) return false;
// if (charCount - (end - start) + newText.length () > textLimit) {
// return false;
// }
// if (newText != oldText) {
// String text = getText ();
// String leftText = text.substring (0, start);
// String rightText = text.substring (end, text.length ());
// setText (leftText + newText + rightText, false);
// start += newText.length ();
// setSelection (new Point (start, start));
// }
// }
// /*
// * Post the modify event so that the character will be inserted
// * into the widget when the modify event is delivered. Normally,
// * modify events are sent but it is safe to post the event here
// * because this method is called from the event loop.
// */
// postEvent (SWT.Modify);
// return newText == oldText;
//}
void sendSelection () {
postEvent(SWT.Selection);
}
void setBackground (float [] color) {
NSColor nsColor;
if (color == null) {
return; // TODO reset to OS default
} else {
nsColor = NSColor.colorWithDeviceRed(color[0], color[1], color[2], 1);
}
((NSTextField)view).setBackgroundColor(nsColor);
}
void setForeground (float [] color) {
NSColor nsColor;
if (color == null) {
return; // TODO reset to OS default
} else {
nsColor = NSColor.colorWithDeviceRed(color[0], color[1], color[2], 1);
}
((NSTextField)view).setTextColor(nsColor);
}
/**
* Sets the text of the item in the receiver's list at the given
* zero-relative index to the string argument.
*
* @param index the index for the item
* @param string the new text for the item
*
* @exception IllegalArgumentException
* - ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
* - ERROR_NULL_ARGUMENT - if the string is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setItem (int index, String string) {
checkWidget ();
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
int count = getItemCount ();
if (0 > index || index >= count) error (SWT.ERROR_INVALID_RANGE);
NSString str = NSString.stringWith(string);
if ((style & SWT.READ_ONLY) != 0) {
NSMenuItem nsItem = ((NSPopUpButton)view).itemAtIndex(index);
nsItem.setTitle(str);
} else {
NSComboBox widget = (NSComboBox)view;
widget.insertItemWithObjectValue(str, index);
widget.removeItemAtIndex(index + 1);
}
}
/**
* Sets the receiver's list to be the given array of items.
*
* @param items the array of items
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the items array is null
* - ERROR_INVALID_ARGUMENT - if an item in the items array is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setItems (String [] items) {
checkWidget();
if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
for (int i=0; itrue,
* and marks it invisible otherwise.
*
* If one of the receiver's ancestors is not visible or some
* other condition makes the receiver not visible, marking
* it visible may not actually cause it to be displayed.
*
*
* @param visible the new visibility state
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 3.4
*/
/*public*/ void setListVisible (boolean visible) {
checkWidget ();
if ((style & SWT.READ_ONLY) != 0) {
((NSPopUpButton)view).setPullsDown(visible);
} else {
}
}
/**
* Sets the orientation of the receiver, which must be one
* of the constants SWT.LEFT_TO_RIGHT
or SWT.RIGHT_TO_LEFT
.
*
*
* @param orientation new orientation style
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 2.1.2
*/
public void setOrientation (int orientation) {
checkWidget();
}
/**
* Sets the selection in the receiver's text field to the
* range specified by the argument whose x coordinate is the
* start of the selection and whose y coordinate is the end
* of the selection.
*
* @param selection a point representing the new selection start and end
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the point is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setSelection (Point selection) {
checkWidget ();
if (selection == null) error (SWT.ERROR_NULL_ARGUMENT);
if ((style & SWT.READ_ONLY) == 0) {
// int length = getCharCount ();
// int start = selection.x, end = selection.y;
// ControlEditTextSelectionRec sel = new ControlEditTextSelectionRec ();
// sel.selStart = (short) Math.min (Math.max (Math.min (start, end), 0), length);
// sel.selEnd = (short) Math.min (Math.max (Math.max (start, end), 0), length);
// if (hasFocus ()) {
// OS.SetControlData (handle, OS.kHIComboBoxEditTextPart, OS.kControlEditTextSelectionTag, 4, sel);
// } else {
// this.selection = sel;
// }
}
}
/**
* Sets the contents of the receiver's text field to the
* given string.
*
* Note: The text field in a Combo
is typically
* only capable of displaying a single line of text. Thus,
* setting the text to a string containing line breaks or
* other special characters will probably cause it to
* display incorrectly.
*
*
* @param string the new text
*
* @exception IllegalArgumentException
* - ERROR_NULL_ARGUMENT - if the string is null
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*/
public void setText (String string) {
checkWidget ();
if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
setText (string, true);
}
void setText (String string, boolean notify) {
if (notify) {
if (hooks (SWT.Verify) || filters (SWT.Verify)) {
string = verifyText (string, 0, getCharCount (), null);
if (string == null) return;
}
}
if ((style & SWT.READ_ONLY) != 0) {
int index = indexOf (string);
if (index != -1 && index != getSelectionIndex ()) {
select (index);
if (notify) sendEvent (SWT.Modify);
}
} else {
new NSCell(((NSComboBox)view).cell()).setTitle(NSString.stringWith(string));
if (notify) sendEvent (SWT.Modify);
}
}
/**
* Sets the maximum number of characters that the receiver's
* text field is capable of holding to be the argument.
*
* To reset this value to the default, use setTextLimit(Combo.LIMIT)
.
* Specifying a limit value larger than Combo.LIMIT
sets the
* receiver's limit to Combo.LIMIT
.
*
* @param limit new text limit
*
* @exception IllegalArgumentException
* - ERROR_CANNOT_BE_ZERO - if the limit is zero
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @see #LIMIT
*/
public void setTextLimit (int limit) {
checkWidget ();
if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
textLimit = limit;
}
/**
* Sets the number of items that are visible in the drop
* down portion of the receiver's list.
*
* Note: This operation is a hint and is not supported on
* platforms that do not have this concept.
*
*
* @param count the new number of items to be visible
*
* @exception SWTException
* - ERROR_WIDGET_DISPOSED - if the receiver has been disposed
* - ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
*
*
* @since 3.0
*/
public void setVisibleItemCount (int count) {
checkWidget ();
if (count < 0) return;
if ((style & SWT.READ_ONLY) != 0) {
//TODO
} else {
((NSComboBox)view).setNumberOfVisibleItems(count);
}
}
String verifyText (String string, int start, int end, Event keyEvent) {
Event event = new Event ();
event.text = string;
event.start = start;
event.end = end;
if (keyEvent != null) {
event.character = keyEvent.character;
event.keyCode = keyEvent.keyCode;
event.stateMask = keyEvent.stateMask;
}
/*
* It is possible (but unlikely), that application
* code could have disposed the widget in the verify
* event. If this happens, answer null to cancel
* the operation.
*/
sendEvent (SWT.Verify, event);
if (!event.doit || isDisposed ()) return null;
return event.text;
}
}