Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/eclipse/swt/widgets/Combo.java


1   /*******************************************************************************
2    * Copyright (c) 2000, 2004 IBM Corporation and others.
3    * All rights reserved. This program and the accompanying materials
4    * are made available under the terms of the Common Public License v1.0
5    * which accompanies this distribution, and is available at
6    * http://www.eclipse.org/legal/cpl-v10.html
7    * 
8    * Contributors:
9    *     IBM Corporation - initial API and implementation
10   *******************************************************************************/
11  package org.eclipse.swt.widgets;
12  
13  
14  import org.eclipse.swt.*;
15  import org.eclipse.swt.internal.*;
16  import org.eclipse.swt.internal.gtk.*;
17  import org.eclipse.swt.graphics.*;
18  import org.eclipse.swt.events.*;
19  
20  /**
21   * Instances of this class are controls that allow the user
22   * to choose an item from a list of items, or optionally 
23   * enter a new value by typing it into an editable text
24   * field. Often, <code>Combo</code>s are used in the same place
25   * where a single selection <code>List</code> widget could
26   * be used but space is limited. A <code>Combo</code> takes
27   * less space than a <code>List</code> widget and shows
28   * similar information.
29   * <p>
30   * Note: Since <code>Combo</code>s can contain both a list
31   * and an editable text field, it is possible to confuse methods
32   * which access one versus the other (compare for example,
33   * <code>clearSelection()</code> and <code>deselectAll()</code>).
34   * The API documentation is careful to indicate either "the
35   * receiver's list" or the "the receiver's text field" to 
36   * distinguish between the two cases.
37   * </p><p>
38   * Note that although this class is a subclass of <code>Composite</code>,
39   * it does not make sense to add children to it, or set a layout on it.
40   * </p>
41   * <dl>
42   * <dt><b>Styles:</b></dt>
43   * <dd>DROP_DOWN, READ_ONLY, SIMPLE</dd>
44   * <dt><b>Events:</b></dt>
45   * <dd>DefaultSelection, Modify, Selection</dd>
46   * </dl>
47   * <p>
48   * Note: Only one of the styles DROP_DOWN and SIMPLE 
49   * may be specified.
50   * </p><p>
51   * IMPORTANT: This class is <em>not</em> intended to be subclassed.
52   * </p>
53   *
54   * @see List
55   */
56  public class Combo extends Composite {
57    long /*int*/ arrowHandle, entryHandle, listHandle;
58    int lastEventTime, visibleCount = 5;
59    String [] items = new String [0];
60    boolean ignoreSelect;
61  
62    static final int INNER_BORDER = 2;
63  
64    /**
65     * the operating system limit for the number of characters
66     * that the text field in an instance of this class can hold
67     */
68    public final static int LIMIT;
69    
70    /*
71    * These values can be different on different platforms.
72    * Therefore they are not initialized in the declaration
73    * to stop the compiler from inlining.
74    */
75    static {
76      LIMIT = 0xFFFF;
77    }
78  
79  /**
80   * Constructs a new instance of this class given its parent
81   * and a style value describing its behavior and appearance.
82   * <p>
83   * The style value is either one of the style constants defined in
84   * class <code>SWT</code> which is applicable to instances of this
85   * class, or must be built by <em>bitwise OR</em>'ing together 
86   * (that is, using the <code>int</code> "|" operator) two or more
87   * of those <code>SWT</code> style constants. The class description
88   * lists the style constants that are applicable to the class.
89   * Style bits are also inherited from superclasses.
90   * </p>
91   *
92   * @param parent a composite control which will be the parent of the new instance (cannot be null)
93   * @param style the style of control to construct
94   *
95   * @exception IllegalArgumentException <ul>
96   *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
97   * </ul>
98   * @exception SWTException <ul>
99   *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
100  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
101  * </ul>
102  *
103  * @see SWT#DROP_DOWN
104  * @see SWT#READ_ONLY
105  * @see SWT#SIMPLE
106  * @see Widget#checkSubclass
107  * @see Widget#getStyle
108  */
109 public Combo (Composite parent, int style) {
110   super (parent, checkStyle (style));
111 }
112 
113 /**
114  * Adds the argument to the end of the receiver's list.
115  *
116  * @param string the new item
117  *
118  * @exception IllegalArgumentException <ul>
119  *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
120  * </ul>
121  * @exception SWTException <ul>
122  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
123  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
124  * </ul>
125  * @exception SWTError <ul>
126  *    <li>ERROR_ITEM_NOT_ADDED - if the operation fails because of an operating system failure</li>
127  * </ul>
128  *
129  * @see #add(String,int)
130  */
131 public void add (String string) {
132   checkWidget();
133   if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
134   String [] newItems = new String [items.length + 1];
135   System.arraycopy (items, 0, newItems, 0, items.length);
136   newItems [items.length] = string;
137   setItems (newItems, true, true);
138 }
139 
140 /**
141  * Adds the argument to the receiver's list at the given
142  * zero-relative index.
143  * <p>
144  * Note: To add an item at the end of the list, use the
145  * result of calling <code>getItemCount()</code> as the
146  * index or use <code>add(String)</code>.
147  * </p>
148  *
149  * @param string the new item
150  * @param index the index for the item
151  *
152  * @exception IllegalArgumentException <ul>
153  *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
154  *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list (inclusive)</li>
155  * </ul>
156  * @exception SWTException <ul>
157  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
158  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
159  * </ul>
160  * @exception SWTError <ul>
161  *    <li>ERROR_ITEM_NOT_ADDED - if the operation fails because of an operating system failure</li>
162  * </ul>
163  *
164  * @see #add(String)
165  */
166 public void add (String string, int index) {
167   checkWidget();
168   if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
169   if (!(0 <= index && index <= items.length)) {
170     error (SWT.ERROR_INVALID_RANGE);
171   }
172   String [] newItems = new String [items.length + 1];
173   System.arraycopy (items, 0, newItems, 0, index);
174   newItems [index] = string;
175   System.arraycopy (items, index, newItems, index + 1, items.length - index);
176   setItems (newItems, true, true);
177 }
178 
179 /**
180  * Adds the listener to the collection of listeners who will
181  * be notified when the receiver's text is modified, by sending
182  * it one of the messages defined in the <code>ModifyListener</code>
183  * interface.
184  *
185  * @param listener the listener which should be notified
186  *
187  * @exception IllegalArgumentException <ul>
188  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
189  * </ul>
190  * @exception SWTException <ul>
191  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
192  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
193  * </ul>
194  *
195  * @see ModifyListener
196  * @see #removeModifyListener
197  */
198 public void addModifyListener (ModifyListener listener) {
199   checkWidget();
200   if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
201   TypedListener typedListener = new TypedListener (listener);
202   addListener (SWT.Modify, typedListener);
203 }
204 
205 /**
206  * Adds the listener to the collection of listeners who will
207  * be notified when the receiver's selection changes, by sending
208  * it one of the messages defined in the <code>SelectionListener</code>
209  * interface.
210  * <p>
211  * <code>widgetSelected</code> is called when the combo's list selection changes.
212  * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed the combo's text area.
213  * </p>
214  *
215  * @param listener the listener which should be notified
216  *
217  * @exception IllegalArgumentException <ul>
218  *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
219  * </ul>
220  * @exception SWTException <ul>
221  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
222  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
223  * </ul>
224  *
225  * @see SelectionListener
226  * @see #removeSelectionListener
227  * @see SelectionEvent
228  */
229 public void addSelectionListener(SelectionListener listener) {
230   checkWidget();
231   if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
232   TypedListener typedListener = new TypedListener (listener);
233   addListener (SWT.Selection,typedListener);
234   addListener (SWT.DefaultSelection,typedListener);
235 }
236 
237 static int checkStyle (int style) {
238   /*
239   * Feature in Windows.  It is not possible to create
240   * a combo box that has a border using Windows style
241   * bits.  All combo boxes draw their own border and
242   * do not use the standard Windows border styles.
243   * Therefore, no matter what style bits are specified,
244   * clear the BORDER bits so that the SWT style will
245   * match the Windows widget.
246   *
247   * The Windows behavior is currently implemented on
248   * all platforms.
249   */
250   style &= ~SWT.BORDER;
251   
252   /*
253   * Even though it is legal to create this widget
254   * with scroll bars, they serve no useful purpose
255   * because they do not automatically scroll the
256   * widget's client area.  The fix is to clear
257   * the SWT style.
258   */
259   style &= ~(SWT.H_SCROLL | SWT.V_SCROLL);
260   style = checkBits (style, SWT.DROP_DOWN, SWT.SIMPLE, 0, 0, 0, 0);
261   if ((style & SWT.SIMPLE) != 0) return style & ~SWT.READ_ONLY;
262   return style;
263 }
264 
265 /**
266  * Sets the selection in the receiver's text field to an empty
267  * selection starting just before the first character. If the
268  * text field is editable, this has the effect of placing the
269  * i-beam at the start of the text.
270  * <p>
271  * Note: To clear the selected items in the receiver's list, 
272  * use <code>deselectAll()</code>.
273  * </p>
274  *
275  * @exception SWTException <ul>
276  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
277  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
278  * </ul>
279  *
280  * @see #deselectAll
281  */
282 public void clearSelection () {
283   checkWidget();
284   int position = OS.gtk_editable_get_position (entryHandle);
285   OS.gtk_editable_select_region (entryHandle, position, position);
286 }
287 
288 public Point computeSize (int wHint, int hHint, boolean changed) {
289   checkWidget ();
290   if (wHint != SWT.DEFAULT && wHint < 0) wHint = 0;
291   if (hHint != SWT.DEFAULT && hHint < 0) hHint = 0;
292   int[] w = new int [1], h = new int [1];
293   long /*int*/ layout = OS.gtk_entry_get_layout (entryHandle);
294   OS.pango_layout_get_size (layout, w, h);
295   int xborder = INNER_BORDER, yborder = INNER_BORDER;
296   long /*int*/ style = OS.gtk_widget_get_style (entryHandle);
297   xborder += OS.gtk_style_get_xthickness (style);
298   yborder += OS.gtk_style_get_ythickness (style);
299   int [] property = new int [1];
300   OS.gtk_widget_style_get (entryHandle, OS.interior_focus, property, 0);
301   if (property [0] != 0) {
302     OS.gtk_widget_style_get (entryHandle, OS.focus_line_width, property, 0);
303     xborder += property [0];
304     yborder += property [0];
305   }
306   int width = OS.PANGO_PIXELS (w [0]) + xborder  * 2;
307   int height = OS.PANGO_PIXELS (h [0]) + yborder  * 2;
308 
309   GtkRequisition arrowRequesition = new GtkRequisition ();
310   OS.gtk_widget_size_request (arrowHandle, arrowRequesition);
311   GtkRequisition listRequesition = new GtkRequisition ();
312   long /*int*/ listParent = OS.gtk_widget_get_parent (listHandle);
313   OS.gtk_widget_size_request (listParent != 0 ? listParent : listHandle, listRequesition);
314   
315   width = Math.max (listRequesition.width, width) + arrowRequesition.width + 4;
316   width = wHint == SWT.DEFAULT ? width : wHint;
317   height = hHint == SWT.DEFAULT ? height : hHint;
318   return new Point (width, height);
319 }
320 
321 /**
322  * Copies the selected text.
323  * <p>
324  * The current selection is copied to the clipboard.
325  * </p>
326  *
327  * @exception SWTException <ul>
328  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
329  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
330  * </ul>
331  * 
332  * @since 2.1
333  */
334 public void copy () {
335   checkWidget ();
336   OS.gtk_editable_copy_clipboard (entryHandle);
337 }
338 
339 void createHandle (int index) {
340   state |= HANDLE | MENU;
341   fixedHandle = OS.gtk_fixed_new ();
342   if (fixedHandle == 0) error (SWT.ERROR_NO_HANDLES);
343   OS.gtk_fixed_set_has_window (fixedHandle, true);
344   handle = OS.gtk_combo_new ();
345   if (handle == 0) error (SWT.ERROR_NO_HANDLES);
346   long /*int*/ parentHandle = parent.parentingHandle ();
347   OS.gtk_container_add (parentHandle, fixedHandle);
348   OS.gtk_container_add (fixedHandle, handle);
349   OS.gtk_widget_show (fixedHandle);
350   OS.gtk_widget_show (handle);
351   GtkCombo combo = new GtkCombo ();
352   OS.memmove (combo, handle);
353   entryHandle = combo.entry;
354   listHandle = combo.list;
355   
356   /*
357   * Feature in GTK.  There is no API to query the arrow
358   * handle from a combo box although it is possible to
359   * get the list and text field.  The arrow handle is needed
360   * to hook events.  The fix is to find the first child that is
361   * not the entry or list and assume this is the arrow handle.
362   */
363   long /*int*/ list = OS.gtk_container_get_children (handle);
364   if (list != 0) {
365     int i = 0, count = OS.g_list_length (list);
366     while (i<count) {
367       long /*int*/ childHandle = OS.g_list_nth_data (list, i);
368       if (childHandle != entryHandle && childHandle != listHandle) {
369         arrowHandle = childHandle;
370         break;
371       }
372       i++;
373     }
374     OS.g_list_free (list);
375   }
376   
377   boolean editable = (style & SWT.READ_ONLY) == 0;
378   OS.gtk_editable_set_editable (entryHandle, editable);
379   OS.gtk_entry_set_activates_default (entryHandle, true);
380   OS.gtk_combo_disable_activate (handle);
381   OS.gtk_combo_set_case_sensitive (handle, true);
382 }
383 
384 /**
385  * Cuts the selected text.
386  * <p>
387  * The current selection is first copied to the
388  * clipboard and then deleted from the widget.
389  * </p>
390  *
391  * @exception SWTException <ul>
392  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
393  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
394  * </ul>
395  * 
396  * @since 2.1
397  */
398 public void cut () {
399   checkWidget ();
400   OS.gtk_editable_cut_clipboard (entryHandle);
401 }
402 
403 void deregister () {
404   super.deregister ();
405   if (arrowHandle != 0) display.removeWidget (arrowHandle);
406   display.removeWidget (entryHandle);
407   display.removeWidget (listHandle);
408   long /*int*/ imContext = imContext ();
409   if (imContext != 0) display.removeWidget (imContext);
410 }
411 
412 boolean filterKey (int keyval, long /*int*/ event) {
413   /*
414   * Bug in GTK.  On simplified Chinese, when the IM is open and the user
415   * presses a tab key, focus traversal occurs and the IM stops working.
416   * In order to process keys properly in SWT, if the same key event is
417   * dispatched twice, it is ignored.  If the tab key is not dispatched twice,
418   * the IM fails.  The fix is to dispatch it.
419   */
420   boolean isTab = keyval == OS.GDK_Tab || keyval == OS.GDK_ISO_Left_Tab;
421   int time = OS.gdk_event_get_time (event);
422   if (time != lastEventTime ||  isTab) {
423     lastEventTime = time;
424     long /*int*/ imContext = imContext ();
425     if (imContext != 0) {
426       return OS.gtk_im_context_filter_keypress (imContext, event);
427     }
428   }
429   return false;
430 }
431 
432 long /*int*/ fontHandle () {
433   if (entryHandle != 0) return entryHandle;
434   return super.fontHandle ();
435 }
436 
437 long /*int*/ focusHandle () {
438   if (entryHandle != 0) return entryHandle;
439   return super.focusHandle ();
440 }
441 
442 boolean hasFocus () {
443   if (super.hasFocus ()) return true;
444   if (OS.GTK_WIDGET_HAS_FOCUS (entryHandle)) return true;
445   if (OS.GTK_WIDGET_HAS_FOCUS (listHandle)) return true;
446   return false;
447 }
448 
449 void hookEvents () {
450   //TODO - fix multiple enter/exit
451   super.hookEvents ();
452   long /*int*/ windowProc2 = display.windowProc2;
453   long /*int*/ windowProc3 = display.windowProc3;
454   OS.g_signal_connect_after (entryHandle, OS.changed, windowProc2, CHANGED);
455   OS.g_signal_connect (entryHandle, OS.activate, windowProc2, ACTIVATE);
456   int eventMask =  OS.GDK_POINTER_MOTION_MASK | OS.GDK_BUTTON_PRESS_MASK |
457     OS.GDK_BUTTON_RELEASE_MASK | OS.GDK_ENTER_NOTIFY_MASK |
458     OS.GDK_LEAVE_NOTIFY_MASK;
459   long /*int*/ [] handles = new long /*int*/ [] {arrowHandle, entryHandle, listHandle};
460   for (int i=0; i<handles.length; i++) {
461     long /*int*/ eventHandle = handles [i];
462     if (eventHandle != 0) {
463       /* Connect the mouse signals */
464       OS.gtk_widget_add_events (eventHandle, eventMask);
465       OS.g_signal_connect (eventHandle, OS.button_press_event, windowProc3, BUTTON_PRESS_EVENT);
466       OS.g_signal_connect (eventHandle, OS.button_release_event, windowProc3, BUTTON_RELEASE_EVENT);
467       OS.g_signal_connect (eventHandle, OS.motion_notify_event, windowProc3, MOTION_NOTIFY_EVENT);
468       OS.g_signal_connect (eventHandle, OS.enter_notify_event, windowProc3, ENTER_NOTIFY_EVENT);
469       OS.g_signal_connect (eventHandle, OS.leave_notify_event, windowProc3, LEAVE_NOTIFY_EVENT);
470       /*
471       * Feature in GTK.  Events such as mouse move are propagated up
472       * the widget hierarchy and are seen by the parent.  This is the
473       * correct GTK behavior but not correct for SWT.  The fix is to
474       * hook a signal after and stop the propagation using a negative
475       * event number to distinguish this case.
476       */
477       OS.g_signal_connect_after (eventHandle, OS.button_press_event, windowProc3, -BUTTON_PRESS_EVENT);
478       OS.g_signal_connect_after (eventHandle, OS.button_release_event, windowProc3, -BUTTON_RELEASE_EVENT);
479       OS.g_signal_connect_after (eventHandle, OS.motion_notify_event, windowProc3, -MOTION_NOTIFY_EVENT);
480 
481       /* Connect the event_after signal for both key and mouse */
482       if (eventHandle != entryHandle) {
483         OS.g_signal_connect (eventHandle, OS.event_after, windowProc3, EVENT_AFTER);
484       }
485     }
486   }
487   long /*int*/ imContext = imContext ();
488   if (imContext != 0) {
489     OS.g_signal_connect (imContext, OS.commit, windowProc3, COMMIT);
490     int id = OS.g_signal_lookup (OS.commit, OS.gtk_im_context_get_type ());
491     int blockMask =  OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID;
492     OS.g_signal_handlers_block_matched (imContext, blockMask, id, 0, 0, 0, entryHandle);
493   }  
494 }
495 
496 long /*int*/ imContext () {
497   return OS.GTK_ENTRY_IM_CONTEXT (entryHandle);
498 }
499 
500 /**
501  * Deselects the item at the given zero-relative index in the receiver's 
502  * list.  If the item at the index was already deselected, it remains
503  * deselected. Indices that are out of range are ignored.
504  *
505  * @param index the index of the item to deselect
506  *
507  * @exception SWTException <ul>
508  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
509  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
510  * </ul>
511  */
512 public void deselect (int index) {
513   checkWidget();
514   boolean isSelected = getSelectionIndex () == index;
515   setItems (items, !isSelected, !isSelected);
516 }
517 
518 /**
519  * Deselects all selected items in the receiver's list.
520  * <p>
521  * Note: To clear the selection in the receiver's text field,
522  * use <code>clearSelection()</code>.
523  * </p>
524  *
525  * @exception SWTException <ul>
526  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
527  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
528  * </ul>
529  *
530  * @see #clearSelection
531  */
532 public void deselectAll () {
533   checkWidget();
534   setItems (items, false, false);
535 }
536 
537 GdkColor getBackgroundColor () {
538   return getBaseColor ();
539 }
540 
541 GdkColor getForegroundColor () {
542   return getTextColor ();
543 }
544 
545 /**
546  * Returns the item at the given, zero-relative index in the
547  * receiver's list. Throws an exception if the index is out
548  * of range.
549  *
550  * @param index the index of the item to return
551  * @return the item at the given index
552  *
553  * @exception IllegalArgumentException <ul>
554  *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
555  * </ul>
556  * @exception SWTException <ul>
557  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
558  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
559  * </ul>
560  * @exception SWTError <ul>
561  *    <li>ERROR_CANNOT_GET_ITEM - if the operation fails because of an operating system failure</li>
562  * </ul>
563  */
564 public String getItem (int index) {
565   checkWidget();
566   if (!(0 <= index && index < items.length)) {
567     error (SWT.ERROR_INVALID_RANGE);
568   }
569   return items [index];
570 }
571 
572 /**
573  * Returns the number of items contained in the receiver's list.
574  *
575  * @return the number of items
576  *
577  * @exception SWTException <ul>
578  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
579  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
580  * </ul>
581  * @exception SWTError <ul>
582  *    <li>ERROR_CANNOT_GET_COUNT - if the operation fails because of an operating system failure</li>
583  * </ul>
584  */
585 public int getItemCount () {
586   checkWidget();
587   return items.length;
588 }
589 
590 /**
591  * Returns the height of the area which would be used to
592  * display <em>one</em> of the items in the receiver's list.
593  *
594  * @return the height of one item
595  *
596  * @exception SWTException <ul>
597  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
598  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
599  * </ul>
600  * @exception SWTError <ul>
601  *    <li>ERROR_CANNOT_GET_ITEM_HEIGHT - if the operation fails because of an operating system failure</li>
602  * </ul>
603  */
604 public int getItemHeight () {
605   checkWidget();
606   return fontHeight (getFontDescription (), listHandle != 0 ? listHandle : handle);
607 }
608 
609 /**
610  * Returns an array of <code>String</code>s which are the items
611  * in the receiver's list. 
612  * <p>
613  * Note: This is not the actual structure used by the receiver
614  * to maintain its list of items, so modifying the array will
615  * not affect the receiver. 
616  * </p>
617  *
618  * @return the items in the receiver's list
619  *
620  * @exception SWTException <ul>
621  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
622  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
623  * </ul>
624  * @exception SWTError <ul>
625  *    <li>ERROR_CANNOT_GET_ITEM - if the operation fails because of an operating system failure</li>
626  * </ul>
627  */
628 public String [] getItems () {
629   checkWidget();
630   String [] result = new String [items.length];
631   System.arraycopy (items, 0, result, 0, items.length);
632   return result;
633 }
634 
635 /**
636  * Returns the orientation of the receiver.
637  *
638  * @return the orientation style
639  * 
640  * @exception SWTException <ul>
641  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
642  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
643  * </ul>
644  * 
645  * @since 2.1.2
646  */
647 public int getOrientation () {
648   checkWidget();
649   return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
650 }
651 
652 /**
653  * Returns a <code>Point</code> whose x coordinate is the start
654  * of the selection in the receiver's text field, and whose y
655  * coordinate is the end of the selection. The returned values
656  * are zero-relative. An "empty" selection as indicated by
657  * the the x and y coordinates having the same value.
658  *
659  * @return a point representing the selection start and end
660  *
661  * @exception SWTException <ul>
662  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
663  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
664  * </ul>
665  */
666 public Point getSelection () {
667   checkWidget ();
668   int [] start = new int [1];
669   int [] end = new int [1];
670   OS.gtk_editable_get_selection_bounds (entryHandle, start, end);
671   return new Point(start [0], end [0]);
672 }
673 
674 /**
675  * Returns the zero-relative index of the item which is currently
676  * selected in the receiver's list, or -1 if no item is selected.
677  *
678  * @return the index of the selected item
679  *
680  * @exception SWTException <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 int getSelectionIndex () {
686   checkWidget();
687   //NOT RIGHT FOR EDITABLE
688   return indexOf (getText ());
689 }
690 
691 /**
692  * Returns a string containing a copy of the contents of the
693  * receiver's text field.
694  *
695  * @return the receiver's text
696  *
697  * @exception SWTException <ul>
698  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
699  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
700  * </ul>
701  */
702 public String getText () {
703   checkWidget();
704   long /*int*/ address = OS.gtk_entry_get_text (entryHandle);
705   int length = OS.strlen (address);
706   byte [] buffer = new byte [length];
707   OS.memmove (buffer, address, length);
708   return new String (Converter.mbcsToWcs (null, buffer));
709 }
710 
711 String getText (int start, int stop) {
712   /*
713   * NOTE: The current implementation uses substring ()
714   * which can reference a potentially large character
715   * array.
716   */
717   return getText ().substring (start, stop - 1);
718 }
719 
720 /**
721  * Returns the height of the receivers's text field.
722  *
723  * @return the text height
724  *
725  * @exception SWTException <ul>
726  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
727  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
728  * </ul>
729  * @exception SWTError <ul>
730  *    <li>ERROR_CANNOT_GET_ITEM_HEIGHT - if the operation fails because of an operating system failure</li>
731  * </ul>
732  */
733 public int getTextHeight () {
734   checkWidget();
735   return fontHeight (getFontDescription (), entryHandle != 0 ? entryHandle : handle) + 8;
736 }
737 
738 /**
739  * Returns the maximum number of characters that the receiver's
740  * text field is capable of holding. If this has not been changed
741  * by <code>setTextLimit()</code>, it will be the constant
742  * <code>Combo.LIMIT</code>.
743  * 
744  * @return the text limit
745  * 
746  * @exception SWTException <ul>
747  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
748  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
749  * </ul>
750  */
751 public int getTextLimit () {
752   checkWidget();
753   int limit = OS.gtk_entry_get_max_length (entryHandle);
754   return limit == 0 ? LIMIT : limit;
755 }
756 
757 /**
758  * Gets the number of items that are visible in the drop
759  * down portion of the receiver's list.
760  *
761  * @return the number of items that are visible
762  *
763  * @exception SWTException <ul>
764  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
765  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
766  * </ul>
767  * 
768  * @since 3.0
769  */
770 public int getVisibleItemCount () {
771   checkWidget ();
772   return visibleCount;
773 }
774 
775 long /*int*/ gtk_activate (long /*int*/ widget) {
776   postEvent (SWT.DefaultSelection);
777   return 0;
778 }
779 
780 long /*int*/ gtk_changed (long /*int*/ widget) {
781   if (!ignoreSelect) {
782     long /*int*/ ptr = OS.gtk_entry_get_text (entryHandle);
783     int length = OS.strlen (ptr);
784     byte [] buffer = new byte [length];
785     OS.memmove (buffer, ptr, length);
786     String text = new String (Converter.mbcsToWcs (null, buffer));
787     for (int i = 0; i < items.length; i++) {
788       if (items [i].equals (text)) {
789         postEvent (SWT.Selection);
790         break;
791       }
792     }
793   }
794   sendEvent (SWT.Modify);
795   return 0;
796 }
797 
798 long /*int*/ gtk_commit (long /*int*/ imContext, long /*int*/ text) {
799   if (text == 0) return 0;
800   if (!OS.gtk_editable_get_editable (entryHandle)) return 0;
801   int length = OS.strlen (text);
802   if (length == 0) return 0;
803   byte [] buffer = new byte [length];
804   OS.memmove (buffer, text, length);
805   char [] chars = Converter.mbcsToWcs (null, buffer);
806   char [] newChars = sendIMKeyEvent (SWT.KeyDown, null, chars);
807   if (newChars == null) return 0;
808   OS.g_signal_handlers_block_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, COMMIT);
809   int id = OS.g_signal_lookup (OS.commit, OS.gtk_im_context_get_type ());
810   int mask =  OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID;
811   OS.g_signal_handlers_unblock_matched (imContext, mask, id, 0, 0, 0, entryHandle);
812   if (newChars == chars) {
813     OS.g_signal_emit_by_name (imContext, OS.commit, text);
814   } else {
815     buffer = Converter.wcsToMbcs (null, newChars, true);
816     OS.g_signal_emit_by_name (imContext, OS.commit, buffer);
817   }
818   OS.g_signal_handlers_unblock_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, COMMIT);
819   OS.g_signal_handlers_block_matched (imContext, mask, id, 0, 0, 0, entryHandle);
820   return 0;
821 }
822 
823 long /*int*/ gtk_popup_menu (long /*int*/ widget) {
824   int [] x = new int [1], y = new int [1];
825   OS.gdk_window_get_pointer (0, x, y, null);
826   return showMenu (x [0], y [0]) ? 1 : 0;
827 }
828 
829 /**
830  * Searches the receiver's list starting at the first item
831  * (index 0) until an item is found that is equal to the 
832  * argument, and returns the index of that item. If no item
833  * is found, returns -1.
834  *
835  * @param string the search item
836  * @return the index of the item
837  *
838  * @exception IllegalArgumentException <ul>
839  *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
840  * </ul>
841  * @exception SWTException <ul>
842  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
843  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
844  * </ul>
845  */
846 public int indexOf (String string) {
847   checkWidget();
848   return indexOf (string, 0);
849 }
850 
851 /**
852  * Searches the receiver's list starting at the given, 
853  * zero-relative index until an item is found that is equal
854  * to the argument, and returns the index of that item. If
855  * no item is found or the starting index is out of range,
856  * returns -1.
857  *
858  * @param string the search item
859  * @param start the zero-relative index at which to begin the search
860  * @return the index of the item
861  *
862  * @exception IllegalArgumentException <ul>
863  *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
864  * </ul>
865  * @exception SWTException <ul>
866  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
867  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
868  * </ul>
869  */
870 public int indexOf (String string, int start) {
871   checkWidget();
872   if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
873   if (!(0 <= start && start < items.length)) return -1;
874   for (int i=start; i<items.length; i++) {
875     if (string.equals(items [i])) return i;
876   }
877   return -1;
878 }
879 
880 /**
881  * Pastes text from clipboard.
882  * <p>
883  * The selected text is deleted from the widget
884  * and new text inserted from the clipboard.
885  * </p>
886  *
887  * @exception SWTException <ul>
888  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
889  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
890  * </ul>
891  * 
892  * @since 2.1
893  */
894 public void paste () {
895   checkWidget ();
896   OS.gtk_editable_paste_clipboard (entryHandle);
897 }
898 
899 long /*int*/ parentingHandle() {
900   return fixedHandle;
901 }
902 
903 void register () {
904   super.register ();
905   if (arrowHandle != 0) display.addWidget (arrowHandle, this);
906   display.addWidget (entryHandle, this);
907   display.addWidget (listHandle, this);
908   long /*int*/ imContext = imContext ();
909   if (imContext != 0) display.addWidget (imContext, this);
910 }
911 
912 void releaseHandle () {
913   super.releaseHandle ();
914   entryHandle = listHandle = 0;
915 }
916 
917 /**
918  * Removes the item from the receiver's list at the given
919  * zero-relative index.
920  *
921  * @param index the index for the item
922  *
923  * @exception IllegalArgumentException <ul>
924  *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
925  * </ul>
926  * @exception SWTException <ul>
927  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
928  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
929  * </ul>
930  * @exception SWTError <ul>
931  *    <li>ERROR_ITEM_NOT_REMOVED - if the operation fails because of an operating system failure</li>
932  * </ul>
933  */
934 public void remove (int index) {
935   checkWidget();
936   if (!(0 <= index && index < items.length)) {
937     error (SWT.ERROR_INVALID_RANGE);
938   }
939   String [] oldItems = items;
940   String [] newItems = new String [oldItems.length - 1];
941   System.arraycopy (oldItems, 0, newItems, 0, index);
942   System.arraycopy (oldItems, index + 1, newItems, index, oldItems.length - index - 1);
943   setItems (newItems, true, true);
944 }
945 
946 /**
947  * Removes the items from the receiver's list which are
948  * between the given zero-relative start and end 
949  * indices (inclusive).
950  *
951  * @param start the start of the range
952  * @param end the end of the range
953  *
954  * @exception IllegalArgumentException <ul>
955  *    <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>
956  * </ul>
957  * @exception SWTException <ul>
958  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
959  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
960  * </ul>
961  * @exception SWTError <ul>
962  *    <li>ERROR_ITEM_NOT_REMOVED - if the operation fails because of an operating system failure</li>
963  * </ul>
964  */
965 public void remove (int start, int end) {
966   checkWidget();
967   if (start > end) return;
968   if (!(0 <= start && start <= end && end < items.length)) {
969     error (SWT.ERROR_INVALID_RANGE);
970   }
971   String [] oldItems = items;
972   String [] newItems = new String [oldItems.length - (end - start + 1)];
973   System.arraycopy (oldItems, 0, newItems, 0, start);
974   System.arraycopy (oldItems, end + 1, newItems, start, oldItems.length - end - 1);
975   setItems (newItems, true, true);
976 }
977 
978 /**
979  * Searches the receiver's list starting at the first item
980  * until an item is found that is equal to the argument, 
981  * and removes that item from the list.
982  *
983  * @param string the item to remove
984  *
985  * @exception IllegalArgumentException <ul>
986  *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
987  *    <li>ERROR_INVALID_ARGUMENT - if the string is not found in the list</li>
988  * </ul>
989  * @exception SWTException <ul>
990  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
991  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
992  * </ul>
993  * @exception SWTError <ul>
994  *    <li>ERROR_ITEM_NOT_REMOVED - if the operation fails because of an operating system failure</li>
995  * </ul>
996  */
997 public void remove (String string) {
998   checkWidget();
999   int index = indexOf (string, 0);
1000  if (index == -1) error (SWT.ERROR_INVALID_ARGUMENT);
1001  remove (index);
1002}
1003
1004/**
1005 * Removes all of the items from the receiver's list.
1006 * <p>
1007 * @exception SWTException <ul>
1008 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1009 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1010 * </ul>
1011 */
1012public void removeAll () {
1013  checkWidget();
1014  setItems (new String [0], false, false);
1015}
1016
1017/**
1018 * Removes the listener from the collection of listeners who will
1019 * be notified when the receiver's text is modified.
1020 *
1021 * @param listener the listener which should no longer be notified
1022 *
1023 * @exception IllegalArgumentException <ul>
1024 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1025 * </ul>
1026 * @exception SWTException <ul>
1027 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1028 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1029 * </ul>
1030 *
1031 * @see ModifyListener
1032 * @see #addModifyListener
1033 */
1034public void removeModifyListener (ModifyListener listener) {
1035  checkWidget();
1036  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1037  if (eventTable == null) return;
1038  eventTable.unhook (SWT.Modify, listener);  
1039}
1040
1041/**
1042 * Removes the listener from the collection of listeners who will
1043 * be notified when the receiver's selection changes.
1044 *
1045 * @param listener the listener which should no longer be notified
1046 *
1047 * @exception IllegalArgumentException <ul>
1048 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1049 * </ul>
1050 * @exception SWTException <ul>
1051 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1052 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1053 * </ul>
1054 *
1055 * @see SelectionListener
1056 * @see #addSelectionListener
1057 */
1058public void removeSelectionListener (SelectionListener listener) {
1059  checkWidget();
1060  if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
1061  if (eventTable == null) return;
1062  eventTable.unhook (SWT.Selection, listener);
1063  eventTable.unhook (SWT.DefaultSelection,listener);  
1064}
1065
1066/**
1067 * Selects the item at the given zero-relative index in the receiver's 
1068 * list.  If the item at the index was already selected, it remains
1069 * selected. Indices that are out of range are ignored.
1070 *
1071 * @param index the index of the item to select
1072 *
1073 * @exception SWTException <ul>
1074 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1075 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1076 * </ul>
1077 */
1078public void select (int index) {
1079  checkWidget();
1080  if (index < 0 || index >= items.length) return;
1081  setText (items [index]);
1082}
1083
1084void setBackgroundColor (GdkColor color) {
1085  super.setBackgroundColor (color);
1086  if (entryHandle != 0) OS.gtk_widget_modify_base (entryHandle, 0, color);
1087  if (listHandle != 0) OS.gtk_widget_modify_base (listHandle, 0, color);
1088}
1089
1090boolean setBounds (int x, int y, int width, int height, boolean move, boolean resize) {
1091  int newHeight = (resize && (style & SWT.DROP_DOWN) != 0) ? getTextHeight () : height;
1092  return super.setBounds (x, y, width, newHeight, move, resize);
1093}
1094
1095void setFontDescription (long /*int*/ font) {
1096  super.setFontDescription (font);
1097  if (entryHandle != 0) OS.gtk_widget_modify_font (entryHandle, font);
1098  if (listHandle != 0) {
1099    OS.gtk_widget_modify_font (listHandle, font);
1100    long /*int*/ itemsList = OS.gtk_container_get_children (listHandle);
1101    if (itemsList != 0) {
1102      int count = OS.g_list_length (itemsList);
1103      for (int i=count - 1; i>=0; i--) {
1104        long /*int*/ widget = OS.gtk_bin_get_child (OS.g_list_nth_data (itemsList, i));
1105        OS.gtk_widget_modify_font (widget, font);
1106      }
1107      OS.g_list_free (itemsList);
1108    }
1109  }
1110}
1111
1112void setForegroundColor (GdkColor color) {
1113  super.setForegroundColor (color);
1114  if (entryHandle != 0) OS.gtk_widget_modify_text (entryHandle, 0, color);
1115  if (listHandle != 0) {
1116    OS.gtk_widget_modify_text (listHandle, 0, color);
1117    long /*int*/ itemsList = OS.gtk_container_get_children (listHandle);
1118    if (itemsList != 0) {
1119      int count = OS.g_list_length (itemsList);
1120      for (int i=count - 1; i>=0; i--) {
1121        long /*int*/ widget = OS.gtk_bin_get_child (OS.g_list_nth_data (itemsList, i));
1122        OS.gtk_widget_modify_fg (widget,  OS.GTK_STATE_NORMAL, color);
1123      }
1124      OS.g_list_free (itemsList);
1125    }
1126  }
1127}
1128
1129/**
1130 * Sets the text of the item in the receiver's list at the given
1131 * zero-relative index to the string argument. This is equivalent
1132 * to <code>remove</code>'ing the old item at the index, and then
1133 * <code>add</code>'ing the new item at that index.
1134 *
1135 * @param index the index for the item
1136 * @param string the new text for the item
1137 *
1138 * @exception IllegalArgumentException <ul>
1139 *    <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)</li>
1140 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
1141 * </ul>
1142 * @exception SWTException <ul>
1143 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1144 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1145 * </ul>
1146 * @exception SWTError <ul>
1147 *    <li>ERROR_ITEM_NOT_REMOVED - if the remove operation fails because of an operating system failure</li>
1148 *    <li>ERROR_ITEM_NOT_ADDED - if the add operation fails because of an operating system failure</li>
1149 * </ul>
1150 */
1151public void setItem (int index, String string) {
1152  checkWidget();
1153  if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1154  if (!(0 <= index && index < items.length)) {
1155    error (SWT.ERROR_INVALID_ARGUMENT);
1156  }
1157  items [index] = string;
1158  setItems (items, true, true);
1159}
1160
1161/**
1162 * Sets the receiver's list to be the given array of items.
1163 *
1164 * @param items the array of items
1165 *
1166 * @exception IllegalArgumentException <ul>
1167 *    <li>ERROR_NULL_ARGUMENT - if the items array is null</li>
1168 * </ul>
1169 * @exception SWTException <ul>
1170 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1171 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1172 * </ul>
1173 * @exception SWTError <ul>
1174 *    <li>ERROR_ITEM_NOT_ADDED - if the operation fails because of an operating system failure</li>
1175 * </ul>
1176 */
1177public void setItems (String [] items) {
1178  checkWidget();
1179  if (items == null) error (SWT.ERROR_NULL_ARGUMENT);
1180  setItems (items, false, false);
1181}
1182  
1183void setItems (String [] items, boolean keepText, boolean keepSelection) {
1184  this.items = items;
1185  String text = keepText ? getText() : "";
1186  int selectedIndex = keepSelection ? getSelectionIndex() : -1;
1187  ignoreSelect = true;
1188  if (items.length == 0) {
1189    long /*int*/ itemsList = OS.gtk_container_get_children (listHandle);
1190    if (itemsList != 0) {
1191      int count = OS.g_list_length (itemsList);
1192      for (int i=count - 1; i>=0; i--) {
1193        long /*int*/ widget = OS.g_list_nth_data (itemsList, i);
1194        OS.gtk_container_remove (listHandle, widget);
1195      }
1196      OS.g_list_free (itemsList);
1197    }
1198  } else {
1199    long /*int*/ glist = 0;
1200    for (int i=0; i<items.length; i++) {
1201      String string = items [i];
1202      if (string == null) break;
1203      byte [] buffer = Converter.wcsToMbcs (null, string, true);
1204      long /*int*/ data = OS.g_malloc (buffer.length);
1205      OS.memmove (data, buffer, buffer.length);
1206      glist = OS.g_list_append (glist, data);
1207    }
1208    OS.gtk_combo_set_popdown_strings (handle, glist);
1209    if (glist != 0) {
1210      int count = OS.g_list_length (glist);
1211      for (int i=0; i<count; i++) {
1212        long /*int*/ data = OS.g_list_nth_data (glist, i);
1213        if (data != 0) OS.g_free (data);
1214      }
1215      OS.g_list_free (glist);
1216    }
1217    long /*int*/ itemsList = OS.gtk_container_get_children (listHandle);
1218    if (itemsList != 0) {
1219      long /*int*/ font = getFontDescription ();
1220      GdkColor color = getForegroundColor ();
1221      int count = OS.g_list_length (itemsList);
1222      for (int i=count - 1; i>=0; i--) {
1223        long /*int*/ widget = OS.gtk_bin_get_child (OS.g_list_nth_data (itemsList, i));
1224        OS.gtk_widget_modify_fg (widget,  OS.GTK_STATE_NORMAL, color);
1225        OS.gtk_widget_modify_font (widget, font);
1226      }
1227      OS.g_list_free (itemsList);
1228    }
1229  }
1230  OS.gtk_entry_set_text (entryHandle, Converter.wcsToMbcs (null, selectedIndex != -1 ? items [selectedIndex] : text, true));
1231  ignoreSelect = false;
1232}
1233
1234/**
1235 * Sets the orientation of the receiver, which must be one
1236 * of the constants <code>SWT.LEFT_TO_RIGHT</code> or <code>SWT.RIGHT_TO_LEFT</code>.
1237 * <p>
1238 *
1239 * @param orientation new orientation style
1240 * 
1241 * @exception SWTException <ul>
1242 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1243 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1244 * </ul>
1245 * 
1246 * @since 2.1.2
1247 */
1248public void setOrientation (int orientation) {
1249  checkWidget();
1250}
1251
1252/**
1253 * Sets the selection in the receiver's text field to the
1254 * range specified by the argument whose x coordinate is the
1255 * start of the selection and whose y coordinate is the end
1256 * of the selection. 
1257 *
1258 * @param selection a point representing the new selection start and end
1259 *
1260 * @exception IllegalArgumentException <ul>
1261 *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
1262 * </ul>
1263 * @exception SWTException <ul>
1264 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1265 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1266 * </ul>
1267 */
1268public void setSelection (Point selection) {
1269  checkWidget();
1270  if (selection == null) error (SWT.ERROR_NULL_ARGUMENT);
1271  OS.gtk_editable_set_position (entryHandle, selection.x);
1272  OS.gtk_editable_select_region (entryHandle, selection.x, selection.y);
1273}
1274
1275/**
1276 * Sets the contents of the receiver's text field to the
1277 * given string.
1278 * <p>
1279 * Note: The text field in a <code>Combo</code> is typically
1280 * only capable of displaying a single line of text. Thus,
1281 * setting the text to a string containing line breaks or
1282 * other special characters will probably cause it to 
1283 * display incorrectly.
1284 * </p>
1285 *
1286 * @param string the new text
1287 *
1288 * @exception IllegalArgumentException <ul>
1289 *    <li>ERROR_NULL_ARGUMENT - if the string is null</li>
1290 * </ul>
1291 * @exception SWTException <ul>
1292 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1293 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1294 * </ul>
1295 */
1296public void setText (String string) {
1297  checkWidget();
1298  if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1299  byte [] buffer = Converter.wcsToMbcs (null, string, true);
1300  /*
1301  * Feature in gtk.  When text is set in gtk, separate events are fired for the deletion and 
1302  * insertion of the text.  This is not wrong, but is inconsistent with other platforms.  The
1303  * fix is to block the firing of these events and fire them ourselves in a consistent manner. 
1304  */
1305  OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
1306  OS.gtk_entry_set_text (entryHandle, buffer);
1307  OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
1308  sendEvent (SWT.Modify);
1309}
1310
1311/**
1312 * Sets the maximum number of characters that the receiver's
1313 * text field is capable of holding to be the argument.
1314 *
1315 * @param limit new text limit
1316 *
1317 * @exception IllegalArgumentException <ul>
1318 *    <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li>
1319 * </ul>
1320 * @exception SWTException <ul>
1321 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1322 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1323 * </ul>
1324 */
1325public void setTextLimit (int limit) {
1326  checkWidget();
1327  if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
1328  OS.gtk_entry_set_max_length (entryHandle, limit);
1329}
1330
1331/**
1332 * Sets the number of items that are visible in the drop
1333 * down portion of the receiver's list.
1334 *
1335 * @param count the new number of items to be visible
1336 *
1337 * @exception SWTException <ul>
1338 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1339 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1340 * </ul>
1341 * 
1342 * @since 3.0
1343 */
1344public void setVisibleItemCount (int count) {
1345  checkWidget ();
1346  if (count < 0) return;
1347  visibleCount = count;
1348}
1349
1350boolean translateTraversal (GdkEventKey keyEvent) {
1351  int key = keyEvent.keyval;
1352  switch (key) {
1353    case OS.GDK_KP_Enter:
1354    case OS.GDK_Return: {
1355      long /*int*/ imContext = imContext (); 
1356      if (imContext != 0) {
1357        long /*int*/ [] preeditString = new long /*int*/ [1];
1358        OS.gtk_im_context_get_preedit_string (imContext, preeditString, null, null);
1359        if (preeditString [0] != 0) {
1360          int lenght = OS.strlen (preeditString [0]);
1361          OS.g_free (preeditString [0]);
1362          if (lenght != 0) return false;
1363        }
1364      }
1365    }
1366  }
1367  return super.translateTraversal (keyEvent);
1368}
1369
1370}