comparison dwt/widgets/Combo.d @ 0:380af2bdd8e5

Upload of whole dwt tree
author Jacob Carlborg <doob@me.com> <jacob.carlborg@gmail.com>
date Sat, 09 Aug 2008 17:00:02 +0200
parents
children 649b8e223d5a
comparison
equal deleted inserted replaced
-1:000000000000 0:380af2bdd8e5
1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 module dwt.widgets.Combo;
12
13 import dwt.dwthelper.utils;
14
15
16 import dwt.DWT;
17 import dwt.DWTException;
18 import dwt.events.ModifyListener;
19 import dwt.events.SelectionEvent;
20 import dwt.events.SelectionListener;
21 import dwt.events.VerifyListener;
22 import dwt.graphics.Color;
23 import dwt.graphics.Point;
24 import dwt.internal.cocoa.NSCell;
25 import dwt.internal.cocoa.NSColor;
26 import dwt.internal.cocoa.NSComboBox;
27 import dwt.internal.cocoa.NSControl;
28 import dwt.internal.cocoa.NSMenu;
29 import dwt.internal.cocoa.NSMenuItem;
30 import dwt.internal.cocoa.NSPopUpButton;
31 import dwt.internal.cocoa.NSRect;
32 import dwt.internal.cocoa.NSString;
33 import dwt.internal.cocoa.NSTextField;
34 import dwt.internal.cocoa.OS;
35 import dwt.internal.cocoa.SWTComboBox;
36 import dwt.internal.cocoa.SWTPopUpButton;
37
38 /**
39 * Instances of this class are controls that allow the user
40 * to choose an item from a list of items, or optionally
41 * enter a new value by typing it into an editable text
42 * field. Often, <code>Combo</code>s are used in the same place
43 * where a single selection <code>List</code> widget could
44 * be used but space is limited. A <code>Combo</code> takes
45 * less space than a <code>List</code> widget and shows
46 * similar information.
47 * <p>
48 * Note: Since <code>Combo</code>s can contain both a list
49 * and an editable text field, it is possible to confuse methods
50 * which access one versus the other (compare for example,
51 * <code>clearSelection()</code> and <code>deselectAll()</code>).
52 * The API documentation is careful to indicate either "the
53 * receiver's list" or the "the receiver's text field" to
54 * distinguish between the two cases.
55 * </p><p>
56 * Note that although this class is a subclass of <code>Composite</code>,
57 * it does not make sense to add children to it, or set a layout on it.
58 * </p>
59 * <dl>
60 * <dt><b>Styles:</b></dt>
61 * <dd>DROP_DOWN, READ_ONLY, SIMPLE</dd>
62 * <dt><b>Events:</b></dt>
63 * <dd>DefaultSelection, Modify, Selection, Verify</dd>
64 * </dl>
65 * <p>
66 * Note: Only one of the styles DROP_DOWN and SIMPLE may be specified.
67 * </p><p>
68 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
69 * </p>
70 *
71 * @see List
72 */
73 public class Combo extends Composite {
74 int textLimit = LIMIT;
75
76 /**
77 * the operating system limit for the number of characters
78 * that the text field in an instance of this class can hold
79 */
80 public static final int LIMIT;
81
82 /*
83 * These values can be different on different platforms.
84 * Therefore they are not initialized in the declaration
85 * to stop the compiler from inlining.
86 */
87 static {
88 LIMIT = 0x7FFFFFFF;
89 }
90
91
92 /**
93 * Constructs a new instance of this class given its parent
94 * and a style value describing its behavior and appearance.
95 * <p>
96 * The style value is either one of the style constants defined in
97 * class <code>DWT</code> which is applicable to instances of this
98 * class, or must be built by <em>bitwise OR</em>'ing together
99 * (that is, using the <code>int</code> "|" operator) two or more
100 * of those <code>DWT</code> style constants. The class description
101 * lists the style constants that are applicable to the class.
102 * Style bits are also inherited from superclasses.
103 * </p>
104 *
105 * @param parent a composite control which will be the parent of the new instance (cannot be null)
106 * @param style the style of control to construct
107 *
108 * @exception IllegalArgumentException <ul>
109 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
110 * </ul>
111 * @exception DWTException <ul>
112 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
113 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
114 * </ul>
115 *
116 * @see DWT#DROP_DOWN
117 * @see DWT#READ_ONLY
118 * @see DWT#SIMPLE
119 * @see Widget#checkSubclass
120 * @see Widget#getStyle
121 */
122 public Combo (Composite parent, int style) {
123 super (parent, checkStyle (style));
124 }
125
126 /**
127 * Adds the argument to the end of the receiver's list.
128 *
129 * @param string the new item
130 *
131 * @exception IllegalArgumentException <ul>
132 * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
133 * </ul>
134 * @exception DWTException <ul>
135 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
136 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
137 * </ul>
138 *
139 * @see #add(String,int)
140 */
141 public void add (String string) {
142 checkWidget ();
143 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
144 NSString str = NSString.stringWith(string);
145 if ((style & DWT.READ_ONLY) !is 0) {
146 NSMenu nsMenu = ((NSPopUpButton)view).menu();
147 NSMenuItem nsItem = (NSMenuItem)new NSMenuItem().alloc();
148 nsItem.initWithTitle(str, 0, NSString.stringWith(""));
149 nsMenu.addItem(nsItem);
150 nsItem.release();
151 } else {
152 ((NSComboBox)view).addItemWithObjectValue(str);
153 }
154 }
155
156 /**
157 * Adds the argument to the receiver's list at the given
158 * zero-relative index.
159 * <p>
160 * Note: To add an item at the end of the list, use the
161 * result of calling <code>getItemCount()</code> as the
162 * index or use <code>add(String)</code>.
163 * </p>
164 *
165 * @param string the new item
166 * @param index the index for the item
167 *
168 * @exception IllegalArgumentException <ul>
169 * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
170 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)</li>
171 * </ul>
172 * @exception DWTException <ul>
173 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
174 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
175 * </ul>
176 *
177 * @see #add(String)
178 */
179 public void add (String string, int index) {
180 checkWidget ();
181 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
182 int count = getItemCount ();
183 if (0 > index || index > count) error (DWT.ERROR_INVALID_RANGE);
184 NSString str = NSString.stringWith(string);
185 if ((style & DWT.READ_ONLY) !is 0) {
186 NSMenu nsMenu = ((NSPopUpButton)view).menu();
187 NSMenuItem nsItem = (NSMenuItem)new NSMenuItem().alloc();
188 nsItem.initWithTitle(str, 0, NSString.stringWith(""));
189 nsMenu.insertItem(nsItem, index);
190 nsItem.release();
191 } else {
192 ((NSComboBox)view).insertItemWithObjectValue(str, index);
193 }
194 }
195
196 /**
197 * Adds the listener to the collection of listeners who will
198 * be notified when the receiver's text is modified, by sending
199 * it one of the messages defined in the <code>ModifyListener</code>
200 * interface.
201 *
202 * @param listener the listener which should be notified
203 *
204 * @exception IllegalArgumentException <ul>
205 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
206 * </ul>
207 * @exception DWTException <ul>
208 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
209 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
210 * </ul>
211 *
212 * @see ModifyListener
213 * @see #removeModifyListener
214 */
215 public void addModifyListener (ModifyListener listener) {
216 checkWidget();
217 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
218 TypedListener typedListener = new TypedListener (listener);
219 addListener (DWT.Modify, typedListener);
220 }
221
222 /**
223 * Adds the listener to the collection of listeners who will
224 * be notified when the user changes the receiver's selection, by sending
225 * it one of the messages defined in the <code>SelectionListener</code>
226 * interface.
227 * <p>
228 * <code>widgetSelected</code> is called when the user changes the combo's list selection.
229 * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed the combo's text area.
230 * </p>
231 *
232 * @param listener the listener which should be notified
233 *
234 * @exception IllegalArgumentException <ul>
235 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
236 * </ul>
237 * @exception DWTException <ul>
238 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
239 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
240 * </ul>
241 *
242 * @see SelectionListener
243 * @see #removeSelectionListener
244 * @see SelectionEvent
245 */
246 public void addSelectionListener(SelectionListener listener) {
247 checkWidget();
248 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
249 TypedListener typedListener = new TypedListener (listener);
250 addListener (DWT.Selection,typedListener);
251 addListener (DWT.DefaultSelection,typedListener);
252 }
253
254 /**
255 * Adds the listener to the collection of listeners who will
256 * be notified when the receiver's text is verified, by sending
257 * it one of the messages defined in the <code>VerifyListener</code>
258 * interface.
259 *
260 * @param listener the listener which should be notified
261 *
262 * @exception IllegalArgumentException <ul>
263 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
264 * </ul>
265 * @exception DWTException <ul>
266 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
267 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
268 * </ul>
269 *
270 * @see VerifyListener
271 * @see #removeVerifyListener
272 *
273 * @since 3.1
274 */
275 public void addVerifyListener (VerifyListener listener) {
276 checkWidget();
277 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
278 TypedListener typedListener = new TypedListener (listener);
279 addListener (DWT.Verify, typedListener);
280 }
281
282 static int checkStyle (int style) {
283 /*
284 * Feature in Windows. It is not possible to create
285 * a combo box that has a border using Windows style
286 * bits. All combo boxes draw their own border and
287 * do not use the standard Windows border styles.
288 * Therefore, no matter what style bits are specified,
289 * clear the BORDER bits so that the DWT style will
290 * match the Windows widget.
291 *
292 * The Windows behavior is currently implemented on
293 * all platforms.
294 */
295 style &= ~DWT.BORDER;
296
297 /*
298 * Even though it is legal to create this widget
299 * with scroll bars, they serve no useful purpose
300 * because they do not automatically scroll the
301 * widget's client area. The fix is to clear
302 * the DWT style.
303 */
304 style &= ~(DWT.H_SCROLL | DWT.V_SCROLL);
305 style = checkBits (style, DWT.DROP_DOWN, DWT.SIMPLE, 0, 0, 0, 0);
306 if ((style & DWT.SIMPLE) !is 0) return style & ~DWT.READ_ONLY;
307 return style;
308 }
309
310 protected void checkSubclass () {
311 if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS);
312 }
313
314 /**
315 * Sets the selection in the receiver's text field to an empty
316 * selection starting just before the first character. If the
317 * text field is editable, this has the effect of placing the
318 * i-beam at the start of the text.
319 * <p>
320 * Note: To clear the selected items in the receiver's list,
321 * use <code>deselectAll()</code>.
322 * </p>
323 *
324 * @exception DWTException <ul>
325 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
326 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
327 * </ul>
328 *
329 * @see #deselectAll
330 */
331 public void clearSelection () {
332 checkWidget();
333 if ((style & DWT.READ_ONLY) is 0) {
334 Point selection = getSelection ();
335 selection.y = selection.x;
336 setSelection (selection);
337 }
338 }
339
340 void comboBoxSelectionDidChange(int notification) {
341 sendSelection();
342 }
343
344 public Point computeSize (int wHint, int hHint, bool changed) {
345 checkWidget ();
346 int width = 0, height = 0;
347 NSControl widget = (NSControl)view;
348 NSRect oldRect = widget.frame();
349 widget.sizeToFit();
350 NSRect newRect = widget.frame();
351 widget.setFrame (oldRect);
352 width = (int)newRect.width;
353 height = (int)newRect.height;
354 if (wHint !is DWT.DEFAULT) width = wHint;
355 if (hHint !is DWT.DEFAULT) height = hHint;
356 return new Point (width, height);
357 }
358
359 /**
360 * Copies the selected text.
361 * <p>
362 * The current selection is copied to the clipboard.
363 * </p>
364 *
365 * @exception DWTException <ul>
366 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
367 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
368 * </ul>
369 *
370 * @since 2.1
371 */
372 public void copy () {
373 checkWidget ();
374 Point selection = getSelection ();
375 if (selection.x is selection.y) return;
376 // copyToClipboard (getText (selection.x, selection.y));
377 }
378
379 void createHandle () {
380 if ((style & DWT.READ_ONLY) !is 0) {
381 NSPopUpButton widget = (NSPopUpButton)new SWTPopUpButton().alloc();
382 widget.initWithFrame(new NSRect(), false);
383 widget.menu().setAutoenablesItems(false);
384 widget.setTarget(widget);
385 widget.setAction(OS.sel_sendSelection);
386 widget.setTag(jniRef);
387 view = widget;
388 parent.view.addSubview_(widget);
389 } else {
390 NSComboBox widget = (NSComboBox)new SWTComboBox().alloc();
391 widget.initWithFrame(new NSRect());
392 widget.setTag(jniRef);
393 widget.setDelegate(widget);
394 view = widget;
395 parent.contentView().addSubview_(widget);
396 }
397 }
398
399 /**
400 * Cuts the selected text.
401 * <p>
402 * The current selection is first copied to the
403 * clipboard and then deleted from the widget.
404 * </p>
405 *
406 * @exception DWTException <ul>
407 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
408 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
409 * </ul>
410 *
411 * @since 2.1
412 */
413 public void cut () {
414 checkWidget ();
415 if ((style & DWT.READ_ONLY) !is 0) return;
416 // Point selection = getSelection ();
417 // if (selection.x is selection.y) return;
418 // int start = selection.x, end = selection.y;
419 // String text = getText ();
420 // String leftText = text.substring (0, start);
421 // String rightText = text.substring (end, text.length ());
422 // String oldText = text.substring (start, end);
423 // String newText = "";
424 // if (hooks (DWT.Verify) || filters (DWT.Verify)) {
425 // newText = verifyText (newText, start, end, null);
426 // if (newText is null) return;
427 // }
428 // char [] buffer = new char [oldText.length ()];
429 // oldText.getChars (0, buffer.length, buffer, 0);
430 // copyToClipboard (buffer);
431 // setText (leftText + newText + rightText, false);
432 // start += newText.length ();
433 // setSelection (new Point (start, start));
434 // sendEvent (DWT.Modify);
435 }
436
437 Color defaultBackground () {
438 return display.getSystemColor (DWT.COLOR_LIST_BACKGROUND);
439 }
440
441 Color defaultForeground () {
442 return display.getSystemColor (DWT.COLOR_LIST_FOREGROUND);
443 }
444
445 /**
446 * Deselects the item at the given zero-relative index in the receiver's
447 * list. If the item at the index was already deselected, it remains
448 * deselected. Indices that are out of range are ignored.
449 *
450 * @param index the index of the item to deselect
451 *
452 * @exception DWTException <ul>
453 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
454 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
455 * </ul>
456 */
457 public void deselect (int index) {
458 checkWidget ();
459 if (index is -1) return;
460 if (index is getSelectionIndex ()) {
461 if ((style & DWT.READ_ONLY) !is 0) {
462 ((NSPopUpButton)view).selectItem(null);
463 sendEvent (DWT.Modify);
464 } else {
465 ((NSComboBox)view).deselectItemAtIndex(index);
466 }
467 }
468 }
469
470 /**
471 * Deselects all selected items in the receiver's list.
472 * <p>
473 * Note: To clear the selection in the receiver's text field,
474 * use <code>clearSelection()</code>.
475 * </p>
476 *
477 * @exception DWTException <ul>
478 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
479 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
480 * </ul>
481 *
482 * @see #clearSelection
483 */
484 public void deselectAll () {
485 checkWidget ();
486 if ((style & DWT.READ_ONLY) !is 0) {
487 ((NSPopUpButton)view).selectItem(null);
488 sendEvent (DWT.Modify);
489 } else {
490 setText ("");
491 }
492 }
493
494 int getCharCount() {
495 NSString str;
496 if ((style & DWT.READ_ONLY) !is 0) {
497 str = ((NSPopUpButton)view).titleOfSelectedItem();
498 } else {
499 str = new NSCell(((NSComboBox)view).cell()).title();
500 }
501 return str.length();
502 }
503
504 /**
505 * Returns the item at the given, zero-relative index in the
506 * receiver's list. Throws an exception if the index is out
507 * of range.
508 *
509 * @param index the index of the item to return
510 * @return the item at the given index
511 *
512 * @exception IllegalArgumentException <ul>
513 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
514 * </ul>
515 * @exception DWTException <ul>
516 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
517 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
518 * </ul>
519 */
520 public String getItem (int index) {
521 checkWidget ();
522 int count = getItemCount ();
523 if (0 > index || index >= count) error (DWT.ERROR_INVALID_RANGE);
524 NSString str;
525 if ((style & DWT.READ_ONLY) !is 0) {
526 str = ((NSPopUpButton)view).itemTitleAtIndex(index);
527 } else {
528 str = new NSString(((NSComboBox)view).itemObjectValueAtIndex(index));
529 }
530 if (str is null) error(DWT.ERROR_CANNOT_GET_ITEM);
531 char[] buffer = new char[str.length()];
532 str.getCharacters_(buffer);
533 return new String (buffer);
534 }
535
536 /**
537 * Returns the number of items contained in the receiver's list.
538 *
539 * @return the number of items
540 *
541 * @exception DWTException <ul>
542 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
543 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
544 * </ul>
545 */
546 public int getItemCount () {
547 checkWidget ();
548 if ((style & DWT.READ_ONLY) !is 0) {
549 return ((NSPopUpButton)view).numberOfItems();
550 } else {
551 return ((NSComboBox)view).numberOfItems();
552 }
553 }
554
555 /**
556 * Returns the height of the area which would be used to
557 * display <em>one</em> of the items in the receiver's list.
558 *
559 * @return the height of one item
560 *
561 * @exception DWTException <ul>
562 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
563 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
564 * </ul>
565 */
566 public int getItemHeight () {
567 checkWidget ();
568 //TODO - not supported by the OS
569 return 26;
570 }
571
572 /**
573 * Returns a (possibly empty) array of <code>String</code>s which are
574 * the items in the receiver's list.
575 * <p>
576 * Note: This is not the actual structure used by the receiver
577 * to maintain its list of items, so modifying the array will
578 * not affect the receiver.
579 * </p>
580 *
581 * @return the items in the receiver's list
582 *
583 * @exception DWTException <ul>
584 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
585 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
586 * </ul>
587 */
588 public String [] getItems () {
589 checkWidget ();
590 int count = getItemCount ();
591 String [] result = new String [count];
592 for (int i=0; i<count; i++) result [i] = getItem (i);
593 return result;
594 }
595
596 int getMininumHeight () {
597 return getTextHeight ();
598 }
599
600 /**
601 * Returns the orientation of the receiver.
602 *
603 * @return the orientation style
604 *
605 * @exception DWTException <ul>
606 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
607 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
608 * </ul>
609 *
610 * @since 2.1.2
611 */
612 public int getOrientation () {
613 checkWidget();
614 return style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT);
615 }
616
617 /**
618 * Returns a <code>Point</code> whose x coordinate is the
619 * character position representing the start of the selection
620 * in the receiver's text field, and whose y coordinate is the
621 * character position representing the end of the selection.
622 * An "empty" selection is indicated by the x and y coordinates
623 * having the same value.
624 * <p>
625 * Indexing is zero based. The range of a selection is from
626 * 0..N where N is the number of characters in the widget.
627 * </p>
628 *
629 * @return a point representing the selection start and end
630 *
631 * @exception DWTException <ul>
632 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
633 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
634 * </ul>
635 */
636 public Point getSelection () {
637 checkWidget ();
638 if ((style & DWT.READ_ONLY) !is 0) {
639 return new Point (0, getCharCount ());
640 } else {
641 // ControlEditTextSelectionRec selection;
642 // if (this.selection !is null) {
643 // selection = this.selection;
644 // } else {
645 // selection = new ControlEditTextSelectionRec ();
646 // OS.GetControlData (handle, (short) OS.kHIComboBoxEditTextPart, OS.kControlEditTextSelectionTag, 4, selection, null);
647 // }
648 // return new Point (selection.selStart, selection.selEnd);
649 return null;
650 }
651 }
652
653 /**
654 * Returns the zero-relative index of the item which is currently
655 * selected in the receiver's list, or -1 if no item is selected.
656 *
657 * @return the index of the selected item
658 *
659 * @exception DWTException <ul>
660 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
661 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
662 * </ul>
663 */
664 public int getSelectionIndex () {
665 checkWidget ();
666 if ((style & DWT.READ_ONLY) !is 0) {
667 return ((NSPopUpButton)view).indexOfSelectedItem();
668 } else {
669 return ((NSComboBox)view).indexOfSelectedItem();
670 }
671 }
672
673 /**
674 * Returns a string containing a copy of the contents of the
675 * receiver's text field, or an empty string if there are no
676 * contents.
677 *
678 * @return the receiver's text
679 *
680 * @exception DWTException <ul>
681 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
682 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
683 * </ul>
684 */
685 public String getText () {
686 checkWidget ();
687 return getText(0, -1);
688 }
689
690 String getText (int start, int end) {
691 NSString str;
692 if ((style & DWT.READ_ONLY) !is 0) {
693 str = ((NSPopUpButton)view).titleOfSelectedItem();
694 } else {
695 str = new NSCell(((NSComboBox)view).cell()).title();
696 }
697 if (str is null) return "";
698 int length = str.length();
699 char[] buffer = new char[length];
700 str.getCharacters_(buffer);
701 String string = new String(buffer);
702 if (end is -1) end = length;
703 start = Math.max(0, Math.min(start, length));
704 end = Math.max(0, Math.min(end, length));
705 return string.substring(start, end);
706 }
707
708 /**
709 * Returns the height of the receivers's text field.
710 *
711 * @return the text height
712 *
713 * @exception DWTException <ul>
714 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
715 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
716 * </ul>
717 */
718 public int getTextHeight () {
719 checkWidget();
720 //TODO - not supported by the OS
721 return 26;
722 }
723
724 /**
725 * Returns the maximum number of characters that the receiver's
726 * text field is capable of holding. If this has not been changed
727 * by <code>setTextLimit()</code>, it will be the constant
728 * <code>Combo.LIMIT</code>.
729 *
730 * @return the text limit
731 *
732 * @exception DWTException <ul>
733 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
734 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
735 * </ul>
736 *
737 * @see #LIMIT
738 */
739 public int getTextLimit () {
740 checkWidget();
741 return textLimit;
742 }
743
744 /**
745 * Gets the number of items that are visible in the drop
746 * down portion of the receiver's list.
747 * <p>
748 * Note: This operation is a hint and is not supported on
749 * platforms that do not have this concept.
750 * </p>
751 *
752 * @return the number of items that are visible
753 *
754 * @exception DWTException <ul>
755 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
756 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
757 * </ul>
758 *
759 * @since 3.0
760 */
761 public int getVisibleItemCount () {
762 checkWidget ();
763 if ((style & DWT.READ_ONLY) !is 0) {
764 return getItemCount ();
765 } else {
766 return ((NSComboBox)view).numberOfVisibleItems();
767 }
768 }
769
770 /**
771 * Searches the receiver's list starting at the first item
772 * (index 0) until an item is found that is equal to the
773 * argument, and returns the index of that item. If no item
774 * is found, returns -1.
775 *
776 * @param string the search item
777 * @return the index of the item
778 *
779 * @exception IllegalArgumentException <ul>
780 * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
781 * </ul>
782 * @exception DWTException <ul>
783 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
784 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
785 * </ul>
786 */
787 public int indexOf (String string) {
788 return indexOf (string, 0);
789 }
790
791 /**
792 * Searches the receiver's list starting at the given,
793 * zero-relative index until an item is found that is equal
794 * to the argument, and returns the index of that item. If
795 * no item is found or the starting index is out of range,
796 * returns -1.
797 *
798 * @param string the search item
799 * @param start the zero-relative index at which to begin the search
800 * @return the index of the item
801 *
802 * @exception IllegalArgumentException <ul>
803 * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
804 * </ul>
805 * @exception DWTException <ul>
806 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
807 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
808 * </ul>
809 */
810 public int indexOf (String string, int start) {
811 checkWidget();
812 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
813 int count = getItemCount ();
814 if (!(0 <= start && start < count)) return -1;
815 for (int i=start; i<count; i++) {
816 if (string.equals (getItem (i))) {
817 return i;
818 }
819 }
820 return -1;
821 }
822
823 /**
824 * Pastes text from clipboard.
825 * <p>
826 * The selected text is deleted from the widget
827 * and new text inserted from the clipboard.
828 * </p>
829 *
830 * @exception DWTException <ul>
831 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
832 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
833 * </ul>
834 *
835 * @since 2.1
836 */
837 public void paste () {
838 checkWidget ();
839 if ((style & DWT.READ_ONLY) !is 0) return;
840 // Point selection = getSelection ();
841 // int start = selection.x, end = selection.y;
842 // String text = getText ();
843 // String leftText = text.substring (0, start);
844 // String rightText = text.substring (end, text.length ());
845 // String newText = getClipboardText ();
846 // if (hooks (DWT.Verify) || filters (DWT.Verify)) {
847 // newText = verifyText (newText, start, end, null);
848 // if (newText is null) return;
849 // }
850 // if (textLimit !is LIMIT) {
851 // int charCount = text.length ();
852 // if (charCount - (end - start) + newText.length() > textLimit) {
853 // newText = newText.substring(0, textLimit - charCount + (end - start));
854 // }
855 // }
856 // setText (leftText + newText + rightText, false);
857 // start += newText.length ();
858 // setSelection (new Point (start, start));
859 // sendEvent (DWT.Modify);
860 }
861
862 /**
863 * Removes the item from the receiver's list at the given
864 * zero-relative index.
865 *
866 * @param index the index for the item
867 *
868 * @exception IllegalArgumentException <ul>
869 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
870 * </ul>
871 * @exception DWTException <ul>
872 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
873 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
874 * </ul>
875 */
876 public void remove (int index) {
877 checkWidget ();
878 if (index is -1) error (DWT.ERROR_INVALID_RANGE);
879 int count = getItemCount ();
880 if (0 > index || index >= count) error (DWT.ERROR_INVALID_RANGE);
881 if ((style & DWT.READ_ONLY) !is 0) {
882 ((NSPopUpButton)view).removeItemAtIndex(index);
883 } else {
884 ((NSComboBox)view).removeItemAtIndex(index);
885 }
886 }
887
888 /**
889 * Removes the items from the receiver's list which are
890 * between the given zero-relative start and end
891 * indices (inclusive).
892 *
893 * @param start the start of the range
894 * @param end the end of the range
895 *
896 * @exception IllegalArgumentException <ul>
897 * <li>ERROR_INVALID_RANGE - if either the start or end are not between 0 and the number of elements in the list minus 1 (inclusive)</li>
898 * </ul>
899 * @exception DWTException <ul>
900 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
901 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
902 * </ul>
903 */
904 public void remove (int start, int end) {
905 checkWidget();
906 if (start > end) return;
907 int count = getItemCount ();
908 if (!(0 <= start && start <= end && end < count)) {
909 error (DWT.ERROR_INVALID_RANGE);
910 }
911 int newEnd = Math.min (end, count - 1);
912 for (int i=newEnd; i>=start; i--) {
913 remove(i);
914 }
915 }
916
917 /**
918 * Searches the receiver's list starting at the first item
919 * until an item is found that is equal to the argument,
920 * and removes that item from the list.
921 *
922 * @param string the item to remove
923 *
924 * @exception IllegalArgumentException <ul>
925 * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
926 * <li>ERROR_INVALID_ARGUMENT - if the string is not found in the list</li>
927 * </ul>
928 * @exception DWTException <ul>
929 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
930 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
931 * </ul>
932 */
933 public void remove (String string) {
934 checkWidget ();
935 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
936 int index = indexOf (string, 0);
937 if (index is -1) error (DWT.ERROR_INVALID_ARGUMENT);
938 remove (index);
939 }
940
941 /**
942 * Removes all of the items from the receiver's list and clear the
943 * contents of receiver's text field.
944 * <p>
945 * @exception DWTException <ul>
946 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
947 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
948 * </ul>
949 */
950 public void removeAll () {
951 checkWidget ();
952 if ((style & DWT.READ_ONLY) !is 0) {
953 ((NSPopUpButton)view).removeAllItems();
954 } else {
955 setText ("", true);
956 ((NSComboBox)view).removeAllItems();
957 }
958 }
959
960 /**
961 * Removes the listener from the collection of listeners who will
962 * be notified when the receiver's text is modified.
963 *
964 * @param listener the listener which should no longer be notified
965 *
966 * @exception IllegalArgumentException <ul>
967 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
968 * </ul>
969 * @exception DWTException <ul>
970 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
971 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
972 * </ul>
973 *
974 * @see ModifyListener
975 * @see #addModifyListener
976 */
977 public void removeModifyListener (ModifyListener listener) {
978 checkWidget();
979 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
980 if (eventTable is null) return;
981 eventTable.unhook (DWT.Modify, listener);
982 }
983
984 /**
985 * Removes the listener from the collection of listeners who will
986 * be notified when the user changes the receiver's selection.
987 *
988 * @param listener the listener which should no longer be notified
989 *
990 * @exception IllegalArgumentException <ul>
991 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
992 * </ul>
993 * @exception DWTException <ul>
994 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
995 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
996 * </ul>
997 *
998 * @see SelectionListener
999 * @see #addSelectionListener
1000 */
1001 public void removeSelectionListener (SelectionListener listener) {
1002 checkWidget();
1003 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
1004 if (eventTable is null) return;
1005 eventTable.unhook (DWT.Selection, listener);
1006 eventTable.unhook (DWT.DefaultSelection,listener);
1007 }
1008
1009 /**
1010 * Removes the listener from the collection of listeners who will
1011 * be notified when the control is verified.
1012 *
1013 * @param listener the listener which should no longer be notified
1014 *
1015 * @exception IllegalArgumentException <ul>
1016 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1017 * </ul>
1018 * @exception DWTException <ul>
1019 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1020 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1021 * </ul>
1022 *
1023 * @see VerifyListener
1024 * @see #addVerifyListener
1025 *
1026 * @since 3.1
1027 */
1028 public void removeVerifyListener (VerifyListener listener) {
1029 checkWidget();
1030 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT);
1031 if (eventTable is null) return;
1032 eventTable.unhook (DWT.Verify, listener);
1033 }
1034
1035 /**
1036 * Selects the item at the given zero-relative index in the receiver's
1037 * list. If the item at the index was already selected, it remains
1038 * selected. Indices that are out of range are ignored.
1039 *
1040 * @param index the index of the item to select
1041 *
1042 * @exception DWTException <ul>
1043 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1044 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1045 * </ul>
1046 */
1047 public void select (int index) {
1048 checkWidget ();
1049 int count = getItemCount ();
1050 if (0 <= index && index < count) {
1051 if ((style & DWT.READ_ONLY) !is 0) {
1052 ((NSPopUpButton)view).selectItemAtIndex(index);
1053 sendEvent (DWT.Modify);
1054 } else {
1055 ((NSComboBox)view).selectItemAtIndex(index);
1056 }
1057 }
1058 }
1059
1060 //bool sendKeyEvent (int type, Event event) {
1061 // if (!super.sendKeyEvent (type, event)) {
1062 // return false;
1063 // }
1064 // if (type !is DWT.KeyDown) return true;
1065 // if ((style & DWT.READ_ONLY) !is 0) return true;
1066 // if (event.character is 0) return true;
1067 // if ((event.stateMask & DWT.COMMAND) !is 0) return true;
1068 // String oldText = "", newText = "";
1069 // if (hooks (DWT.Verify) || filters (DWT.Verify)) {
1070 // int charCount = getCharCount ();
1071 // Point selection = getSelection ();
1072 // int start = selection.x, end = selection.y;
1073 // switch (event.character) {
1074 // case DWT.BS:
1075 // if (start is end) {
1076 // if (start is 0) return true;
1077 // start = Math.max (0, start - 1);
1078 // }
1079 // break;
1080 // case DWT.DEL:
1081 // if (start is end) {
1082 // if (start is charCount) return true;
1083 // end = Math.min (end + 1, charCount);
1084 // }
1085 // break;
1086 // case DWT.CR:
1087 // return true;
1088 // default:
1089 // if (event.character !is '\t' && event.character < 0x20) return true;
1090 // oldText = new String (new char [] {event.character});
1091 // }
1092 // newText = verifyText (oldText, start, end, event);
1093 // if (newText is null) return false;
1094 // if (charCount - (end - start) + newText.length () > textLimit) {
1095 // return false;
1096 // }
1097 // if (newText !is oldText) {
1098 // String text = getText ();
1099 // String leftText = text.substring (0, start);
1100 // String rightText = text.substring (end, text.length ());
1101 // setText (leftText + newText + rightText, false);
1102 // start += newText.length ();
1103 // setSelection (new Point (start, start));
1104 // }
1105 // }
1106 // /*
1107 // * Post the modify event so that the character will be inserted
1108 // * into the widget when the modify event is delivered. Normally,
1109 // * modify events are sent but it is safe to post the event here
1110 // * because this method is called from the event loop.
1111 // */
1112 // postEvent (DWT.Modify);
1113 // return newText is oldText;
1114 //}
1115
1116 void sendSelection () {
1117 postEvent(DWT.Selection);
1118 }
1119
1120 void setBackground (float [] color) {
1121 NSColor nsColor;
1122 if (color is null) {
1123 return; // TODO reset to OS default
1124 } else {
1125 nsColor = NSColor.colorWithDeviceRed(color[0], color[1], color[2], 1);
1126 }
1127 ((NSTextField)view).setBackgroundColor(nsColor);
1128 }
1129
1130 void setForeground (float [] color) {
1131 NSColor nsColor;
1132 if (color is null) {
1133 return; // TODO reset to OS default
1134 } else {
1135 nsColor = NSColor.colorWithDeviceRed(color[0], color[1], color[2], 1);
1136 }
1137 ((NSTextField)view).setTextColor(nsColor);
1138 }
1139
1140 /**
1141 * Sets the text of the item in the receiver's list at the given
1142 * zero-relative index to the string argument.
1143 *
1144 * @param index the index for the item
1145 * @param string the new text for the item
1146 *
1147 * @exception IllegalArgumentException <ul>
1148 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
1149 * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
1150 * </ul>
1151 * @exception DWTException <ul>
1152 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1153 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1154 * </ul>
1155 */
1156 public void setItem (int index, String string) {
1157 checkWidget ();
1158 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
1159 int count = getItemCount ();
1160 if (0 > index || index >= count) error (DWT.ERROR_INVALID_RANGE);
1161 NSString str = NSString.stringWith(string);
1162 if ((style & DWT.READ_ONLY) !is 0) {
1163 NSMenuItem nsItem = ((NSPopUpButton)view).itemAtIndex(index);
1164 nsItem.setTitle(str);
1165 } else {
1166 NSComboBox widget = (NSComboBox)view;
1167 widget.insertItemWithObjectValue(str, index);
1168 widget.removeItemAtIndex(index + 1);
1169 }
1170 }
1171
1172 /**
1173 * Sets the receiver's list to be the given array of items.
1174 *
1175 * @param items the array of items
1176 *
1177 * @exception IllegalArgumentException <ul>
1178 * <li>ERROR_NULL_ARGUMENT - if the items array is null</li>
1179 * <li>ERROR_INVALID_ARGUMENT - if an item in the items array is null</li>
1180 * </ul>
1181 * @exception DWTException <ul>
1182 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1183 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1184 * </ul>
1185 */
1186 public void setItems (String [] items) {
1187 checkWidget();
1188 if (items is null) error (DWT.ERROR_NULL_ARGUMENT);
1189 for (int i=0; i<items.length; i++) {
1190 if (items [i] is null) error (DWT.ERROR_INVALID_ARGUMENT);
1191 }
1192 removeAll();
1193 if (items.length is 0) return;
1194 for (int i= 0; i < items.length; i++) {
1195 NSString str = NSString.stringWith(items[i]);
1196 if ((style & DWT.READ_ONLY) !is 0) {
1197 NSMenu nsMenu = ((NSPopUpButton)view).menu();
1198 NSMenuItem nsItem = (NSMenuItem)new NSMenuItem().alloc();
1199 nsItem.initWithTitle(str, 0, NSString.stringWith(""));
1200 nsMenu.addItem(nsItem);
1201 nsItem.release();
1202 } else {
1203 ((NSComboBox)view).addItemWithObjectValue(str);
1204 }
1205 }
1206 }
1207
1208 /*public*/ void setListVisible (bool visible) {
1209 checkWidget ();
1210 if ((style & DWT.READ_ONLY) !is 0) {
1211 ((NSPopUpButton)view).setPullsDown(visible);
1212 } else {
1213 }
1214 }
1215
1216 /**
1217 * Sets the orientation of the receiver, which must be one
1218 * of the constants <code>DWT.LEFT_TO_RIGHT</code> or <code>DWT.RIGHT_TO_LEFT</code>.
1219 * <p>
1220 *
1221 * @param orientation new orientation style
1222 *
1223 * @exception DWTException <ul>
1224 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1225 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1226 * </ul>
1227 *
1228 * @since 2.1.2
1229 */
1230 public void setOrientation (int orientation) {
1231 checkWidget();
1232 }
1233
1234 /**
1235 * Sets the selection in the receiver's text field to the
1236 * range specified by the argument whose x coordinate is the
1237 * start of the selection and whose y coordinate is the end
1238 * of the selection.
1239 *
1240 * @param selection a point representing the new selection start and end
1241 *
1242 * @exception IllegalArgumentException <ul>
1243 * <li>ERROR_NULL_ARGUMENT - if the point is null</li>
1244 * </ul>
1245 * @exception DWTException <ul>
1246 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1247 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1248 * </ul>
1249 */
1250 public void setSelection (Point selection) {
1251 checkWidget ();
1252 if (selection is null) error (DWT.ERROR_NULL_ARGUMENT);
1253 if ((style & DWT.READ_ONLY) is 0) {
1254 // int length = getCharCount ();
1255 // int start = selection.x, end = selection.y;
1256 // ControlEditTextSelectionRec sel = new ControlEditTextSelectionRec ();
1257 // sel.selStart = (short) Math.min (Math.max (Math.min (start, end), 0), length);
1258 // sel.selEnd = (short) Math.min (Math.max (Math.max (start, end), 0), length);
1259 // if (hasFocus ()) {
1260 // OS.SetControlData (handle, OS.kHIComboBoxEditTextPart, OS.kControlEditTextSelectionTag, 4, sel);
1261 // } else {
1262 // this.selection = sel;
1263 // }
1264 }
1265 }
1266
1267 /**
1268 * Sets the contents of the receiver's text field to the
1269 * given string.
1270 * <p>
1271 * Note: The text field in a <code>Combo</code> is typically
1272 * only capable of displaying a single line of text. Thus,
1273 * setting the text to a string containing line breaks or
1274 * other special characters will probably cause it to
1275 * display incorrectly.
1276 * </p>
1277 *
1278 * @param string the new text
1279 *
1280 * @exception IllegalArgumentException <ul>
1281 * <li>ERROR_NULL_ARGUMENT - if the string is null</li>
1282 * </ul>
1283 * @exception DWTException <ul>
1284 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1285 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1286 * </ul>
1287 */
1288 public void setText (String string) {
1289 checkWidget ();
1290 if (string is null) error (DWT.ERROR_NULL_ARGUMENT);
1291 setText (string, true);
1292 }
1293
1294 void setText (String string, bool notify) {
1295 if (notify) {
1296 if (hooks (DWT.Verify) || filters (DWT.Verify)) {
1297 string = verifyText (string, 0, getCharCount (), null);
1298 if (string is null) return;
1299 }
1300 }
1301 if ((style & DWT.READ_ONLY) !is 0) {
1302 int index = indexOf (string);
1303 if (index !is -1 && index !is getSelectionIndex ()) {
1304 select (index);
1305 if (notify) sendEvent (DWT.Modify);
1306 }
1307 } else {
1308 new NSCell(((NSComboBox)view).cell()).setTitle(NSString.stringWith(string));
1309 if (notify) sendEvent (DWT.Modify);
1310 }
1311 }
1312
1313 /**
1314 * Sets the maximum number of characters that the receiver's
1315 * text field is capable of holding to be the argument.
1316 * <p>
1317 * To reset this value to the default, use <code>setTextLimit(Combo.LIMIT)</code>.
1318 * Specifying a limit value larger than <code>Combo.LIMIT</code> sets the
1319 * receiver's limit to <code>Combo.LIMIT</code>.
1320 * </p>
1321 * @param limit new text limit
1322 *
1323 * @exception IllegalArgumentException <ul>
1324 * <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>
1325 * </ul>
1326 * @exception DWTException <ul>
1327 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1328 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1329 * </ul>
1330 *
1331 * @see #LIMIT
1332 */
1333 public void setTextLimit (int limit) {
1334 checkWidget ();
1335 if (limit is 0) error (DWT.ERROR_CANNOT_BE_ZERO);
1336 textLimit = limit;
1337 }
1338
1339 /**
1340 * Sets the number of items that are visible in the drop
1341 * down portion of the receiver's list.
1342 * <p>
1343 * Note: This operation is a hint and is not supported on
1344 * platforms that do not have this concept.
1345 * </p>
1346 *
1347 * @param count the new number of items to be visible
1348 *
1349 * @exception DWTException <ul>
1350 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1351 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1352 * </ul>
1353 *
1354 * @since 3.0
1355 */
1356 public void setVisibleItemCount (int count) {
1357 checkWidget ();
1358 if (count < 0) return;
1359 if ((style & DWT.READ_ONLY) !is 0) {
1360 //TODO
1361 } else {
1362 ((NSComboBox)view).setNumberOfVisibleItems(count);
1363 }
1364 }
1365
1366 String verifyText (String string, int start, int end, Event keyEvent) {
1367 Event event = new Event ();
1368 event.text = string;
1369 event.start = start;
1370 event.end = end;
1371 if (keyEvent !is null) {
1372 event.character = keyEvent.character;
1373 event.keyCode = keyEvent.keyCode;
1374 event.stateMask = keyEvent.stateMask;
1375 }
1376 /*
1377 * It is possible (but unlikely), that application
1378 * code could have disposed the widget in the verify
1379 * event. If this happens, answer null to cancel
1380 * the operation.
1381 */
1382 sendEvent (DWT.Verify, event);
1383 if (!event.doit || isDisposed ()) return null;
1384 return event.text;
1385 }
1386
1387 }