View | Details | Raw Unified | Return to bug 230854 | Differences between
and this patch

Collapse All | Expand All

(-)Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java (+40 lines)
Lines 236-241 Link Here
236
	int /*long*/ allChildrenProc, allChildren;
236
	int /*long*/ allChildrenProc, allChildren;
237
	Callback allChildrenCallback;
237
	Callback allChildrenCallback;
238
238
239
	/* Segments callbacks */
240
	int /*long*/ segmentsProc2, segmentsProc4, segmentsProc5;
241
	Callback segmentsCallback2, segmentsCallback4, segmentsCallback5;
242
239
	/* Settings callbacks */
243
	/* Settings callbacks */
240
	int /*long*/ signalProc;
244
	int /*long*/ signalProc;
241
	Callback signalCallback;
245
	Callback signalCallback;
Lines 2520-2525 Link Here
2520
	closures [Widget.EXPAND_COLLAPSE_CURSOR_ROW] = OS.g_cclosure_new (windowProc5, Widget.EXPAND_COLLAPSE_CURSOR_ROW, 0);
2524
	closures [Widget.EXPAND_COLLAPSE_CURSOR_ROW] = OS.g_cclosure_new (windowProc5, Widget.EXPAND_COLLAPSE_CURSOR_ROW, 0);
2521
	closures [Widget.INSERT_TEXT] = OS.g_cclosure_new (windowProc5, Widget.INSERT_TEXT, 0);
2525
	closures [Widget.INSERT_TEXT] = OS.g_cclosure_new (windowProc5, Widget.INSERT_TEXT, 0);
2522
	closures [Widget.TEXT_BUFFER_INSERT_TEXT] = OS.g_cclosure_new (windowProc5, Widget.TEXT_BUFFER_INSERT_TEXT, 0);
2526
	closures [Widget.TEXT_BUFFER_INSERT_TEXT] = OS.g_cclosure_new (windowProc5, Widget.TEXT_BUFFER_INSERT_TEXT, 0);
2527
	//closures [Widget.MOVE_CURSOR] = OS.g_cclosure_new (windowProc5, Widget.MOVE_CURSOR, 0);
2523
2528
2524
	for (int i = 0; i < Widget.LAST_SIGNAL; i++) {
2529
	for (int i = 0; i < Widget.LAST_SIGNAL; i++) {
2525
		if (closures [i] != 0) OS.g_closure_ref (closures [i]);
2530
		if (closures [i] != 0) OS.g_closure_ref (closures [i]);
Lines 3291-3296 Link Here
3291
	caretCallback.dispose ();
3296
	caretCallback.dispose ();
3292
	caretCallback = null;
3297
	caretCallback = null;
3293
	
3298
	
3299
	/* Dispose the segments callbacks */
3300
	if (segmentsCallback2 != null) {
3301
		segmentsCallback2.dispose ();
3302
		segmentsCallback2 = null;
3303
		segmentsProc2 = 0;
3304
	}
3305
	if (segmentsCallback4 != null) {
3306
		segmentsCallback4.dispose ();
3307
		segmentsCallback4 = null;
3308
		segmentsProc4 = 0;
3309
	}
3310
	if (segmentsCallback2 != null) {
3311
		segmentsCallback5.dispose ();
3312
		segmentsCallback5 = null;
3313
		segmentsProc5 = 0;
3314
	}
3315
3294
	/* Release closures */
3316
	/* Release closures */
3295
	for (int i = 0; i < Widget.LAST_SIGNAL; i++) {
3317
	for (int i = 0; i < Widget.LAST_SIGNAL; i++) {
3296
		if (closures [i] != 0) OS.g_closure_unref (closures [i]);
3318
		if (closures [i] != 0) OS.g_closure_unref (closures [i]);
Lines 3651-3656 Link Here
3651
	return APP_VERSION;
3673
	return APP_VERSION;
3652
}
3674
}
3653
3675
3676
int /*long*/ segmentsProc2 (int /*long*/ handle, int /*long*/ user_data) {
3677
	Widget widget = getWidget (handle);
3678
	if (widget == null) return 0;
3679
	return widget.segmentsProc (handle, 0, 0, 0, user_data);
3680
}
3681
3682
int /*long*/ segmentsProc4 (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ user_data) {
3683
	Widget widget = getWidget (handle);
3684
	if (widget == null) return 0;
3685
	return widget.segmentsProc (handle, arg0, arg1, 0, user_data);
3686
}
3687
3688
int /*long*/ segmentsProc5 (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) {
3689
	Widget widget = getWidget (handle);
3690
	if (widget == null) return 0;
3691
	return widget.segmentsProc (handle, arg0, arg1, arg2, user_data);
3692
}
3693
3654
/**
3694
/**
3655
 * Sets the application name to the argument.
3695
 * Sets the application name to the argument.
3656
 * <p>
3696
 * <p>
(-)Eclipse SWT/gtk/org/eclipse/swt/widgets/Combo.java (-5 / +320 lines)
Lines 64-69 Link Here
64
	String [] items = new String [0];
64
	String [] items = new String [0];
65
	boolean ignoreSelect, lockText, selectionAdded;
65
	boolean ignoreSelect, lockText, selectionAdded;
66
	int indexSelected;
66
	int indexSelected;
67
68
	static final char LTR_MARK = '\u200e';
69
	static final char RTL_MARK = '\u200f';
70
71
	/* GTK signals data */
72
	static final int BACKSPACE = 1;
73
	static final int COPY_CLIPBOARD = 2;
74
	static final int CUT_CLIPBOARD = 3;
75
	static final int PASTE_CLIPBOARD = 4;
76
	static final int DELETE_FROM_CURSOR = 5;
77
	static final int MOVE_CURSOR = 6;
78
	static final int CONNECTED_AFTER = 8;
79
80
	int[] segments;
81
67
	/**
82
	/**
68
	 * the operating system limit for the number of characters
83
	 * the operating system limit for the number of characters
69
	 * that the text field in an instance of this class can hold
84
	 * that the text field in an instance of this class can hold
Lines 168-173 Link Here
168
	newItems [index] = string;
183
	newItems [index] = string;
169
	System.arraycopy (items, index, newItems, index + 1, items.length - index);
184
	System.arraycopy (items, index, newItems, index + 1, items.length - index);
170
	items = newItems;
185
	items = newItems;
186
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
187
		string = getSegmentsText (string);
188
	}
171
	byte [] buffer = Converter.wcsToMbcs (null, string, true);
189
	byte [] buffer = Converter.wcsToMbcs (null, string, true);
172
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
190
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
173
		OS.gtk_combo_box_insert_text (handle, index, buffer);
191
		OS.gtk_combo_box_insert_text (handle, index, buffer);
Lines 220-225 Link Here
220
	addListener (SWT.Modify, typedListener);
238
	addListener (SWT.Modify, typedListener);
221
}
239
}
222
240
241
public void addSegmentListener (SegmentListener listener) {
242
	checkWidget ();
243
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
244
	if (segments != null) clearSegments (true);
245
	addListener (SWT.GetSegments, new TypedListener (listener));
246
	applySegments ();
247
	for (int i = items.length; i-- > 0;) {
248
		setItem (i, items [i]);
249
	}
250
	if (OS.g_signal_handler_find (entryHandle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc2, 0) == 0) { 
251
		/* 
252
		* NOTE: We do not instantiate the segments callbacks unless they are
253
		* really needed. 
254
		*/
255
		if (display.segmentsCallback2 == null) {
256
			display.segmentsCallback2 = new Callback (display, "segmentsProc2", 2); //$NON-NLS-1$
257
			display.segmentsProc2 = display.segmentsCallback2.getAddress ();
258
			if (display.segmentsProc2 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
259
			display.segmentsCallback4 = new Callback (display, "segmentsProc4", 4); //$NON-NLS-1$
260
			display.segmentsProc4 = display.segmentsCallback4.getAddress ();
261
			if (display.segmentsProc4 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
262
			display.segmentsCallback5 = new Callback (display, "segmentsProc5", 5); //$NON-NLS-1$
263
			display.segmentsProc5 = display.segmentsCallback5.getAddress ();
264
			if (display.segmentsProc5 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
265
		}
266
		OS.g_signal_connect (entryHandle, OS.backspace, display.segmentsProc2, BACKSPACE);
267
		OS.g_signal_connect (entryHandle, OS.copy_clipboard, display.segmentsProc2, COPY_CLIPBOARD);
268
		OS.g_signal_connect (entryHandle, OS.cut_clipboard, display.segmentsProc2, CUT_CLIPBOARD);
269
		OS.g_signal_connect (entryHandle, OS.paste_clipboard, display.segmentsProc2, PASTE_CLIPBOARD);
270
		OS.g_signal_connect (entryHandle, OS.delete_from_cursor, display.segmentsProc4, DELETE_FROM_CURSOR);
271
		OS.g_signal_connect (entryHandle, OS.move_cursor, display.segmentsProc5, MOVE_CURSOR);
272
		OS.g_signal_connect_after (entryHandle, OS.backspace, display.segmentsProc2, BACKSPACE | CONNECTED_AFTER);
273
		OS.g_signal_connect_after (entryHandle, OS.copy_clipboard, display.segmentsProc2, COPY_CLIPBOARD | CONNECTED_AFTER);
274
		OS.g_signal_connect_after (entryHandle, OS.cut_clipboard, display.segmentsProc2, CUT_CLIPBOARD | CONNECTED_AFTER);
275
		OS.g_signal_connect_after (entryHandle, OS.paste_clipboard, display.segmentsProc2, PASTE_CLIPBOARD | CONNECTED_AFTER);
276
		OS.g_signal_connect_after (entryHandle, OS.delete_from_cursor, display.segmentsProc4, DELETE_FROM_CURSOR | CONNECTED_AFTER);
277
		OS.g_signal_connect_after (entryHandle, OS.move_cursor, display.segmentsProc5, MOVE_CURSOR | CONNECTED_AFTER);
278
	}
279
}
280
223
/**
281
/**
224
 * Adds the listener to the collection of listeners who will
282
 * Adds the listener to the collection of listeners who will
225
 * be notified when the user changes the receiver's selection, by sending
283
 * be notified when the user changes the receiver's selection, by sending
Lines 312-317 Link Here
312
	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
370
	if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS);
313
}
371
}
314
372
373
void applySegments () {
374
	if (entryHandle == 0 || !hooks (SWT.GetSegments) && !filters (SWT.GetSegments)) {
375
		return;
376
	}
377
	if (segments != null) clearSegments (true);
378
	String string = getText ();
379
	Event event = getSegments (string);
380
	if (event == null) return;
381
	segments = event.segments;
382
	if (segments == null) return;
383
	int nSegments = segments.length;
384
	if (nSegments == 0) return;
385
386
	for (int i = 1, lineLength = string == null ? 0 : string.length (); i < nSegments; i++) {
387
		if (event.segments [i] < event.segments [i - 1] || event.segments [i] > lineLength) {
388
			SWT.error (SWT.ERROR_INVALID_ARGUMENT);
389
		}
390
	}
391
	char[] segmentsChars = event.segmentsChars;
392
	char [] separator = { getOrientation () == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK };
393
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
394
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
395
	int limit = OS.gtk_entry_get_max_length (entryHandle);
396
	if (limit != 0) OS.gtk_entry_set_max_length (entryHandle, limit + nSegments);
397
	int [] pos = new int [1];
398
	for (int i = 0; i < nSegments; i++) {
399
		pos [0] = segments [i] + i;
400
		if (segmentsChars != null && segmentsChars.length > i) {
401
			separator [0] = segmentsChars [i];
402
		}
403
		byte [] buffer = Converter.wcsToMbcs (null, separator, false);
404
		OS.gtk_editable_insert_text (entryHandle, buffer, buffer.length, pos);
405
	}
406
	OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
407
	OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
408
}
409
315
/**
410
/**
316
 * Sets the selection in the receiver's text field to an empty
411
 * Sets the selection in the receiver's text field to an empty
317
 * selection starting just before the first character. If the
412
 * selection starting just before the first character. If the
Lines 336-341 Link Here
336
		OS.gtk_editable_select_region (entryHandle, position, position);
431
		OS.gtk_editable_select_region (entryHandle, position, position);
337
	}
432
	}
338
}
433
}
434
void clearSegments (boolean applyValue) {
435
	if (segments == null || entryHandle == 0) return;
436
	int nSegments = segments.length;
437
	if (nSegments == 0) return;
438
439
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
440
	if (applyValue) {
441
		OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
442
		for (int i = 0; i < nSegments; i++) {
443
			OS.gtk_editable_delete_text (entryHandle, segments[i], segments[i] + 1);
444
		}
445
		OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
446
	}
447
	int limit = OS.gtk_entry_get_max_length (entryHandle);
448
	if (limit != 0) OS.gtk_entry_set_max_length (entryHandle, limit - nSegments);
449
	OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
450
	segments = null;
451
}
339
452
340
void clearText () {
453
void clearText () {
341
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
454
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
Lines 357-362 Link Here
357
		}
470
		}
358
		OS.gtk_combo_box_set_active (handle, -1);
471
		OS.gtk_combo_box_set_active (handle, -1);
359
 		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
472
 		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
473
		if (segments != null) clearSegments (false);
360
	}
474
	}
361
}
475
}
362
476
Lines 546-551 Link Here
546
	if (entryHandle != 0) OS.gtk_editable_cut_clipboard (entryHandle);
660
	if (entryHandle != 0) OS.gtk_editable_cut_clipboard (entryHandle);
547
}
661
}
548
662
663
char [] deprocessText (char [] text, int start) {
664
	if (text == null || segments == null) return text;
665
	int length = text.length;
666
	if (length == 0) return text;
667
	int nSegments = segments.length;
668
	if (nSegments == 0) return text;
669
	if (start > segments [nSegments - 1] || start + length <= segments [0]) return text;
670
	char[] newText = new char [length];
671
	int nLeadSegments = 0;
672
	while (start - nLeadSegments > segments [nLeadSegments]) nLeadSegments++;
673
	int segmentCount = nLeadSegments;
674
	for (int i = 0; i < length; i++) {
675
		if (segmentCount < nSegments && i + start - segmentCount == segments [segmentCount]) {
676
			++segmentCount;
677
		} else {
678
			newText [i - segmentCount + nLeadSegments] = text [i];
679
		}
680
	}
681
	segmentCount -= nLeadSegments;
682
	if (segmentCount > 0) {
683
		char [] newChars = new char [length - segmentCount];
684
		System.arraycopy(newText, 0, newChars, 0, length - segmentCount);
685
		return newChars;
686
	}
687
	return newText;
688
}
689
549
void deregister () {
690
void deregister () {
550
	super.deregister ();
691
	super.deregister ();
551
	if (buttonHandle != 0) display.removeWidget (buttonHandle);
692
	if (buttonHandle != 0) display.removeWidget (buttonHandle);
Lines 776-781 Link Here
776
		if (selected) {
917
		if (selected) {
777
			OS.gtk_list_unselect_all (listHandle);
918
			OS.gtk_list_unselect_all (listHandle);
778
			OS.gtk_entry_set_text (entryHandle, new byte[1]);
919
			OS.gtk_entry_set_text (entryHandle, new byte[1]);
920
			if (segments != null) clearSegments (false);
779
		}
921
		}
780
		OS.g_list_free (children);
922
		OS.g_list_free (children);
781
		ignoreSelect = false;
923
		ignoreSelect = false;
Lines 805-810 Link Here
805
		OS.gtk_list_unselect_all (listHandle);
947
		OS.gtk_list_unselect_all (listHandle);
806
		OS.gtk_entry_set_text (entryHandle, new byte[1]);
948
		OS.gtk_entry_set_text (entryHandle, new byte[1]);
807
		ignoreSelect = false;
949
		ignoreSelect = false;
950
		if (segments != null) clearSegments (false);
808
	}
951
	}
809
}
952
}
810
953
Lines 969-974 Link Here
969
	return super.getOrientation ();
1112
	return super.getOrientation ();
970
}
1113
}
971
1114
1115
Event getSegments (String string) {
1116
	if (string == null || !hooks (SWT.GetSegments) && !filters (SWT.GetSegments)) {
1117
		return null;
1118
	}
1119
	Event event = new Event ();
1120
	event.text = string;
1121
	event.segments = segments;
1122
	sendEvent (SWT.GetSegments, event);
1123
	return event;
1124
}
1125
1126
String getSegmentsText (String string) {
1127
	Event event = getSegments (string);
1128
	if (event == null) return string;
1129
	int [] segments = event.segments;
1130
	if (segments == null) return string;
1131
	int nSegments = segments.length;
1132
	if (nSegments == 0) return string;
1133
	char [] segmentsChars = event.segmentsChars;
1134
	int length = string.length ();
1135
	char [] oldChars = new char [length];
1136
	string.getChars (0, length, oldChars, 0);
1137
	char [] newChars = new char [length + nSegments];
1138
	int charCount = 0, segmentCount = 0;
1139
	char defaultSeparator = getOrientation () == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK;
1140
	while (charCount < length) {
1141
		if (segmentCount < nSegments && charCount == segments [segmentCount]) {
1142
			char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars [segmentCount] : defaultSeparator;
1143
			newChars [charCount + segmentCount++] = separator;
1144
		} else {
1145
			newChars [charCount + segmentCount] = oldChars [charCount++];
1146
		}
1147
	}
1148
	while (segmentCount < nSegments) {
1149
		segments[segmentCount] = charCount;
1150
		char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars [segmentCount] : defaultSeparator;
1151
		newChars [charCount + segmentCount++] = separator;
1152
	}
1153
	return new String (newChars, 0, newChars.length);
1154
}
1155
972
/**
1156
/**
973
 * Returns a <code>Point</code> whose x coordinate is the
1157
 * Returns a <code>Point</code> whose x coordinate is the
974
 * character position representing the start of the selection
1158
 * character position representing the start of the selection
Lines 997-1003 Link Here
997
			if (index != -1) length = getItem (index).length ();
1181
			if (index != -1) length = getItem (index).length ();
998
		} else {
1182
		} else {
999
			int /*long*/ str = OS.gtk_entry_get_text (entryHandle);
1183
			int /*long*/ str = OS.gtk_entry_get_text (entryHandle);
1000
			if (str != 0) length = (int)/*64*/OS.g_utf8_strlen (str, -1);
1184
			if (str != 0) {
1185
				length = (int)/*64*/OS.g_utf8_strlen (str, -1);
1186
				if (segments != null) length -= segments.length;
1187
			}
1001
		}
1188
		}
1002
		return new Point (0, length);
1189
		return new Point (0, length);
1003
	}
1190
	}
Lines 1005-1010 Link Here
1005
	int [] end = new int [1];
1192
	int [] end = new int [1];
1006
	if (entryHandle != 0) {
1193
	if (entryHandle != 0) {
1007
		OS.gtk_editable_get_selection_bounds (entryHandle, start, end);
1194
		OS.gtk_editable_get_selection_bounds (entryHandle, start, end);
1195
		if (segments != null) {
1196
			start [0] = untranslateOffset (start [0]);
1197
			end [0] = untranslateOffset (end [0]);
1198
		}
1008
	}
1199
	}
1009
	return new Point(start [0], end [0]);
1200
	return new Point(start [0], end [0]);
1010
}
1201
}
Lines 1061-1066 Link Here
1061
		int length = OS.strlen (str);
1252
		int length = OS.strlen (str);
1062
		byte [] buffer = new byte [length];
1253
		byte [] buffer = new byte [length];
1063
		OS.memmove (buffer, str, length);
1254
		OS.memmove (buffer, str, length);
1255
		if (segments != null) {
1256
			return new String (deprocessText (Converter.mbcsToWcs (null, buffer), 0));
1257
		}
1064
		return new String (Converter.mbcsToWcs (null, buffer));
1258
		return new String (Converter.mbcsToWcs (null, buffer));
1065
	} else {
1259
	} else {
1066
		int index = OS.gtk_combo_box_get_active (handle);		  
1260
		int index = OS.gtk_combo_box_get_active (handle);		  
Lines 1112-1118 Link Here
1112
public int getTextLimit () {
1306
public int getTextLimit () {
1113
	checkWidget();
1307
	checkWidget();
1114
	int limit = entryHandle != 0 ? OS.gtk_entry_get_max_length (entryHandle) : 0;
1308
	int limit = entryHandle != 0 ? OS.gtk_entry_get_max_length (entryHandle) : 0;
1115
	return limit == 0 ? LIMIT : limit;
1309
	return limit == 0 ? LIMIT : segments != null ? limit - segments.length : limit;
1116
}
1310
}
1117
1311
1118
/**
1312
/**
Lines 1405-1411 Link Here
1405
}
1599
}
1406
1600
1407
int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
1601
int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
1602
	GdkEventKey keyEvent = null;
1603
	boolean handleSegments = false, segmentsCleared = false;
1604
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
1605
		keyEvent = new GdkEventKey ();
1606
		OS.memmove (keyEvent, event, GdkEventKey.sizeof);
1607
		if (keyEvent.length > 0 && (keyEvent.state & (OS.GDK_MOD1_MASK | OS.GDK_CONTROL_MASK)) == 0) {
1608
			handleSegments = true;
1609
			if (segments != null) {
1610
				clearSegments (true);
1611
				segmentsCleared = true;
1612
			}
1613
		}
1614
	}
1408
	int /*long*/ result = super.gtk_key_press_event (widget, event);
1615
	int /*long*/ result = super.gtk_key_press_event (widget, event);
1616
	if (handleSegments && (result != 0 || gdkEventKey == -1 || segmentsCleared)) {
1617
		applySegments ();
1618
	}
1409
	if (result != 0) {
1619
	if (result != 0) {
1410
	    gdkEventKey = 0;
1620
	    gdkEventKey = 0;
1411
	    fixIM ();
1621
	    fixIM ();
Lines 1414-1421 Link Here
1414
	if (gdkEventKey == -1) result = 1;
1624
	if (gdkEventKey == -1) result = 1;
1415
	gdkEventKey = 0;
1625
	gdkEventKey = 0;
1416
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0) && (style & SWT.READ_ONLY) == 0) {
1626
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0) && (style & SWT.READ_ONLY) == 0) {
1417
		GdkEventKey keyEvent = new GdkEventKey ();
1627
		if (keyEvent == null) {
1418
		OS.memmove (keyEvent, event, GdkEventKey.sizeof);
1628
			keyEvent = new GdkEventKey ();
1629
			OS.memmove (keyEvent, event, GdkEventKey.sizeof);
1630
		}
1419
		int oldIndex = OS.gtk_combo_box_get_active (handle);
1631
		int oldIndex = OS.gtk_combo_box_get_active (handle);
1420
		int newIndex = oldIndex;
1632
		int newIndex = oldIndex;
1421
		int key = keyEvent.keyval;
1633
		int key = keyEvent.keyval;
Lines 1465-1470 Link Here
1465
1677
1466
int /*long*/ gtk_selection_done(int /*long*/ menushell) {
1678
int /*long*/ gtk_selection_done(int /*long*/ menushell) {
1467
	int index = OS.gtk_combo_box_get_active (handle);
1679
	int index = OS.gtk_combo_box_get_active (handle);
1680
	if (index != -1 && (hooks (SWT.GetSegments) || filters (SWT.GetSegments))) {
1681
		int nSegments = segments == null ? 0 : segments.length;
1682
		int delta = 0;
1683
		Event event = getSegments (items [index]);
1684
		if (event != null) {
1685
			segments = event.segments;
1686
			delta = segments == null ? nSegments : nSegments - segments.length;
1687
			if (delta != 0) {
1688
				int limit = OS.gtk_entry_get_max_length (entryHandle);
1689
				if (limit != 0) {
1690
					OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
1691
					OS.gtk_entry_set_max_length (entryHandle, limit - delta);
1692
					OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
1693
				}
1694
			}
1695
		}
1696
	}
1468
	if (indexSelected == -1){
1697
	if (indexSelected == -1){
1469
		indexSelected = index;
1698
		indexSelected = index;
1470
	}
1699
	}
Lines 1628-1633 Link Here
1628
		OS.g_list_free (children);
1857
		OS.g_list_free (children);
1629
		if (selected) {
1858
		if (selected) {
1630
			OS.gtk_entry_set_text (entryHandle, new byte[1]);
1859
			OS.gtk_entry_set_text (entryHandle, new byte[1]);
1860
			if (segments != null) clearSegments (false);
1631
		}
1861
		}
1632
		ignoreSelect = false;
1862
		ignoreSelect = false;
1633
	}
1863
	}
Lines 1681-1686 Link Here
1681
		OS.g_list_free (children);
1911
		OS.g_list_free (children);
1682
		if (selected) {
1912
		if (selected) {
1683
			OS.gtk_entry_set_text (entryHandle, new byte[1]);
1913
			OS.gtk_entry_set_text (entryHandle, new byte[1]);
1914
			if (segments != null) clearSegments (false);
1684
		}
1915
		}
1685
		ignoreSelect = false;
1916
		ignoreSelect = false;
1686
	}
1917
	}
Lines 1733-1738 Link Here
1733
		OS.gtk_list_clear_items (listHandle, 0, -1);
1964
		OS.gtk_list_clear_items (listHandle, 0, -1);
1734
		OS.gtk_entry_set_text (entryHandle, new byte[1]);
1965
		OS.gtk_entry_set_text (entryHandle, new byte[1]);
1735
		ignoreSelect = false;
1966
		ignoreSelect = false;
1967
		if (segments != null) clearSegments (false);
1736
	}
1968
	}
1737
}
1969
}
1738
1970
Lines 1760-1765 Link Here
1760
	eventTable.unhook (SWT.Modify, listener);	
1992
	eventTable.unhook (SWT.Modify, listener);	
1761
}
1993
}
1762
1994
1995
public void removeSegmentListener (SegmentListener listener) {
1996
	checkWidget ();
1997
	if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
1998
	clearSegments (true);
1999
	//setItems (items);
2000
	eventTable.unhook (SWT.GetSegments, listener);
2001
	if (entryHandle != 0 && getListeners (SWT.GetSegments).length == 0) {
2002
		OS.g_signal_handlers_disconnect_matched (entryHandle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc2, 0);
2003
		OS.g_signal_handlers_disconnect_matched (entryHandle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc4, 0);
2004
		OS.g_signal_handlers_disconnect_matched (entryHandle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc5, 0);
2005
	} else {
2006
		applySegments ();
2007
	}
2008
	for (int i = items.length; i-- > 0;) {
2009
		setItem (i, items [i]);
2010
	}
2011
}
2012
1763
/**
2013
/**
1764
 * Removes the listener from the collection of listeners who will
2014
 * Removes the listener from the collection of listeners who will
1765
 * be notified when the user changes the receiver's selection.
2015
 * be notified when the user changes the receiver's selection.
Lines 1811-1816 Link Here
1811
	eventTable.unhook (SWT.Verify, listener);	
2061
	eventTable.unhook (SWT.Verify, listener);	
1812
}
2062
}
1813
2063
2064
int /*long*/ segmentsProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) {
2065
	switch (user_data & ~CONNECTED_AFTER) {
2066
		case MOVE_CURSOR:
2067
			if (arg0 != 1 /*GtkMovementStep#GTK_MOVEMENT_VISUAL_POSITIONS*/) break;
2068
		default:
2069
			if ((user_data & CONNECTED_AFTER) != 0) applySegments ();
2070
			else if (segments != null) clearSegments (true);
2071
	}
2072
	return 0;
2073
}
2074
1814
/**
2075
/**
1815
 * Selects the item at the given zero-relative index in the receiver's 
2076
 * Selects the item at the given zero-relative index in the receiver's 
1816
 * list.  If the item at the index was already selected, it remains
2077
 * list.  If the item at the index was already selected, it remains
Lines 1843-1848 Link Here
1843
		OS.gtk_list_select_item (listHandle, index);
2104
		OS.gtk_list_select_item (listHandle, index);
1844
		ignoreSelect = false;
2105
		ignoreSelect = false;
1845
	}
2106
	}
2107
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2108
		int nSegments = segments == null ? 0 : segments.length;
2109
		int delta = 0;
2110
		Event event = getSegments (items [index]);
2111
		if (event != null) {
2112
			segments = event.segments;
2113
			delta = segments == null ? nSegments : nSegments - segments.length;
2114
			if (delta != 0) {
2115
				int limit = OS.gtk_entry_get_max_length (entryHandle);
2116
				if (limit != 0) {
2117
					OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2118
					OS.gtk_entry_set_max_length (entryHandle, limit - delta);
2119
					OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2120
				}
2121
			}
2122
		}
2123
	}
1846
}
2124
}
1847
2125
1848
void setBackgroundColor (GdkColor color) {
2126
void setBackgroundColor (GdkColor color) {
Lines 1942-1947 Link Here
1942
		error (SWT.ERROR_INVALID_ARGUMENT);
2220
		error (SWT.ERROR_INVALID_ARGUMENT);
1943
	}
2221
	}
1944
	items [index] = string;
2222
	items [index] = string;
2223
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2224
		string = getSegmentsText (string);
2225
	}
1945
	byte [] buffer = Converter.wcsToMbcs (null, string, true);
2226
	byte [] buffer = Converter.wcsToMbcs (null, string, true);
1946
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
2227
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
1947
		OS.gtk_combo_box_remove_text (handle, index);
2228
		OS.gtk_combo_box_remove_text (handle, index);
Lines 1990-1995 Link Here
1990
		}
2271
		}
1991
		for (int i = 0; i < items.length; i++) {
2272
		for (int i = 0; i < items.length; i++) {
1992
			String string = items [i];
2273
			String string = items [i];
2274
			if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2275
				string = getSegmentsText (string);
2276
			}
1993
			byte [] buffer = Converter.wcsToMbcs (null, string, true);
2277
			byte [] buffer = Converter.wcsToMbcs (null, string, true);
1994
			OS.gtk_combo_box_insert_text (handle, i, buffer);
2278
			OS.gtk_combo_box_insert_text (handle, i, buffer);
1995
			if ((style & SWT.RIGHT_TO_LEFT) != 0 && popupHandle != 0) {
2279
			if ((style & SWT.RIGHT_TO_LEFT) != 0 && popupHandle != 0) {
Lines 2017-2022 Link Here
2017
		}
2301
		}
2018
		lockText = ignoreSelect = false;
2302
		lockText = ignoreSelect = false;
2019
		OS.gtk_entry_set_text (entryHandle, new byte[1]);
2303
		OS.gtk_entry_set_text (entryHandle, new byte[1]);
2304
		if (segments != null) clearSegments (false);
2020
	}
2305
	}
2021
}
2306
}
2022
2307
Lines 2113-2118 Link Here
2113
	if (selection == null) error (SWT.ERROR_NULL_ARGUMENT);
2398
	if (selection == null) error (SWT.ERROR_NULL_ARGUMENT);
2114
	if ((style & SWT.READ_ONLY) != 0) return;
2399
	if ((style & SWT.READ_ONLY) != 0) return;
2115
	if (entryHandle != 0) {
2400
	if (entryHandle != 0) {
2401
		if (segments != null) {
2402
			selection.x = translateOffset (selection.x);
2403
			selection.y = translateOffset (selection.y);
2404
		}
2116
		OS.gtk_editable_set_position (entryHandle, selection.x);
2405
		OS.gtk_editable_set_position (entryHandle, selection.x);
2117
		OS.gtk_editable_select_region (entryHandle, selection.x, selection.y);
2406
		OS.gtk_editable_select_region (entryHandle, selection.x, selection.y);
2118
	}
2407
	}
Lines 2179-2184 Link Here
2179
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2468
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2180
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
2469
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
2181
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
2470
	OS.g_signal_handlers_block_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
2471
	if (segments != null) clearSegments (false);
2182
	OS.gtk_entry_set_text (entryHandle, buffer);
2472
	OS.gtk_entry_set_text (entryHandle, buffer);
2183
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
2473
	if (OS.GTK_VERSION >= OS.VERSION (2, 4, 0)) {
2184
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2474
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
Lines 2187-2192 Link Here
2187
	OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
2477
	OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
2188
	OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
2478
	OS.g_signal_handlers_unblock_matched (entryHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
2189
	sendEvent (SWT.Modify);
2479
	sendEvent (SWT.Modify);
2480
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2481
		applySegments ();
2482
	}
2190
}
2483
}
2191
2484
2192
/**
2485
/**
Lines 2212-2218 Link Here
2212
public void setTextLimit (int limit) {
2505
public void setTextLimit (int limit) {
2213
	checkWidget();
2506
	checkWidget();
2214
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
2507
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
2215
	if (entryHandle != 0) OS.gtk_entry_set_max_length (entryHandle, limit);
2508
	if (entryHandle != 0) {
2509
		if (segments != null) {
2510
			OS.gtk_entry_set_max_length (entryHandle, Math.min (LIMIT, limit + segments.length));
2511
		} else {
2512
			OS.gtk_entry_set_max_length (entryHandle, limit);
2513
		}
2514
	}
2216
}
2515
}
2217
2516
2218
void setToolTipText (Shell shell, String newString) {
2517
void setToolTipText (Shell shell, String newString) {
Lines 2247-2252 Link Here
2247
	return false;
2546
	return false;
2248
}
2547
}
2249
2548
2549
int translateOffset (int offset) {
2550
	if (segments == null) return offset;
2551
	for (int i = 0, nSegments = segments.length; i < nSegments && offset - i >= segments[i]; i++) {
2552
		offset++;
2553
	}	
2554
	return offset;
2555
}
2556
2250
boolean translateTraversal (GdkEventKey keyEvent) {
2557
boolean translateTraversal (GdkEventKey keyEvent) {
2251
	int key = keyEvent.keyval;
2558
	int key = keyEvent.keyval;
2252
	switch (key) {
2559
	switch (key) {
Lines 2267-2272 Link Here
2267
	return super.translateTraversal (keyEvent);
2574
	return super.translateTraversal (keyEvent);
2268
}
2575
}
2269
2576
2577
int untranslateOffset (int offset) {
2578
	if (segments == null) return offset;
2579
	for (int i = 0, nSegments = segments.length; i < nSegments && offset > segments[i]; i++) {
2580
		offset--;
2581
	}
2582
	return offset;
2583
}
2584
2270
String verifyText (String string, int start, int end) {
2585
String verifyText (String string, int start, int end) {
2271
	if (string.length () == 0 && start == end) return null;
2586
	if (string.length () == 0 && start == end) return null;
2272
	Event event = new Event ();
2587
	Event event = new Event ();
(-)Eclipse SWT/gtk/org/eclipse/swt/widgets/Widget.java (+4 lines)
Lines 1252-1257 Link Here
1252
	eventTable.unhook (SWT.Dispose, listener);
1252
	eventTable.unhook (SWT.Dispose, listener);
1253
}
1253
}
1254
1254
1255
int /*long*/ segmentsProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) {
1256
	return 0;
1257
}
1258
1255
void sendEvent (Event event) {
1259
void sendEvent (Event event) {
1256
	Display display = event.display;
1260
	Display display = event.display;
1257
	if (!display.filterEvent (event)) {
1261
	if (!display.filterEvent (event)) {
(-)Eclipse SWT/gtk/org/eclipse/swt/widgets/Text.java (-19 / +318 lines)
Lines 63-68 Link Here
63
	boolean doubleClick;
63
	boolean doubleClick;
64
	String message = "";
64
	String message = "";
65
	
65
	
66
	static final char LTR_MARK = '\u200e';
67
	static final char RTL_MARK = '\u200f';
68
69
	/* GTK signals data */
70
	static final int BACKSPACE = 1;
71
	static final int COPY_CLIPBOARD = 2;
72
	static final int CUT_CLIPBOARD = 3;
73
	static final int PASTE_CLIPBOARD = 4;
74
	static final int DELETE_FROM_CURSOR = 5;
75
	static final int MOVE_CURSOR = 6;
76
	static final int CONNECTED_AFTER = 8;
77
78
	int[] segments;
79
66
	static final int ITER_SIZEOF = OS.GtkTextIter_sizeof();
80
	static final int ITER_SIZEOF = OS.GtkTextIter_sizeof();
67
	static final int SPACE_FOR_CURSOR = 1;
81
	static final int SPACE_FOR_CURSOR = 1;
68
	
82
	
Lines 257-262 Link Here
257
	addListener (SWT.Modify, typedListener);
271
	addListener (SWT.Modify, typedListener);
258
}
272
}
259
273
274
public void addSegmentListener (SegmentListener listener) {
275
	checkWidget ();
276
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
277
	if (segments != null) clearSegments ();
278
	addListener (SWT.GetSegments, new TypedListener (listener));
279
	applySegments ();
280
	
281
	if (OS.g_signal_handler_find (handle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc2, 0) == 0) {
282
		/* 
283
		* NOTE: We do not instantiate the segments callbacks unless they are
284
		* really needed. 
285
		*/
286
		if (display.segmentsCallback2 == null) {
287
			display.segmentsCallback2 = new Callback (display, "segmentsProc2", 2); //$NON-NLS-1$
288
			display.segmentsProc2 = display.segmentsCallback2.getAddress ();
289
			if (display.segmentsProc2 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
290
			display.segmentsCallback4 = new Callback (display, "segmentsProc4", 4); //$NON-NLS-1$
291
			display.segmentsProc4 = display.segmentsCallback4.getAddress ();
292
			if (display.segmentsProc4 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
293
			display.segmentsCallback5 = new Callback (display, "segmentsProc5", 5); //$NON-NLS-1$
294
			display.segmentsProc5 = display.segmentsCallback5.getAddress ();
295
			if (display.segmentsProc5 == 0) error (SWT.ERROR_NO_MORE_CALLBACKS);
296
		}
297
		OS.g_signal_connect (handle, OS.backspace, display.segmentsProc2, BACKSPACE);
298
		OS.g_signal_connect (handle, OS.copy_clipboard, display.segmentsProc2, COPY_CLIPBOARD);
299
		OS.g_signal_connect (handle, OS.cut_clipboard, display.segmentsProc2, CUT_CLIPBOARD);
300
		OS.g_signal_connect (handle, OS.paste_clipboard, display.segmentsProc2, PASTE_CLIPBOARD);
301
		OS.g_signal_connect (handle, OS.delete_from_cursor, display.segmentsProc4, DELETE_FROM_CURSOR);
302
		OS.g_signal_connect (handle, OS.move_cursor, display.segmentsProc5, MOVE_CURSOR);
303
		OS.g_signal_connect_after (handle, OS.backspace, display.segmentsProc2, BACKSPACE | CONNECTED_AFTER);
304
		OS.g_signal_connect_after (handle, OS.copy_clipboard, display.segmentsProc2, COPY_CLIPBOARD | CONNECTED_AFTER);
305
		OS.g_signal_connect_after (handle, OS.cut_clipboard, display.segmentsProc2, CUT_CLIPBOARD | CONNECTED_AFTER);
306
		OS.g_signal_connect_after (handle, OS.paste_clipboard, display.segmentsProc2, PASTE_CLIPBOARD | CONNECTED_AFTER);
307
		OS.g_signal_connect_after (handle, OS.delete_from_cursor, display.segmentsProc4, DELETE_FROM_CURSOR | CONNECTED_AFTER);
308
		OS.g_signal_connect_after (handle, OS.move_cursor, display.segmentsProc5, MOVE_CURSOR | CONNECTED_AFTER);
309
	}
310
}
311
260
/**
312
/**
261
 * Adds the listener to the collection of listeners who will
313
 * Adds the listener to the collection of listeners who will
262
 * be notified when the control is selected by the user, by sending
314
 * be notified when the control is selected by the user, by sending
Lines 338-343 Link Here
338
	checkWidget ();
390
	checkWidget ();
339
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
391
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
340
	byte [] buffer = Converter.wcsToMbcs (null, string, false);
392
	byte [] buffer = Converter.wcsToMbcs (null, string, false);
393
	if (segments != null) clearSegments ();
341
	if ((style & SWT.SINGLE) != 0) {
394
	if ((style & SWT.SINGLE) != 0) {
342
		OS.gtk_editable_insert_text (handle, buffer, buffer.length, new int[]{-1});
395
		OS.gtk_editable_insert_text (handle, buffer, buffer.length, new int[]{-1});
343
		OS.gtk_editable_set_position (handle, -1);
396
		OS.gtk_editable_set_position (handle, -1);
Lines 349-354 Link Here
349
		int /*long*/ mark = OS.gtk_text_buffer_get_insert (bufferHandle);
402
		int /*long*/ mark = OS.gtk_text_buffer_get_insert (bufferHandle);
350
		OS.gtk_text_view_scroll_mark_onscreen (handle, mark);
403
		OS.gtk_text_view_scroll_mark_onscreen (handle, mark);
351
	}
404
	}
405
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
406
		applySegments ();
407
	}
408
}
409
410
void applySegments () {
411
	if (!hooks (SWT.GetSegments) && !filters (SWT.GetSegments)) return;
412
	if (segments != null) clearSegments ();
413
	Event event = new Event ();
414
	String string = getText ();
415
	event.text = string;
416
	event.segments = segments;
417
	sendEvent (SWT.GetSegments, event);
418
	segments = event.segments;
419
	if (segments == null) return;
420
	int nSegments = segments.length;
421
	if (nSegments == 0) return;
422
423
	for (int i = 1, lineLength = string == null ? 0 : string.length (); i < nSegments; i++) {
424
		if (event.segments [i] < event.segments [i - 1] || event.segments [i] > lineLength) {
425
			SWT.error (SWT.ERROR_INVALID_ARGUMENT);
426
		}
427
	}
428
	char[] segmentsChars = event.segmentsChars;
429
	char [] separator = { getOrientation () == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK };
430
	if ((style & SWT.SINGLE) != 0) {
431
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
432
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
433
		int limit = OS.gtk_entry_get_max_length (handle);
434
		if (limit != 0) OS.gtk_entry_set_max_length (handle, limit + nSegments);
435
		int [] pos = new int [1];
436
		for (int i = 0; i < nSegments; i++) {
437
			pos [0] = segments [i] + i;
438
			if (segmentsChars != null && segmentsChars.length > i) {
439
				separator [0] = segmentsChars [i];
440
			}
441
			byte [] buffer = Converter.wcsToMbcs (null, separator, false);
442
			OS.gtk_editable_insert_text (handle, buffer, buffer.length, pos);
443
		}
444
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
445
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
446
	} else {
447
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
448
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, TEXT_BUFFER_INSERT_TEXT);
449
		byte [] pos = new byte [ITER_SIZEOF];
450
		for (int i = 0; i < nSegments; i++) {
451
			OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, pos, segments[i] + i);
452
			if (segmentsChars != null && segmentsChars.length > i) {
453
				separator [0] = segmentsChars [i];
454
			}
455
			byte [] buffer = Converter.wcsToMbcs (null, separator, false);
456
			OS.gtk_text_buffer_insert (bufferHandle, pos, buffer, buffer.length);
457
		}
458
		OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
459
		OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, TEXT_BUFFER_INSERT_TEXT);
460
	}
461
}
462
463
void clearSegments () {
464
	if (segments == null) return;
465
	int nSegments = segments.length;
466
	if (nSegments == 0) return;
467
468
	if ((style & SWT.SINGLE) != 0) {
469
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
470
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
471
		for (int i = 0; i < nSegments; i++) {
472
			OS.gtk_editable_delete_text (handle, segments[i], segments[i] + 1);
473
		}
474
		int limit = OS.gtk_entry_get_max_length (handle);
475
		if (limit != 0) OS.gtk_entry_set_max_length (handle, limit - nSegments);
476
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
477
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
478
	} else {
479
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
480
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_RANGE);
481
482
		byte [] start = new byte [ITER_SIZEOF], end = new byte [ITER_SIZEOF];
483
		for (int i = 0; i < nSegments; i++) {
484
			OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, start, segments[i]);
485
			OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, end, segments[i] + 1);
486
			OS.gtk_text_buffer_delete (bufferHandle, start, end);
487
		}
488
		OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
489
		OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_RANGE);
490
	}
491
	segments = null;
352
}
492
}
353
493
354
/**
494
/**
Lines 462-468 Link Here
462
		OS.gtk_editable_copy_clipboard (handle);
602
		OS.gtk_editable_copy_clipboard (handle);
463
	} else {
603
	} else {
464
		int /*long*/ clipboard = OS.gtk_clipboard_get (OS.GDK_NONE);
604
		int /*long*/ clipboard = OS.gtk_clipboard_get (OS.GDK_NONE);
465
		OS.gtk_text_buffer_copy_clipboard (bufferHandle, clipboard);
605
		if (segments != null) {
606
			clearSegments ();
607
			OS.gtk_text_buffer_copy_clipboard (bufferHandle, clipboard);
608
			applySegments ();
609
		} else {
610
			OS.gtk_text_buffer_copy_clipboard (bufferHandle, clipboard);
611
		}
466
	}
612
	}
467
}
613
}
468
614
Lines 484-491 Link Here
484
		OS.gtk_editable_cut_clipboard (handle);
630
		OS.gtk_editable_cut_clipboard (handle);
485
	} else {
631
	} else {
486
		int /*long*/ clipboard = OS.gtk_clipboard_get (OS.GDK_NONE);
632
		int /*long*/ clipboard = OS.gtk_clipboard_get (OS.GDK_NONE);
487
		OS.gtk_text_buffer_cut_clipboard (bufferHandle, clipboard, OS.gtk_text_view_get_editable (handle));
633
		if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
634
			if (segments != null) clearSegments ();
635
			OS.gtk_text_buffer_cut_clipboard (bufferHandle, clipboard, OS.gtk_text_view_get_editable (handle));
636
			applySegments ();
637
		} else {
638
			OS.gtk_text_buffer_cut_clipboard (bufferHandle, clipboard, OS.gtk_text_view_get_editable (handle));
639
		}
640
	}
641
}
642
643
char [] deprocessText (char [] text, int start) {
644
	if (text == null || segments == null) return text;
645
	int length = text.length;
646
	if (length == 0) return text;
647
	int nSegments = segments.length;
648
	if (nSegments == 0) return text;
649
	if (start > segments [nSegments - 1] || start + length <= segments [0]) return text;
650
	char[] newText = new char [length];
651
	int nLeadSegments = 0;
652
	while (start - nLeadSegments > segments [nLeadSegments]) nLeadSegments++;
653
	int segmentCount = nLeadSegments;
654
	for (int i = 0; i < length; i++) {
655
		if (segmentCount < nSegments && i + start - segmentCount == segments [segmentCount]) {
656
			++segmentCount;
657
		} else {
658
			newText [i - segmentCount + nLeadSegments] = text [i];
659
		}
660
	}
661
	segmentCount -= nLeadSegments;
662
	if (segmentCount > 0) {
663
		char [] newChars = new char [length - segmentCount];
664
		System.arraycopy(newText, 0, newChars, 0, length - segmentCount);
665
		return newChars;
488
	}
666
	}
667
	return newText;
489
}
668
}
490
669
491
void deregister () {
670
void deregister () {
Lines 669-681 Link Here
669
 */
848
 */
670
public int getCaretPosition () {
849
public int getCaretPosition () {
671
	checkWidget ();
850
	checkWidget ();
851
	int caretPos;
672
	if ((style & SWT.SINGLE) != 0)  {
852
	if ((style & SWT.SINGLE) != 0)  {
673
		return OS.gtk_editable_get_position (handle);
853
		caretPos = OS.gtk_editable_get_position (handle);
854
	} else {
855
		byte [] position = new byte [ITER_SIZEOF];
856
		int /*long*/ mark = OS.gtk_text_buffer_get_insert (bufferHandle);
857
		OS.gtk_text_buffer_get_iter_at_mark (bufferHandle, position, mark);
858
		caretPos = OS.gtk_text_iter_get_offset (position);
674
	}
859
	}
675
	byte [] position = new byte [ITER_SIZEOF];
860
	if (segments != null) caretPos = untranslateOffset (caretPos);
676
	int /*long*/ mark = OS.gtk_text_buffer_get_insert (bufferHandle);
861
	return caretPos;
677
	OS.gtk_text_buffer_get_iter_at_mark (bufferHandle, position, mark);
678
	return OS.gtk_text_iter_get_offset (position);
679
}
862
}
680
863
681
/**
864
/**
Lines 690-700 Link Here
690
 */
873
 */
691
public int getCharCount () {
874
public int getCharCount () {
692
	checkWidget ();
875
	checkWidget ();
876
	int count;
693
	if ((style & SWT.SINGLE) != 0) {
877
	if ((style & SWT.SINGLE) != 0) {
694
		int /*long*/ ptr = OS.gtk_entry_get_text (handle);
878
		int /*long*/ ptr = OS.gtk_entry_get_text (handle);
695
		return (int)/*64*/OS.g_utf8_strlen (ptr, -1);
879
		count = (int)/*64*/OS.g_utf8_strlen (ptr, -1);
880
	} else {
881
		count = OS.gtk_text_buffer_get_char_count (bufferHandle);
696
	}
882
	}
697
	return OS.gtk_text_buffer_get_char_count (bufferHandle);
883
	if (segments != null) count -= segments.length;
884
	return count;
698
}
885
}
699
886
700
/**
887
/**
Lines 868-873 Link Here
868
		OS.gtk_text_view_get_iter_at_location (handle, p, point.x, point.y);
1055
		OS.gtk_text_view_get_iter_at_location (handle, p, point.x, point.y);
869
		position = OS.gtk_text_iter_get_offset (p);
1056
		position = OS.gtk_text_iter_get_offset (p);
870
	}
1057
	}
1058
	if (segments != null) position = untranslateOffset(position);
871
	return position;
1059
	return position;
872
}
1060
}
873
1061
Lines 891-906 Link Here
891
 */
1079
 */
892
public Point getSelection () {
1080
public Point getSelection () {
893
	checkWidget ();
1081
	checkWidget ();
1082
	Point selection;
894
	if ((style & SWT.SINGLE) != 0) {
1083
	if ((style & SWT.SINGLE) != 0) {
895
		int [] start = new int [1];
1084
		int [] start = new int [1];
896
		int [] end = new int [1];
1085
		int [] end = new int [1];
897
		OS.gtk_editable_get_selection_bounds (handle, start, end);
1086
		OS.gtk_editable_get_selection_bounds (handle, start, end);
898
		return new Point (start [0], end [0]);
1087
		selection = new Point (start [0], end [0]);
1088
	} else {
1089
		byte [] start =  new byte [ITER_SIZEOF];
1090
		byte [] end =  new byte [ITER_SIZEOF];
1091
		OS.gtk_text_buffer_get_selection_bounds (bufferHandle, start, end);
1092
		selection = new Point (OS.gtk_text_iter_get_offset (start), OS.gtk_text_iter_get_offset (end));
1093
	}
1094
	if (segments != null) {
1095
		selection.x = untranslateOffset (selection.x);
1096
		selection.y = untranslateOffset (selection.y);
899
	}
1097
	}
900
	byte [] start =  new byte [ITER_SIZEOF];
1098
	return selection;
901
	byte [] end =  new byte [ITER_SIZEOF];
902
	OS.gtk_text_buffer_get_selection_bounds (bufferHandle, start, end);
903
	return new Point (OS.gtk_text_iter_get_offset (start), OS.gtk_text_iter_get_offset (end));
904
}
1099
}
905
1100
906
/**
1101
/**
Lines 1007-1022 Link Here
1007
	int /*long*/ address;
1202
	int /*long*/ address;
1008
	if ((style & SWT.SINGLE) != 0) {
1203
	if ((style & SWT.SINGLE) != 0) {
1009
		start = Math.max (0, start);
1204
		start = Math.max (0, start);
1010
		address = OS.gtk_editable_get_chars (handle, start, end + 1);
1205
		if (segments != null) {
1206
			start = translateOffset (start);
1207
			address = OS.gtk_editable_get_chars (handle, start, translateOffset (end + 1));
1208
		} else {
1209
			address = OS.gtk_editable_get_chars (handle, start, end + 1);
1210
		}
1011
	} else {
1211
	} else {
1012
		int length = OS.gtk_text_buffer_get_char_count (bufferHandle);
1212
		int length = OS.gtk_text_buffer_get_char_count (bufferHandle);
1213
		if (segments != null) length -= segments.length;
1013
		end = Math.min (end, length - 1);
1214
		end = Math.min (end, length - 1);
1014
		if (start > end) return "";
1215
		if (start > end) return "";
1015
		start = Math.max (0, start);
1216
		start = Math.max (0, start);
1016
		byte [] startIter =  new byte [ITER_SIZEOF];
1217
		byte [] startIter =  new byte [ITER_SIZEOF];
1017
		byte [] endIter =  new byte [ITER_SIZEOF];
1218
		byte [] endIter =  new byte [ITER_SIZEOF];
1219
		if (segments != null) {
1220
			start = translateOffset (start);
1221
			OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, endIter, translateOffset (end + 1));
1222
		} else {
1223
			OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, endIter, end + 1);
1224
		}
1018
		OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, startIter, start);
1225
		OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, startIter, start);
1019
		OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, endIter, end + 1);
1020
		address = OS.gtk_text_buffer_get_text (bufferHandle, startIter, endIter, true);
1226
		address = OS.gtk_text_buffer_get_text (bufferHandle, startIter, endIter, true);
1021
	}
1227
	}
1022
	if (address == 0) error (SWT.ERROR_CANNOT_GET_TEXT);
1228
	if (address == 0) error (SWT.ERROR_CANNOT_GET_TEXT);
Lines 1024-1029 Link Here
1024
	byte [] buffer = new byte [length];
1230
	byte [] buffer = new byte [length];
1025
	OS.memmove (buffer, address, length);
1231
	OS.memmove (buffer, address, length);
1026
	OS.g_free (address);
1232
	OS.g_free (address);
1233
	if (segments != null) {
1234
		return new String (deprocessText (Converter.mbcsToWcs (null, buffer), start));
1235
	}
1027
	return new String (Converter.mbcsToWcs (null, buffer));
1236
	return new String (Converter.mbcsToWcs (null, buffer));
1028
}
1237
}
1029
1238
Lines 1058-1063 Link Here
1058
	byte [] buffer = new byte [length];
1267
	byte [] buffer = new byte [length];
1059
	OS.memmove (buffer, address, length);
1268
	OS.memmove (buffer, address, length);
1060
	if ((style & SWT.MULTI) != 0) OS.g_free (address);
1269
	if ((style & SWT.MULTI) != 0) OS.g_free (address);
1270
	if (segments != null) {
1271
		return deprocessText (Converter.mbcsToWcs (null, buffer), 0);
1272
	}
1061
	return Converter.mbcsToWcs (null, buffer);
1273
	return Converter.mbcsToWcs (null, buffer);
1062
}
1274
}
1063
1275
Lines 1081-1087 Link Here
1081
	checkWidget ();
1293
	checkWidget ();
1082
	if ((style & SWT.MULTI) != 0) return LIMIT;
1294
	if ((style & SWT.MULTI) != 0) return LIMIT;
1083
	int limit = OS.gtk_entry_get_max_length (handle);
1295
	int limit = OS.gtk_entry_get_max_length (handle);
1084
	return limit == 0 ? 0xFFFF : limit;
1296
	return limit == 0 ? 0xFFFF : segments != null ? limit - segments.length : limit;
1085
}
1297
}
1086
1298
1087
/**
1299
/**
Lines 1467-1476 Link Here
1467
}
1679
}
1468
1680
1469
int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
1681
int /*long*/ gtk_key_press_event (int /*long*/ widget, int /*long*/ event) {
1682
	boolean handleSegments = false, segmentsCleared = false;
1683
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
1684
		GdkEventKey gdkEvent = new GdkEventKey ();
1685
		OS.memmove (gdkEvent, event, GdkEventKey.sizeof);
1686
		if (gdkEvent.length > 0 && (gdkEvent.state & (OS.GDK_MOD1_MASK | OS.GDK_CONTROL_MASK)) == 0) {
1687
			handleSegments = true;
1688
			if (segments != null) {
1689
				clearSegments ();
1690
				segmentsCleared = true;
1691
			}
1692
		}
1693
	}
1470
	int /*long*/ result = super.gtk_key_press_event (widget, event);
1694
	int /*long*/ result = super.gtk_key_press_event (widget, event);
1471
	if (result != 0) fixIM ();
1695
	if (result != 0) fixIM ();
1472
	if (gdkEventKey == -1) result = 1;
1696
	if (gdkEventKey == -1) result = 1;
1473
	gdkEventKey = 0;
1697
	gdkEventKey = 0;
1698
	if (handleSegments && (result != 0 || segmentsCleared)) {
1699
		applySegments ();
1700
	}
1474
	return result;
1701
	return result;
1475
}
1702
}
1476
1703
Lines 1564-1569 Link Here
1564
public void insert (String string) {
1791
public void insert (String string) {
1565
	checkWidget ();
1792
	checkWidget ();
1566
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1793
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1794
	if (segments != null) clearSegments ();
1567
	byte [] buffer = Converter.wcsToMbcs (null, string, false);
1795
	byte [] buffer = Converter.wcsToMbcs (null, string, false);
1568
	if ((style & SWT.SINGLE) != 0) {
1796
	if ((style & SWT.SINGLE) != 0) {
1569
		int [] start = new int [1], end = new int [1];
1797
		int [] start = new int [1], end = new int [1];
Lines 1582-1587 Link Here
1582
		int /*long*/ mark = OS.gtk_text_buffer_get_insert (bufferHandle);
1810
		int /*long*/ mark = OS.gtk_text_buffer_get_insert (bufferHandle);
1583
		OS.gtk_text_view_scroll_mark_onscreen (handle, mark);
1811
		OS.gtk_text_view_scroll_mark_onscreen (handle, mark);
1584
	}
1812
	}
1813
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
1814
		applySegments ();
1815
	}
1585
}
1816
}
1586
1817
1587
int /*long*/ paintWindow () {
1818
int /*long*/ paintWindow () {
Lines 1624-1630 Link Here
1624
		OS.gtk_editable_paste_clipboard (handle);
1855
		OS.gtk_editable_paste_clipboard (handle);
1625
	} else {
1856
	} else {
1626
		int /*long*/ clipboard = OS.gtk_clipboard_get (OS.GDK_NONE);
1857
		int /*long*/ clipboard = OS.gtk_clipboard_get (OS.GDK_NONE);
1627
		OS.gtk_text_buffer_paste_clipboard (bufferHandle, clipboard, null, OS.gtk_text_view_get_editable (handle));
1858
		if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
1859
			if (segments != null) clearSegments ();
1860
			OS.gtk_text_buffer_paste_clipboard (bufferHandle, clipboard, null, OS.gtk_text_view_get_editable (handle));
1861
			applySegments ();
1862
		} else {
1863
			OS.gtk_text_buffer_paste_clipboard (bufferHandle, clipboard, null, OS.gtk_text_view_get_editable (handle));
1864
		}
1628
	}
1865
	}
1629
}
1866
}
1630
1867
Lines 1677-1682 Link Here
1677
	eventTable.unhook (SWT.Modify, listener);	
1914
	eventTable.unhook (SWT.Modify, listener);	
1678
}
1915
}
1679
1916
1917
public void removeSegmentListener (SegmentListener listener) {
1918
	checkWidget ();
1919
	if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
1920
	clearSegments ();
1921
	eventTable.unhook (SWT.GetSegments, listener);
1922
	if (getListeners (SWT.GetSegments).length == 0) {
1923
		OS.g_signal_handlers_disconnect_matched (handle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc2, 0);
1924
		OS.g_signal_handlers_disconnect_matched (handle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc4, 0);
1925
		OS.g_signal_handlers_disconnect_matched (handle, OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, display.segmentsProc5, 0);
1926
	} else {
1927
		applySegments ();
1928
	}
1929
}
1930
1680
/**
1931
/**
1681
 * Removes the listener from the collection of listeners who will
1932
 * Removes the listener from the collection of listeners who will
1682
 * be notified when the control is selected by the user.
1933
 * be notified when the control is selected by the user.
Lines 1726-1731 Link Here
1726
	eventTable.unhook (SWT.Verify, listener);	
1977
	eventTable.unhook (SWT.Verify, listener);	
1727
}
1978
}
1728
1979
1980
int /*long*/ segmentsProc (int /*long*/ handle, int /*long*/ arg0, int /*long*/ arg1, int /*long*/ arg2, int /*long*/ user_data) {
1981
	switch (user_data & ~CONNECTED_AFTER) {
1982
		case MOVE_CURSOR:
1983
			if (arg0 != 1 /*GtkMovementStep#GTK_MOVEMENT_VISUAL_POSITIONS*/) break;
1984
		default:
1985
			if ((user_data & CONNECTED_AFTER) != 0) applySegments ();
1986
			else if (segments != null) clearSegments ();
1987
	}
1988
	return 0;
1989
}
1990
1729
/**
1991
/**
1730
 * Selects all the text in the receiver.
1992
 * Selects all the text in the receiver.
1731
 *
1993
 *
Lines 1912-1917 Link Here
1912
 */
2174
 */
1913
public void setSelection (int start) {
2175
public void setSelection (int start) {
1914
	checkWidget ();
2176
	checkWidget ();
2177
	if (segments != null) start = translateOffset (start);
1915
	if ((style & SWT.SINGLE) != 0) {
2178
	if ((style & SWT.SINGLE) != 0) {
1916
		OS.gtk_editable_set_position (handle, start);
2179
		OS.gtk_editable_set_position (handle, start);
1917
	} else {
2180
	} else {
Lines 1950-1955 Link Here
1950
 */
2213
 */
1951
public void setSelection (int start, int end) {
2214
public void setSelection (int start, int end) {
1952
	checkWidget ();
2215
	checkWidget ();
2216
	if (segments != null) {
2217
		start = translateOffset (start);
2218
		end = translateOffset (end);
2219
	}
1953
	if ((style & SWT.SINGLE) != 0) { 
2220
	if ((style & SWT.SINGLE) != 0) { 
1954
		OS.gtk_editable_set_position (handle, start);
2221
		OS.gtk_editable_set_position (handle, start);
1955
		OS.gtk_editable_select_region (handle, start, end);
2222
		OS.gtk_editable_select_region (handle, start, end);
Lines 2099-2107 Link Here
2099
void setText (char [] text) {
2366
void setText (char [] text) {
2100
	if ((style & SWT.SINGLE) != 0) {
2367
	if ((style & SWT.SINGLE) != 0) {
2101
		byte [] buffer = Converter.wcsToMbcs (null, text, true);
2368
		byte [] buffer = Converter.wcsToMbcs (null, text, true);
2369
//		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_FUNC, 0, 0, 0, clipboardProc, CHANGED);
2102
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2370
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2103
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
2371
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
2104
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
2372
		OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, INSERT_TEXT);
2373
		if (segments != null) {
2374
			int limit = OS.gtk_entry_get_max_length (handle);
2375
			if (limit != 0) OS.gtk_entry_set_max_length (handle, limit - segments.length);
2376
			segments = null;
2377
		}
2105
		OS.gtk_entry_set_text (handle, buffer);
2378
		OS.gtk_entry_set_text (handle, buffer);
2106
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2379
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2107
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
2380
		OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_TEXT);
Lines 2109-2114 Link Here
2109
	} else {
2382
	} else {
2110
		byte [] buffer = Converter.wcsToMbcs (null, text, false);
2383
		byte [] buffer = Converter.wcsToMbcs (null, text, false);
2111
		byte [] position =  new byte [ITER_SIZEOF];
2384
		byte [] position =  new byte [ITER_SIZEOF];
2385
		segments = null;
2112
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2386
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, CHANGED);
2113
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_RANGE);
2387
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, DELETE_RANGE);
2114
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, TEXT_BUFFER_INSERT_TEXT);
2388
		OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, 0, 0, TEXT_BUFFER_INSERT_TEXT);
Lines 2127-2132 Link Here
2127
			OS.gtk_entry_set_icon_sensitive (handle, OS.GTK_ENTRY_ICON_SECONDARY, true);
2401
			OS.gtk_entry_set_icon_sensitive (handle, OS.GTK_ENTRY_ICON_SECONDARY, true);
2128
		}
2402
		}
2129
	}
2403
	}
2404
	if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2405
		applySegments ();
2406
	}
2130
}
2407
}
2131
2408
2132
/**
2409
/**
Lines 2156-2162 Link Here
2156
public void setTextLimit (int limit) {
2433
public void setTextLimit (int limit) {
2157
	checkWidget ();
2434
	checkWidget ();
2158
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
2435
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
2159
	if ((style & SWT.SINGLE) != 0) OS.gtk_entry_set_max_length (handle, limit);
2436
	if ((style & SWT.SINGLE) != 0) {
2437
		if (segments != null) {
2438
			OS.gtk_entry_set_max_length (handle, Math.min (LIMIT, limit + segments.length));
2439
		} else {
2440
			OS.gtk_entry_set_max_length (handle, limit);
2441
		}
2442
	}
2160
}
2443
}
2161
2444
2162
/**
2445
/**
Lines 2201-2206 Link Here
2201
	OS.gtk_text_view_scroll_mark_onscreen (handle, mark);
2484
	OS.gtk_text_view_scroll_mark_onscreen (handle, mark);
2202
}
2485
}
2203
2486
2487
int translateOffset (int offset) {
2488
	if (segments == null) return offset;
2489
	for (int i = 0, nSegments = segments.length; i < nSegments && offset - i >= segments[i]; i++) {
2490
		offset++;
2491
	}	
2492
	return offset;
2493
}
2494
2204
boolean translateTraversal (GdkEventKey keyEvent) {
2495
boolean translateTraversal (GdkEventKey keyEvent) {
2205
	int key = keyEvent.keyval;
2496
	int key = keyEvent.keyval;
2206
	switch (key) {
2497
	switch (key) {
Lines 2236-2241 Link Here
2236
	return bits;
2527
	return bits;
2237
}
2528
}
2238
2529
2530
int untranslateOffset (int offset) {
2531
	if (segments == null) return offset;
2532
	for (int i = 0, nSegments = segments.length; i < nSegments && offset > segments[i]; i++) {
2533
		offset--;
2534
	}
2535
	return offset;
2536
}
2537
2239
String verifyText (String string, int start, int end) {
2538
String verifyText (String string, int start, int end) {
2240
	if (string != null && string.length () == 0 && start == end) return null;
2539
	if (string != null && string.length () == 0 && start == end) return null;
2241
	Event event = new Event ();
2540
	Event event = new Event ();
(-)Eclipse SWT PI/gtk/org/eclipse/swt/internal/gtk/OS.java (+6 lines)
Lines 445-450 Link Here
445
	
445
	
446
	/** Signals */
446
	/** Signals */
447
	public static final byte[] activate = ascii("activate");
447
	public static final byte[] activate = ascii("activate");
448
	public static final byte[] backspace = ascii("backspace");
448
	public static final byte[] button_press_event = ascii("button-press-event");
449
	public static final byte[] button_press_event = ascii("button-press-event");
449
	public static final byte[] button_release_event = ascii("button-release-event");
450
	public static final byte[] button_release_event = ascii("button-release-event");
450
	public static final byte[] changed = ascii("changed");
451
	public static final byte[] changed = ascii("changed");
Lines 453-459 Link Here
453
	public static final byte[] clicked = ascii("clicked");
454
	public static final byte[] clicked = ascii("clicked");
454
	public static final byte[] commit = ascii("commit");
455
	public static final byte[] commit = ascii("commit");
455
	public static final byte[] configure_event = ascii("configure-event");
456
	public static final byte[] configure_event = ascii("configure-event");
457
	public static final byte[] copy_clipboard = ascii("copy-clipboard");
458
	public static final byte[] cut_clipboard = ascii("cut-clipboard");
456
	public static final byte[] delete_event = ascii("delete-event");
459
	public static final byte[] delete_event = ascii("delete-event");
460
	public static final byte[] delete_from_cursor = ascii("delete-from-cursor");
457
	public static final byte[] day_selected = ascii("day-selected");
461
	public static final byte[] day_selected = ascii("day-selected");
458
	public static final byte[] day_selected_double_click = ascii("day-selected-double-click");
462
	public static final byte[] day_selected_double_click = ascii("day-selected-double-click");
459
	public static final byte[] delete_range = ascii("delete-range");
463
	public static final byte[] delete_range = ascii("delete-range");
Lines 486-493 Link Here
486
	public static final byte[] mnemonic_activate = ascii("mnemonic-activate");
490
	public static final byte[] mnemonic_activate = ascii("mnemonic-activate");
487
	public static final byte[] month_changed = ascii("month-changed");
491
	public static final byte[] month_changed = ascii("month-changed");
488
	public static final byte[] motion_notify_event = ascii("motion-notify-event");
492
	public static final byte[] motion_notify_event = ascii("motion-notify-event");
493
	public static final byte[] move_cursor = ascii("move-cursor");
489
	public static final byte[] move_focus = ascii("move-focus");
494
	public static final byte[] move_focus = ascii("move-focus");
490
	public static final byte[] output = ascii("output");
495
	public static final byte[] output = ascii("output");
496
	public static final byte[] paste_clipboard = ascii("paste-clipboard");
491
	public static final byte[] popup_menu = ascii("popup-menu");
497
	public static final byte[] popup_menu = ascii("popup-menu");
492
	public static final byte[] populate_popup = ascii("populate-popup");
498
	public static final byte[] populate_popup = ascii("populate-popup");
493
	public static final byte[] preedit_changed = ascii("preedit-changed");
499
	public static final byte[] preedit_changed = ascii("preedit-changed");
(-)Eclipse SWT/common/org/eclipse/swt/SWT.java (+14 lines)
Lines 748-753 Link Here
748
	 */
748
	 */
749
	public static final int Gesture = 48;
749
	public static final int Gesture = 48;
750
750
751
	/**
752
	 * The get segments event type (value is 49).
753
	 * 
754
	 * @see org.eclipse.swt.widgets.Widget#addListener
755
	 * @see org.eclipse.swt.widgets.Display#addFilter
756
	 * @see org.eclipse.swt.widgets.Event
757
	 * 
758
	 * @see org.eclipse.swt.widgets.Text#addSegmentListener
759
	 * @see org.eclipse.swt.events.SegmentEvent
760
	 * 
761
	 * @since 3.7
762
	 */
763
	public static final int GetSegments = 49;
764
751
	/* Event Details */
765
	/* Event Details */
752
	
766
	
753
	/**
767
	/**
(-)Eclipse SWT/common/org/eclipse/swt/widgets/Event.java (+12 lines)
Lines 203-208 Link Here
203
	 */
203
	 */
204
	public String text;
204
	public String text;
205
205
206
	/** 
207
	 * Bidi segment offsets
208
	 * @since 3.7
209
	 */
210
	public int[] segments;
211
	
212
	/** 
213
	 * Characters to be applied on the segment boundaries
214
	 * @since 3.7
215
	 */
216
	public char[] segmentsChars;
217
206
	/**
218
	/**
207
	 * depending on the event, a flag indicating whether the operation
219
	 * depending on the event, a flag indicating whether the operation
208
	 * should be allowed.  Setting this field to false will cancel the
220
	 * should be allowed.  Setting this field to false will cancel the
(-)Eclipse SWT Custom Widgets/common/org/eclipse/swt/custom/BidiSegmentEvent.java (-13 / +1 lines)
Lines 73-79 Link Here
73
 *
73
 *
74
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
74
 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
75
 */
75
 */
76
public class BidiSegmentEvent extends TypedEvent {
76
public class BidiSegmentEvent extends SegmentEvent {
77
	
77
	
78
	/** 
78
	/** 
79
	 * line start offset 
79
	 * line start offset 
Lines 84-102 Link Here
84
	 * line text 
84
	 * line text 
85
	 */			
85
	 */			
86
	public String lineText;
86
	public String lineText;
87
	
88
	/** 
89
	 * bidi segments, see above 
90
	 */
91
	public int[] segments;
92
87
93
	/** 
94
	 * characters to be used in the segment boundaries (optional)
95
	 * 
96
	 * @since 3.6
97
	 */
98
	public char[] segmentsChars;
99
		
100
	static final long serialVersionUID = 3257846571587547957L;
88
	static final long serialVersionUID = 3257846571587547957L;
101
89
102
BidiSegmentEvent(StyledTextEvent e) {
90
BidiSegmentEvent(StyledTextEvent e) {
(-)Eclipse (+37 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 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
package org.eclipse.swt.events;
12
13
import org.eclipse.swt.internal.SWTEventListener;
14
15
/**
16
 * This listener interface may be implemented in order to receive
17
 * SegmentEvents.
18
 * @see SegmentEvent
19
 */
20
public interface SegmentListener extends SWTEventListener {
21
22
/**
23
 * This method is called when a line needs to be reordered for 
24
 * measuring or rendering in a bidi locale. 
25
 * <p>
26
 * The following event fields are used:<ul>
27
 * <li>event.lineText line text (input)</li>
28
 * <li>event.segmentsChars characters that should be inserted</li>
29
 * <li>event.segments text offsets for segment characters</li></ul>
30
 *
31
 * @param event the given event
32
 * @see SegmentEvent
33
 * @see org.eclipse.swt.custom.BidiSegmentListener
34
 */
35
public void lineGetSegments(SegmentEvent event);
36
37
}
(-)Eclipse (+42 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2010 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
package org.eclipse.swt.events;
12
13
import org.eclipse.swt.widgets.Event;
14
15
/**
16
 * @since 3.7
17
 *
18
 */
19
public class SegmentEvent extends TypedEvent {
20
	/** 
21
	 * line text 
22
	 */			
23
	public String text;
24
	
25
	/** 
26
	 * bidi segments, see above 
27
	 */
28
	public int[] segments;
29
30
	/** 
31
	 * characters to be employed on the segment boundaries 
32
	 */
33
	public char[] segmentsChars;
34
35
	
36
	private static final long serialVersionUID = -89306787890624323L;
37
38
	public SegmentEvent(Event e) {
39
		super(e);
40
		text = e.text;
41
	}
42
}
(-)Eclipse SWT/win32/org/eclipse/swt/widgets/Combo.java (-25 / +450 lines)
Lines 69-75 Link Here
69
	 * that the text field in an instance of this class can hold
69
	 * that the text field in an instance of this class can hold
70
	 */
70
	 */
71
	public static final int LIMIT;
71
	public static final int LIMIT;
72
	
72
73
	static final char LTR_MARK = '\u200e';
74
	static final char RTL_MARK = '\u200f';
75
76
	int [] segments;
77
	int [][] itemSegments;
78
73
	/*
79
	/*
74
	 * These values can be different on different platforms.
80
	 * These values can be different on different platforms.
75
	 * Therefore they are not initialized in the declaration
81
	 * Therefore they are not initialized in the declaration
Lines 225-230 Link Here
225
231
226
/**
232
/**
227
 * Adds the listener to the collection of listeners who will
233
 * Adds the listener to the collection of listeners who will
234
 * be notified when the receiver's text is verified, by sending
235
 * it one of the messages defined in the <code>SegmentListener</code>
236
 * interface.
237
 *
238
 * @param listener the listener which should be notified
239
 *
240
 * @exception IllegalArgumentException <ul>
241
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
242
 * </ul>
243
 * @exception SWTException <ul>
244
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
245
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
246
 * </ul>
247
 *
248
 * @see SegmentListener
249
 * @see #removeSegmentListener
250
 */
251
public void addSegmentListener (SegmentListener listener) {
252
	checkWidget ();
253
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
254
	if (segments != null) clearSegments (true);
255
	addListener (SWT.GetSegments, new TypedListener (listener));
256
	applySegments ();
257
	applyItemsSegments ();
258
}
259
260
/**
261
 * Adds the listener to the collection of listeners who will
228
 * be notified when the user changes the receiver's selection, by sending
262
 * be notified when the user changes the receiver's selection, by sending
229
 * it one of the messages defined in the <code>SelectionListener</code>
263
 * it one of the messages defined in the <code>SelectionListener</code>
230
 * interface.
264
 * interface.
Lines 283-288 Link Here
283
	addListener (SWT.Verify, typedListener);
317
	addListener (SWT.Verify, typedListener);
284
}
318
}
285
319
320
void applyItemsSegments () {
321
	int count = getItemCount ();
322
	String [] newItems = new String [count];
323
	for (int i = 0; i < count; i++) {
324
		newItems [i] = getItem (i);
325
	}
326
	itemSegments = null;
327
	for (int i = 0; i < count; i++) {
328
   		setItem (i, newItems [i]);
329
    }
330
}
331
332
void applySegments () {
333
	if (segments != null) clearSegments (true);
334
	checkWidget ();
335
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
336
	int length = OS.GetWindowTextLength (hwndText);
337
	int cp = getCodePage ();
338
	TCHAR buffer = new TCHAR (cp, length + 1);
339
	if (length > 0) OS.GetWindowText (hwndText, buffer, length + 1);
340
	String string = buffer.toString (0, length);
341
	Event event = getSegments (string);
342
	Point selection = getSelection ();
343
	if (event != null) {
344
		segments = event.segments;
345
		if (segments != null && segments.length > 0) {
346
			boolean oldIgnoreCharacter = ignoreCharacter, oldIgnoreModify = ignoreModify;
347
			ignoreCharacter = ignoreModify = true;
348
			int/*64*/ limit = (int/*64*/)OS.SendMessage (hwndText, OS.EM_GETLIMITTEXT, 0, 0) & 0x7fffffff;
349
			OS.SendMessage (hwndText, OS.EM_SETLIMITTEXT, limit + Math.min (segments.length, LIMIT - limit), 0);
350
			/*
351
			 * SetWindowText empties the undo buffer and disables further undo
352
			 * operations. Sending OS.EM_REPLACESEL message.
353
			 */
354
			buffer = new TCHAR (cp, getSegmentsText (string, event), true);
355
			OS.SendMessage (hwndText, OS.EM_SETSEL, 0, -1);
356
			OS.SendMessage (hwndText, OS.EM_REPLACESEL, 1, buffer);
357
			setSelection (selection);
358
			ignoreCharacter = oldIgnoreCharacter;
359
			ignoreModify = oldIgnoreModify;
360
		}
361
	}
362
}
363
286
int /*long*/ callWindowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
364
int /*long*/ callWindowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
287
	if (handle == 0) return 0;
365
	if (handle == 0) return 0;
288
	if (hwnd == handle) {
366
	if (hwnd == handle) {
Lines 302-307 Link Here
302
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
380
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
303
	if (hwnd == hwndText) {
381
	if (hwnd == hwndText) {
304
		if (lockText && msg == OS.WM_SETTEXT) return 0;
382
		if (lockText && msg == OS.WM_SETTEXT) return 0;
383
		switch (msg) {
384
			case OS.WM_KEYDOWN: {
385
				switch (wParam) {
386
					case OS.VK_RIGHT:
387
					case OS.VK_LEFT:
388
						if (OS.GetKeyState (OS.VK_MENU) < 0) break;
389
						// else FALL THROUGH
390
					case OS.VK_DELETE: {
391
						if (segments != null) {
392
							clearSegments (true);
393
						}
394
					}
395
				}
396
				break;
397
			}
398
			case OS.WM_CHAR: {
399
				if (!ignoreCharacter && segments != null && OS.GetKeyState (OS.VK_CONTROL) >= 0 && OS.GetKeyState (OS.VK_MENU) >= 0) {
400
					clearSegments (true);
401
				}
402
				break;
403
			}
404
		}
305
		return OS.CallWindowProc (EditProc, hwnd, msg, wParam, lParam);
405
		return OS.CallWindowProc (EditProc, hwnd, msg, wParam, lParam);
306
	}
406
	}
307
	int /*long*/ hwndList = OS.GetDlgItem (handle, CBID_LIST);
407
	int /*long*/ hwndList = OS.GetDlgItem (handle, CBID_LIST);
Lines 360-365 Link Here
360
	return style;
460
	return style;
361
}
461
}
362
462
463
void clearSegments (boolean applyText) {
464
	checkWidget ();
465
	if (segments == null) return;
466
	int nSegments = segments.length;
467
	if (nSegments == 0) return;
468
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
469
	int/*64*/ limit = (int/*64*/)OS.SendMessage (hwndText, OS.EM_GETLIMITTEXT, 0, 0) & 0x7fffffff;
470
 	if (limit < LIMIT) {
471
		OS.SendMessage (hwndText, OS.EM_SETLIMITTEXT, Math.max (1, limit - nSegments), 0);
472
	}
473
	if (!applyText) {
474
		segments = null;
475
		return;
476
	}
477
	boolean oldIgnoreCharacter = ignoreCharacter, oldIgnoreModify = ignoreModify;
478
	ignoreCharacter = ignoreModify = true;
479
	int length = OS.GetWindowTextLength (hwndText);
480
	int cp = getCodePage ();
481
	TCHAR buffer = new TCHAR (cp, length + 1);
482
	if (length > 0) OS.GetWindowText (hwndText, buffer, length + 1);
483
	Point selection = getSelection ();
484
	String string = deprocessText (buffer.toString (0, length), segments);
485
	segments = null;
486
	buffer = new TCHAR (cp, string, true);
487
	/*
488
	 * SetWindowText empties the undo buffer and disables further undo
489
	 * operations. Sending OS.EM_REPLACESEL message.
490
	 */
491
	OS.SendMessage (hwndText, OS.EM_SETSEL, 0, -1);
492
	if (OS.SendMessage (hwndText, OS.EM_CANUNDO, 0, 0) != 0) {
493
		/*
494
		 * Empty text buffer so that if there be no coming text deletion, then
495
		 * undoing will result in empty text not segmented text.
496
		 */
497
		OS.SendMessage (hwndText, OS.EM_REPLACESEL, 1, new TCHAR (cp, "", true));
498
		OS.SendMessage (hwndText, OS.EM_REPLACESEL, 1, buffer);
499
	} else {
500
		OS.SendMessage (hwndText, OS.EM_REPLACESEL, 0, buffer);
501
	}
502
	setSelection (selection);
503
	ignoreCharacter = oldIgnoreCharacter;
504
	ignoreModify = oldIgnoreModify;
505
}
506
363
/**
507
/**
364
 * Sets the selection in the receiver's text field to an empty
508
 * Sets the selection in the receiver's text field to an empty
365
 * selection starting just before the first character. If the
509
 * selection starting just before the first character. If the
Lines 574-579 Link Here
574
	return OS.GetSysColor (OS.COLOR_WINDOW);
718
	return OS.GetSysColor (OS.COLOR_WINDOW);
575
}
719
}
576
720
721
String deprocessText (String text, int[] segments) {
722
	if (text == null || segments == null) return text;
723
	int length = text.length();
724
	if (length == 0) return text;
725
	int nSegments = segments.length;
726
	if (nSegments == 0) return text;
727
	char[] oldChars = new char[length];
728
	text.getChars (0, length, oldChars, 0);
729
	char[] newChars = new char[length];
730
	int segmentCount = 0;
731
	for (int i = 0; i < length; i++) {
732
		if (segmentCount < nSegments && i - segmentCount == segments[segmentCount]) {
733
			++segmentCount;
734
		} else {
735
			newChars[i - segmentCount] = oldChars[i];
736
		}
737
	}
738
	return new String(newChars, 0, newChars.length - segmentCount);
739
}
740
577
void deregister () {
741
void deregister () {
578
	super.deregister ();
742
	super.deregister ();
579
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
743
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
Lines 601-606 Link Here
601
	OS.SendMessage (handle, OS.CB_SETCURSEL, -1, 0);
765
	OS.SendMessage (handle, OS.CB_SETCURSEL, -1, 0);
602
	sendEvent (SWT.Modify);
766
	sendEvent (SWT.Modify);
603
	// widget could be disposed at this point
767
	// widget could be disposed at this point
768
	clearSegments (false);
604
}
769
}
605
770
606
/**
771
/**
Lines 622-627 Link Here
622
	OS.SendMessage (handle, OS.CB_SETCURSEL, -1, 0);
787
	OS.SendMessage (handle, OS.CB_SETCURSEL, -1, 0);
623
	sendEvent (SWT.Modify);
788
	sendEvent (SWT.Modify);
624
	// widget could be disposed at this point
789
	// widget could be disposed at this point
790
	clearSegments (false);
625
}
791
}
626
792
627
boolean dragDetect (int /*long*/ hwnd, int x, int y, boolean filter, boolean [] detect, boolean [] consume) {
793
boolean dragDetect (int /*long*/ hwnd, int x, int y, boolean filter, boolean [] detect, boolean [] consume) {
Lines 668-674 Link Here
668
	if (length != OS.CB_ERR) {
834
	if (length != OS.CB_ERR) {
669
		TCHAR buffer = new TCHAR (getCodePage (), length + 1);
835
		TCHAR buffer = new TCHAR (getCodePage (), length + 1);
670
		int result = (int)/*64*/OS.SendMessage (handle, OS.CB_GETLBTEXT, index, buffer);
836
		int result = (int)/*64*/OS.SendMessage (handle, OS.CB_GETLBTEXT, index, buffer);
671
		if (result != OS.CB_ERR) return buffer.toString (0, length);
837
		if (result != OS.CB_ERR) {
838
			if (itemSegments != null && itemSegments.length > index) {
839
				return deprocessText (buffer.toString (0, length), itemSegments [index]);
840
			}
841
			return buffer.toString (0, length);
842
		}
672
	}
843
	}
673
	int count = (int)/*64*/OS.SendMessage (handle, OS.CB_GETCOUNT, 0, 0);
844
	int count = (int)/*64*/OS.SendMessage (handle, OS.CB_GETCOUNT, 0, 0);
674
	if (0 <= index && index < count) error (SWT.ERROR_CANNOT_GET_ITEM);
845
	if (0 <= index && index < count) error (SWT.ERROR_CANNOT_GET_ITEM);
Lines 806-811 Link Here
806
	return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
977
	return style & (SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT);
807
}
978
}
808
979
980
Event getSegments (String string) {
981
	if (!hooks (SWT.GetSegments) && !filters (SWT.GetSegments)) return null;
982
	Event event = new Event ();
983
	event.text = string;
984
	sendEvent (SWT.GetSegments, event);
985
	if (event.segments != null) {
986
		for (int i = 1, segmentCount = event.segments.length, lineLength = string == null ? 0 : string.length(); i < segmentCount; i++) {
987
			if (event.segments[i] < event.segments[i - 1] || event.segments[i] > lineLength) {
988
				SWT.error (SWT.ERROR_INVALID_ARGUMENT);
989
			}
990
		}
991
	}
992
	return event;
993
}
994
995
String getSegmentsText (String text, Event event) {
996
	if (text == null || event == null) return text;
997
	int[] segments = event.segments;
998
	if (segments == null) return text;
999
	int nSegments = segments.length;
1000
	if (nSegments == 0) return text;
1001
	char[] segmentsChars = /*event == null ? this.segmentsChars : */event.segmentsChars;
1002
	int length = text.length();
1003
	char[] oldChars = new char[length];
1004
	text.getChars (0, length, oldChars, 0);
1005
	char[] newChars = new char[length + nSegments];
1006
	int charCount = 0, segmentCount = 0;
1007
	char defaultSeparator = getOrientation () == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK;
1008
	while (charCount < length) {
1009
		if (segmentCount < nSegments && charCount == segments[segmentCount]) {
1010
			char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars[segmentCount] : defaultSeparator;
1011
			newChars[charCount + segmentCount++] = separator;
1012
		} else {
1013
			newChars[charCount + segmentCount] = oldChars[charCount++];
1014
		}
1015
	}
1016
	while (segmentCount < nSegments) {
1017
		segments[segmentCount] = charCount;
1018
		char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars[segmentCount] : defaultSeparator;
1019
		newChars[charCount + segmentCount++] = separator;
1020
	}
1021
	return new String(newChars, 0, newChars.length);
1022
}
1023
809
/**
1024
/**
810
 * Returns a <code>Point</code> whose x coordinate is the
1025
 * Returns a <code>Point</code> whose x coordinate is the
811
 * character position representing the start of the selection
1026
 * character position representing the start of the selection
Lines 836-841 Link Here
836
		start [0] = mbcsToWcsPos (start [0]);
1051
		start [0] = mbcsToWcsPos (start [0]);
837
		end [0] = mbcsToWcsPos (end [0]);
1052
		end [0] = mbcsToWcsPos (end [0]);
838
	}
1053
	}
1054
	if (segments != null) {
1055
		if (start[0] == end[0]) {
1056
			start [0] = end [0] = untranslateOffset (start [0]);
1057
		}
1058
		else {
1059
			start [0] = untranslateOffset (start [0]);
1060
			end [0] = untranslateOffset (end [0]);
1061
		}
1062
	}
839
	return new Point (start [0], end [0]);
1063
	return new Point (start [0], end [0]);
840
}
1064
}
841
1065
Lines 874-879 Link Here
874
	if (length == 0) return "";
1098
	if (length == 0) return "";
875
	TCHAR buffer = new TCHAR (getCodePage (), length + 1);
1099
	TCHAR buffer = new TCHAR (getCodePage (), length + 1);
876
	OS.GetWindowText (handle, buffer, length + 1);
1100
	OS.GetWindowText (handle, buffer, length + 1);
1101
	if (segments != null) {
1102
		return deprocessText (buffer.toString (0, length), segments);
1103
	}
877
	return buffer.toString (0, length);
1104
	return buffer.toString (0, length);
878
}
1105
}
879
1106
Lines 918-924 Link Here
918
	checkWidget ();
1145
	checkWidget ();
919
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
1146
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
920
	if (hwndText == 0) return LIMIT;
1147
	if (hwndText == 0) return LIMIT;
921
	return (int)/*64*/OS.SendMessage (hwndText, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
1148
	int/*64*/ limit = (int)/*64*/OS.SendMessage (hwndText, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
1149
	/* XXX default limit is 0xfffffffE on NT, probably depends on control style */
1150
	if (segments != null && limit < LIMIT) limit = Math.max (1, limit - segments.length);
1151
	return limit;
922
}
1152
}
923
1153
924
/**
1154
/**
Lines 1024-1029 Link Here
1024
	return index;
1254
	return index;
1025
}
1255
}
1026
1256
1257
void insertItemSegments(int[] segments, int index) {
1258
	if (index < 0 || segments == null) return;
1259
	int count = itemSegments != null ? itemSegments.length + 1 : 1;
1260
	if (index >= count) return;
1261
	int [][] newSegments = new int [count][];
1262
	if (itemSegments != null) {
1263
		System.arraycopy (itemSegments, 0, newSegments, 0, index);
1264
		System.arraycopy (itemSegments, index, newSegments, index + 1, count - index - 1);
1265
	}
1266
	itemSegments = newSegments;
1267
	itemSegments[index] = segments;
1268
}
1269
1027
int mbcsToWcsPos (int mbcsPos) {
1270
int mbcsToWcsPos (int mbcsPos) {
1028
	if (mbcsPos <= 0) return 0;
1271
	if (mbcsPos <= 0) return 0;
1029
	if (OS.IsUnicode) return mbcsPos;
1272
	if (OS.IsUnicode) return mbcsPos;
Lines 1240-1245 Link Here
1240
	if ((style & SWT.H_SCROLL) != 0) setScrollWidth (0);
1483
	if ((style & SWT.H_SCROLL) != 0) setScrollWidth (0);
1241
}
1484
}
1242
1485
1486
void removeItemSegments(int index) {
1487
	if (index < 0 || itemSegments == null) return;
1488
	int count = itemSegments.length;
1489
	if (index >= count) return;
1490
	int [][] newSegments = new int [count - 1][];
1491
	System.arraycopy (itemSegments, 0, newSegments, 0, index);
1492
	System.arraycopy (itemSegments, index + 1, newSegments, index, count - index - 1);
1493
	itemSegments = newSegments;
1494
}
1495
1243
/**
1496
/**
1244
 * Removes the listener from the collection of listeners who will
1497
 * Removes the listener from the collection of listeners who will
1245
 * be notified when the receiver's text is modified.
1498
 * be notified when the receiver's text is modified.
Lines 1266-1271 Link Here
1266
1519
1267
/**
1520
/**
1268
 * Removes the listener from the collection of listeners who will
1521
 * Removes the listener from the collection of listeners who will
1522
 * be notified when the receiver's text is modified.
1523
 *
1524
 * @param listener the listener which should no longer be notified
1525
 *
1526
 * @exception IllegalArgumentException <ul>
1527
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1528
 * </ul>
1529
 * @exception SWTException <ul>
1530
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1531
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1532
 * </ul>
1533
 *
1534
 * @see SegmentListener
1535
 * @see #addSegmentListener
1536
 */
1537
public void removeSegmentListener (SegmentListener listener) {
1538
	checkWidget ();
1539
	if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
1540
	clearSegments (true);
1541
	eventTable.unhook (SWT.GetSegments, listener);
1542
	applySegments ();
1543
	applyItemsSegments ();
1544
}
1545
/**
1546
 * Removes the listener from the collection of listeners who will
1269
 * be notified when the user changes the receiver's selection.
1547
 * be notified when the user changes the receiver's selection.
1270
 *
1548
 *
1271
 * @param listener the listener which should no longer be notified
1549
 * @param listener the listener which should no longer be notified
Lines 1783-1788 Link Here
1783
		start = wcsToMbcsPos (start);
2061
		start = wcsToMbcsPos (start);
1784
		end = wcsToMbcsPos (end);
2062
		end = wcsToMbcsPos (end);
1785
	}
2063
	}
2064
	if (segments != null) {
2065
		if (start == end) {
2066
			start = end = translateOffset (start);
2067
		}
2068
		else {
2069
			start = translateOffset (start);
2070
			end = translateOffset (end);
2071
		}
2072
	}
1786
	int /*long*/ bits = OS.MAKELPARAM (start, end);
2073
	int /*long*/ bits = OS.MAKELPARAM (start, end);
1787
	OS.SendMessage (handle, OS.CB_SETEDITSEL, 0, bits);
2074
	OS.SendMessage (handle, OS.CB_SETEDITSEL, 0, bits);
1788
}
2075
}
Lines 1820-1825 Link Here
1820
		if (index != -1) select (index);
2107
		if (index != -1) select (index);
1821
		return;
2108
		return;
1822
	}
2109
	}
2110
	if (segments != null) clearSegments (false);
1823
	int limit = LIMIT;
2111
	int limit = LIMIT;
1824
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
2112
	int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
1825
	if (hwndText != 0) {
2113
	if (hwndText != 0) {
Lines 1828-1833 Link Here
1828
	if (string.length () > limit) string = string.substring (0, limit);
2116
	if (string.length () > limit) string = string.substring (0, limit);
1829
	TCHAR buffer = new TCHAR (getCodePage (), string, true);
2117
	TCHAR buffer = new TCHAR (getCodePage (), string, true);
1830
	if (OS.SetWindowText (handle, buffer)) {
2118
	if (OS.SetWindowText (handle, buffer)) {
2119
		if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2120
			applySegments ();
2121
		}
1831
		sendEvent (SWT.Modify);
2122
		sendEvent (SWT.Modify);
1832
		// widget could be disposed at this point
2123
		// widget could be disposed at this point
1833
	}
2124
	}
Lines 1856-1862 Link Here
1856
public void setTextLimit (int limit) {
2147
public void setTextLimit (int limit) {
1857
	checkWidget ();
2148
	checkWidget ();
1858
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
2149
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
1859
	OS.SendMessage (handle, OS.CB_LIMITTEXT, limit, 0);
2150
	if (segments != null && limit > 0) {
2151
		OS.SendMessage (handle, OS.CB_LIMITTEXT, limit + Math.min (segments.length, LIMIT - limit), 0);
2152
	} else {
2153
		OS.SendMessage (handle, OS.CB_LIMITTEXT, limit, 0);
2154
	}
1860
}
2155
}
1861
2156
1862
void setToolTipText (Shell shell, String string) {
2157
void setToolTipText (Shell shell, String string) {
Lines 1904-1909 Link Here
1904
	}
2199
	}
1905
}
2200
}
1906
2201
2202
int translateOffset (int offset) {
2203
	if (segments == null) return offset;
2204
	for (int i = 0, nSegments = segments.length; i < nSegments && offset - i >= segments[i]; i++) {
2205
		offset++;
2206
	}	
2207
	return offset;
2208
}
2209
1907
boolean translateTraversal (MSG msg) {
2210
boolean translateTraversal (MSG msg) {
1908
	/*
2211
	/*
1909
	* When the combo box is dropped down, allow return
2212
	* When the combo box is dropped down, allow return
Lines 1954-1959 Link Here
1954
	}
2257
	}
1955
}
2258
}
1956
2259
2260
int untranslateOffset (int offset) {
2261
	if (segments == null) return offset;
2262
	for (int i = 0, nSegments = segments.length; i < nSegments && offset > segments[i]; i++) {
2263
		offset--;
2264
	}
2265
	return offset;
2266
}
2267
1957
void updateDropDownHeight () {
2268
void updateDropDownHeight () {
1958
	/* 
2269
	/* 
1959
	* Feature in Windows.  If the combo box has the CBS_DROPDOWN
2270
	* Feature in Windows.  If the combo box has the CBS_DROPDOWN
Lines 2044-2054 Link Here
2044
		int /*long*/ hwndList = OS.GetDlgItem (handle, CBID_LIST);
2355
		int /*long*/ hwndList = OS.GetDlgItem (handle, CBID_LIST);
2045
		if ((hwndText != 0 && hwnd == hwndText) || (hwndList != 0 && hwnd == hwndList)) {
2356
		if ((hwndText != 0 && hwnd == hwndText) || (hwndList != 0 && hwnd == hwndList)) {
2046
			LRESULT result = null;
2357
			LRESULT result = null;
2358
			boolean processSegments = false, redraw = false;
2047
			switch (msg) {
2359
			switch (msg) {
2048
				/* Keyboard messages */
2360
				/* Keyboard messages */
2049
				case OS.WM_CHAR:		result = wmChar (hwnd, wParam, lParam); break;
2361
				case OS.WM_CHAR:
2362
					if ((hooks (SWT.GetSegments) || filters (SWT.GetSegments))
2363
							&& OS.GetKeyState (OS.VK_CONTROL) >= 0
2364
							&& OS.GetKeyState (OS.VK_MENU) >= 0) {
2365
						processSegments = !ignoreCharacter;
2366
					}
2367
					result = wmChar (hwnd, wParam, lParam); break;
2050
				case OS.WM_IME_CHAR:	result = wmIMEChar (hwnd, wParam, lParam); break;
2368
				case OS.WM_IME_CHAR:	result = wmIMEChar (hwnd, wParam, lParam); break;
2051
				case OS.WM_KEYDOWN:		result = wmKeyDown (hwnd, wParam, lParam); break;
2369
				case OS.WM_KEYDOWN:
2370
					if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2371
						switch (wParam) {
2372
							case OS.VK_DELETE:
2373
								processSegments = true;
2374
								break;
2375
							case OS.VK_RIGHT:
2376
							case OS.VK_LEFT:
2377
								processSegments = segments != null && OS.GetKeyState (OS.VK_MENU) >= 0;
2378
								break;
2379
						}
2380
					}
2381
					result = wmKeyDown (hwnd, wParam, lParam); break;
2052
				case OS.WM_KEYUP:		result = wmKeyUp (hwnd, wParam, lParam); break;
2382
				case OS.WM_KEYUP:		result = wmKeyUp (hwnd, wParam, lParam); break;
2053
				case OS.WM_SYSCHAR:		result = wmSysChar (hwnd, wParam, lParam); break;
2383
				case OS.WM_SYSCHAR:		result = wmSysChar (hwnd, wParam, lParam); break;
2054
				case OS.WM_SYSKEYDOWN:	result = wmSysKeyDown (hwnd, wParam, lParam); break;
2384
				case OS.WM_SYSKEYDOWN:	result = wmSysKeyDown (hwnd, wParam, lParam); break;
Lines 2080-2088 Link Here
2080
				case OS.WM_CONTEXTMENU:		result = wmContextMenu (hwnd, wParam, lParam); break;
2410
				case OS.WM_CONTEXTMENU:		result = wmContextMenu (hwnd, wParam, lParam); break;
2081
					
2411
					
2082
				/* Clipboard messages */
2412
				/* Clipboard messages */
2413
				case OS.WM_COPY: {
2414
					processSegments = segments != null;
2415
					break;
2416
				}
2083
				case OS.WM_CLEAR:
2417
				case OS.WM_CLEAR:
2084
				case OS.WM_CUT:
2418
				case OS.WM_CUT:
2085
				case OS.WM_PASTE:
2419
				case OS.WM_PASTE:
2420
					processSegments = hooks (SWT.GetSegments) || filters (SWT.GetSegments);
2086
				case OS.WM_UNDO:
2421
				case OS.WM_UNDO:
2087
				case OS.EM_UNDO:
2422
				case OS.EM_UNDO:
2088
				case OS.WM_SETTEXT:
2423
				case OS.WM_SETTEXT:
Lines 2092-2124 Link Here
2092
					break;
2427
					break;
2093
			}
2428
			}
2094
			if (result != null) return result.value;
2429
			if (result != null) return result.value;
2430
2431
			if (processSegments) {
2432
				if (getDrawing () && OS.IsWindowVisible (hwndText)) {
2433
					redraw = true;
2434
					OS.DefWindowProc (hwndText, OS.WM_SETREDRAW, 0, 0);
2435
				}
2436
				clearSegments (true);
2437
				int code = callWindowProc (hwnd, msg, wParam, lParam);
2438
				applySegments ();
2439
				if (redraw) {
2440
					OS.DefWindowProc (hwndText, OS.WM_SETREDRAW, 1, 0);
2441
					if (OS.IsWinCE) {
2442
						OS.InvalidateRect (hwndText, null, true);
2443
					} else {
2444
						OS.RedrawWindow (hwndText, null, 0, OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE); 
2445
					}
2446
				}
2447
				return code;
2448
			}
2095
			return callWindowProc (hwnd, msg, wParam, lParam);
2449
			return callWindowProc (hwnd, msg, wParam, lParam);
2096
		}
2450
		}
2097
	}
2451
	}
2098
	if (msg == OS.CB_SETCURSEL) {
2452
	switch (msg) {
2099
		if ((style & SWT.READ_ONLY) != 0) {
2453
		case OS.CB_SETCURSEL: {
2100
			if (hooks (SWT.Verify) || filters (SWT.Verify)) {
2454
			int code = OS.CB_ERR;
2101
				String oldText = getText (), newText = null;
2455
			int index = wParam;
2102
				if (wParam == -1) {
2456
			if ((style & SWT.READ_ONLY) != 0) {
2103
					newText = "";
2457
				if (hooks (SWT.Verify) || filters (SWT.Verify)) {
2104
				} else {
2458
					String oldText = getText (), newText = null;
2105
					if (0 <= wParam && wParam < getItemCount ()) {
2459
					if (wParam == -1) {
2106
						newText = getItem ((int)/*64*/wParam);
2460
						newText = "";
2461
					} else {
2462
						if (0 <= wParam && wParam < getItemCount ()) {
2463
							newText = getItem ((int)/*64*/wParam);
2464
						}
2107
					}
2465
					}
2108
				}
2466
					if (newText != null && !newText.equals (oldText)) {
2109
				if (newText != null && !newText.equals (oldText)) {
2467
						int length = OS.GetWindowTextLength (handle);
2110
					int length = OS.GetWindowTextLength (handle);
2468
						oldText = newText;
2111
					oldText = newText;
2469
						newText = verifyText (newText, 0, length, null);
2112
					newText = verifyText (newText, 0, length, null);
2470
						if (newText == null) return 0;
2113
					if (newText == null) return 0;
2471
						if (!newText.equals (oldText)) {
2114
					if (!newText.equals (oldText)) {
2472
							index = indexOf (newText);
2115
						int index = indexOf (newText);
2473
							if (index != -1 && index != wParam) {
2116
						if (index != -1 && index != wParam) {
2474
								code = callWindowProc (handle, OS.CB_SETCURSEL, index, lParam);
2117
							return callWindowProc (handle, OS.CB_SETCURSEL, index, lParam);
2475
								break;
2476
							}
2118
						}
2477
						}
2119
					}
2478
					}
2120
				}
2479
				}
2121
			}
2480
			}
2481
			if (index == -1 || index == wParam) {
2482
				code = super.windowProc (hwnd, msg, wParam, lParam);
2483
			}
2484
			if (code != OS.CB_ERR && code != OS.CB_ERRSPACE && (hooks (SWT.GetSegments) || filters (SWT.GetSegments))) {
2485
				int nSegments = segments == null ? 0 : segments.length;
2486
				int delta = 0;
2487
				segments = itemSegments == null ? null : itemSegments [index];
2488
				delta = segments == null ? nSegments : nSegments - segments.length;
2489
				if (delta != 0) {
2490
					int /*long*/ hwndText = OS.GetDlgItem (handle, CBID_EDIT);
2491
					int/*64*/ limit = (int/*64*/)OS.SendMessage (hwndText, OS.EM_GETLIMITTEXT, 0, 0) & 0x7fffffff;
2492
				 	if (limit < LIMIT) {
2493
						OS.SendMessage (hwndText, OS.EM_SETLIMITTEXT, Math.max (1, limit - delta), 0);
2494
					}
2495
				}
2496
			}
2497
			return code;
2498
		}
2499
		case OS.CB_ADDSTRING:
2500
		case OS.CB_INSERTSTRING:
2501
		case OS.CB_FINDSTRINGEXACT: {
2502
			// XXX For CB_FINDSTRINGEXACT a neater approach is probably to
2503
			// normalize items rather than process the search key
2504
			if (lParam != 0 && (hooks (SWT.GetSegments) || filters (SWT.GetSegments))) {
2505
				int length = OS.IsUnicode ? OS.wcslen (lParam) : OS.strlen (lParam);
2506
				TCHAR buffer = new TCHAR (getCodePage (), length);
2507
				OS.MoveMemory (buffer, lParam, buffer.length () * TCHAR.sizeof);
2508
				String string = buffer.toString (0, length);
2509
				Event event = getSegments (string);
2510
				if (event != null && event.segments != null) {
2511
					buffer = new TCHAR (getCodePage (), getSegmentsText (string, event), true);
2512
					int /*long*/ hHeap = OS.GetProcessHeap ();
2513
					length = buffer.length() * TCHAR.sizeof;
2514
					int /*long*/ pszText = OS.HeapAlloc (hHeap, OS.HEAP_ZERO_MEMORY, length);
2515
					OS.MoveMemory (pszText, buffer, length); 
2516
					int code = super.windowProc (hwnd, msg, wParam, pszText);
2517
					OS.HeapFree (hHeap, 0, pszText);
2518
					if (msg != OS.CB_FINDSTRINGEXACT && code != OS.CB_ERR && code != OS.CB_ERRSPACE) {
2519
						insertItemSegments (event.segments, code);
2520
					}
2521
					return code;
2522
				}
2523
			}
2524
			break;
2525
		}
2526
		case OS.CB_DELETESTRING: {
2527
			if (itemSegments != null) {
2528
				int code = super.windowProc (hwnd, msg, wParam, lParam);
2529
				if (code != OS.CB_ERR && code != OS.CB_ERRSPACE) {
2530
					removeItemSegments (wParam);
2531
					if (wParam == getSelectionIndex()) {
2532
						clearSegments (false);
2533
					}
2534
				}
2535
				return code;
2536
			}
2537
			break;
2538
		}
2539
		case OS.CB_RESETCONTENT: {
2540
			if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2541
				if (segments != null) clearSegments (false);
2542
				itemSegments = null;
2543
			}
2544
			break;
2122
		}
2545
		}
2123
	}
2546
	}
2124
	return super.windowProc (hwnd, msg, wParam, lParam);
2547
	return super.windowProc (hwnd, msg, wParam, lParam);
Lines 2478-2483 Link Here
2478
				}
2901
				}
2479
				OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits1);
2902
				OS.SetWindowLong (hwnd, OS.GWL_EXSTYLE, bits1);
2480
				OS.SetWindowLong (hwnd, OS.GWL_STYLE, bits2);
2903
				OS.SetWindowLong (hwnd, OS.GWL_STYLE, bits2);
2904
			} else if (hooks (SWT.GetSegments) || filters (SWT.GetSegments)) {
2905
				applySegments ();
2481
			}
2906
			}
2482
			break;
2907
			break;
2483
	}
2908
	}
(-)Eclipse SWT/win32/org/eclipse/swt/widgets/Text.java (-6 / +384 lines)
Lines 58-64 Link Here
58
	int tabs, oldStart, oldEnd;
58
	int tabs, oldStart, oldEnd;
59
	boolean doubleClick, ignoreModify, ignoreVerify, ignoreCharacter;
59
	boolean doubleClick, ignoreModify, ignoreVerify, ignoreCharacter;
60
	String message;
60
	String message;
61
	int[] segments;
61
	
62
	
63
	String saveText = "";
64
65
	// XXX The following two variables are also required for other widgets, move them to some shared space
66
	static final char LTR_MARK = '\u200e';
67
	static final char RTL_MARK = '\u200f';
68
62
	/**
69
	/**
63
	* The maximum number of characters that can be entered
70
	* The maximum number of characters that can be entered
64
	* into a text widget.
71
	* into a text widget.
Lines 251-256 Link Here
251
			}
258
			}
252
			break;
259
			break;
253
		}
260
		}
261
		case OS.WM_KEYDOWN: {
262
			switch (wParam) {
263
				case OS.VK_RIGHT:
264
				case OS.VK_LEFT:
265
					if (OS.GetKeyState(OS.VK_MENU) < 0) break;
266
					// else FALL THROUGH
267
				case OS.VK_DELETE: {
268
					if (segments != null) {
269
						clearSegments(true);
270
					}
271
					break;
272
				}
273
			}
274
			break;
275
		}
276
		case OS.WM_CHAR: {
277
			if (!ignoreCharacter && segments != null && OS.GetKeyState(OS.VK_CONTROL) >= 0 && OS.GetKeyState(OS.VK_MENU) >= 0) {
278
				clearSegments(true);
279
			}
280
			break;
281
		}
254
	}
282
	}
255
	int /*long*/ code = OS.CallWindowProc (EditProc, hwnd, msg, wParam, lParam);
283
	int /*long*/ code = OS.CallWindowProc (EditProc, hwnd, msg, wParam, lParam);
256
	switch (msg) {
284
	switch (msg) {
Lines 304-309 Link Here
304
332
305
/**
333
/**
306
 * Adds the listener to the collection of listeners who will
334
 * Adds the listener to the collection of listeners who will
335
 * be notified when the receiver's text is verified, by sending
336
 * it one of the messages defined in the <code>SegmentListener</code>
337
 * interface.
338
 *
339
 * @param listener the listener which should be notified
340
 *
341
 * @exception IllegalArgumentException <ul>
342
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
343
 * </ul>
344
 * @exception SWTException <ul>
345
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
346
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
347
 * </ul>
348
 *
349
 * @see SegmentListener
350
 * @see #removeSegmentListener
351
 */
352
public void addSegmentListener (SegmentListener listener) {
353
	checkWidget ();
354
	if (listener == null) error (SWT.ERROR_NULL_ARGUMENT);
355
	clearSegments(true);
356
	addListener(SWT.GetSegments, new TypedListener(listener));
357
	applySegments();
358
}
359
360
/**
361
 * Adds the listener to the collection of listeners who will
307
 * be notified when the control is selected by the user, by sending
362
 * be notified when the control is selected by the user, by sending
308
 * it one of the messages defined in the <code>SelectionListener</code>
363
 * it one of the messages defined in the <code>SelectionListener</code>
309
 * interface.
364
 * interface.
Lines 383-388 Link Here
383
	checkWidget ();
438
	checkWidget ();
384
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
439
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
385
	string = Display.withCrLf (string);
440
	string = Display.withCrLf (string);
441
	if (segments != null) clearSegments(true);
386
	int length = OS.GetWindowTextLength (handle);
442
	int length = OS.GetWindowTextLength (handle);
387
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
443
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
388
		string = verifyText (string, length, length, null);
444
		string = verifyText (string, length, length, null);
Lines 405-410 Link Here
405
	OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer);
461
	OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer);
406
	ignoreCharacter = false;
462
	ignoreCharacter = false;
407
	OS.SendMessage (handle, OS.EM_SCROLLCARET, 0, 0);
463
	OS.SendMessage (handle, OS.EM_SCROLLCARET, 0, 0);
464
	if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
465
		saveText = "";
466
		applySegments();
467
	}
468
}
469
470
void applySegments() {
471
	/*
472
	 * It's possible that while handling one event, another event that implies
473
	 * removal and addition of segments was fired. So we need to make sure that
474
	 * segments (if any) are cleared before the current apply operation
475
	 */
476
	if (segments != null) clearSegments(true);
477
	checkWidget ();
478
	int length = OS.GetWindowTextLength (handle);
479
	int cp = getCodePage ();
480
	TCHAR buffer = new TCHAR (cp, length + 1);
481
	if (length > 0) OS.GetWindowText (handle, buffer, length + 1);
482
	String string = buffer.toString (0, length);
483
	Point selection = getSelection();
484
	string = getSegmentsText (string);
485
	if (segments != null && segments.length > 0) {
486
		boolean oldIgnoreCharacter = ignoreCharacter, oldIgnoreModify = ignoreModify, oldIgnoreVerify = ignoreVerify;
487
		ignoreCharacter = ignoreModify = ignoreVerify = true;
488
		/*
489
		 * SetWindowText empties the undo buffer and disables further undo
490
		 * operations. Sending OS.EM_REPLACESEL message.
491
		 */
492
		buffer = new TCHAR (cp, string, true);
493
		OS.SendMessage(handle, OS.EM_SETSEL, 0, -1);
494
		if (OS.SendMessage (handle, OS.EM_CANUNDO, 0, 0) != 0) {
495
			OS.SendMessage(handle, OS.EM_REPLACESEL, 1, new TCHAR(cp, saveText, true));
496
			OS.SendMessage(handle, OS.EM_SETSEL, 0, -1);
497
			OS.SendMessage(handle, OS.EM_REPLACESEL, 1, buffer);
498
		} else {
499
			OS.SendMessage(handle, OS.EM_REPLACESEL, 1, buffer);
500
		}
501
		setSelection(selection);
502
		ignoreCharacter = oldIgnoreCharacter;
503
		ignoreModify = oldIgnoreModify;
504
		ignoreVerify = oldIgnoreVerify;
505
	}
408
}
506
}
409
507
410
static int checkStyle (int style) {
508
static int checkStyle (int style) {
Lines 432-437 Link Here
432
	return style | SWT.SINGLE;
530
	return style | SWT.SINGLE;
433
}
531
}
434
532
533
void clearSegments(boolean applyText) {
534
	checkWidget ();
535
	if (segments == null) return;
536
	int nSegments = segments.length;
537
	if (nSegments == 0) return;
538
	int/*64*/ limit = (int/*64*/)OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7fffffff;
539
	if (limit < LIMIT) {
540
		OS.SendMessage (handle, OS.EM_SETLIMITTEXT, Math.max(1, limit - nSegments), 0);
541
	}
542
	if (!applyText) {
543
		segments = null;
544
		return;
545
	}
546
	boolean oldIgnoreCharacter = ignoreCharacter, oldIgnoreModify = ignoreModify, oldIgnoreVerify = ignoreVerify;
547
	ignoreCharacter = ignoreModify = ignoreVerify = true;
548
	int length = OS.GetWindowTextLength (handle);
549
	int cp = getCodePage ();
550
	TCHAR buffer = new TCHAR (cp, length + 1);
551
	if (length > 0) OS.GetWindowText (handle, buffer, length + 1);
552
	Point selection = getSelection();
553
	String string = deprocessText(buffer.toString (0, length), 0);
554
	segments = null;
555
	buffer = new TCHAR (cp, string, true);
556
	/*
557
	 * SetWindowText empties the undo buffer and disables further undo
558
	 * operations. Sending OS.EM_REPLACESEL message.
559
	 */
560
	OS.SendMessage(handle, OS.EM_SETSEL, 0, -1);
561
	if (OS.SendMessage (handle, OS.EM_CANUNDO, 0, 0) != 0) {
562
		//OS.SendMessage(handle, OS.EM_REPLACESEL, 1, new TCHAR(cp, "", true));
563
		OS.SendMessage(handle, OS.EM_REPLACESEL, 1, buffer);
564
	} else {
565
		OS.SendMessage(handle, OS.EM_REPLACESEL, 0, buffer);
566
	}
567
	setSelection(selection);
568
	ignoreCharacter = oldIgnoreCharacter;
569
	ignoreModify = oldIgnoreModify;
570
	ignoreVerify = oldIgnoreVerify;
571
}
572
435
/**
573
/**
436
 * Clears the selection.
574
 * Clears the selection.
437
 *
575
 *
Lines 574-579 Link Here
574
	return OS.GetSysColor ((bits & OS.ES_READONLY) != 0 ? OS.COLOR_3DFACE : OS.COLOR_WINDOW);
712
	return OS.GetSysColor ((bits & OS.ES_READONLY) != 0 ? OS.COLOR_3DFACE : OS.COLOR_WINDOW);
575
}
713
}
576
714
715
String deprocessText(String text, int start) {
716
	if (text == null || segments == null) return text;
717
	int length = text.length();
718
	if (length == 0) return text;
719
	int nSegments = segments.length;
720
	if (nSegments == 0) return text;
721
	if (start > segments[nSegments - 1] || start + length <= segments[0]) return text;
722
	char[] oldChars = new char[length];
723
	text.getChars(0, length, oldChars, 0);
724
	char[] newChars = new char[length];
725
	int nLeadSegments = 0;
726
	while (start - nLeadSegments > segments[nLeadSegments]) nLeadSegments++;
727
	int segmentCount = nLeadSegments;
728
	for (int i = 0; i < length; i++) {
729
		if (segmentCount < nSegments && i + start - segmentCount == segments[segmentCount]) {
730
			++segmentCount;
731
		} else {
732
			newChars[i - segmentCount + nLeadSegments] = oldChars[i];
733
		}
734
	}
735
	return new String(newChars, 0, newChars.length - segmentCount + nLeadSegments);
736
}
737
577
boolean dragDetect (int /*long*/ hwnd, int x, int y, boolean filter, boolean [] detect, boolean [] consume) {
738
boolean dragDetect (int /*long*/ hwnd, int x, int y, boolean filter, boolean [] detect, boolean [] consume) {
578
	if (filter) {
739
	if (filter) {
579
		int [] start = new int [1], end = new int [1];
740
		int [] start = new int [1], end = new int [1];
Lines 706-711 Link Here
706
	* pixel coordinates (0,0). 
867
	* pixel coordinates (0,0). 
707
	*/
868
	*/
708
	int position = getCaretPosition ();
869
	int position = getCaretPosition ();
870
	if (segments != null) position = translateOffset (position);
709
	int /*long*/ caretPos = OS.SendMessage (handle, OS.EM_POSFROMCHAR, position, 0);
871
	int /*long*/ caretPos = OS.SendMessage (handle, OS.EM_POSFROMCHAR, position, 0);
710
	if (caretPos == -1) {
872
	if (caretPos == -1) {
711
		caretPos = 0;
873
		caretPos = 0;
Lines 798-803 Link Here
798
		}
960
		}
799
	}
961
	}
800
	if (!OS.IsUnicode && OS.IsDBLocale) caret = mbcsToWcsPos (caret);
962
	if (!OS.IsUnicode && OS.IsDBLocale) caret = mbcsToWcsPos (caret);
963
	if (segments != null) caret = untranslateOffset (caret);
801
	return caret;
964
	return caret;
802
}
965
}
803
966
Lines 815-820 Link Here
815
	checkWidget ();
978
	checkWidget ();
816
	int length = OS.GetWindowTextLength (handle);
979
	int length = OS.GetWindowTextLength (handle);
817
	if (!OS.IsUnicode && OS.IsDBLocale) length = mbcsToWcsPos (length);
980
	if (!OS.IsUnicode && OS.IsDBLocale) length = mbcsToWcsPos (length);
981
	if (segments != null) length -= segments.length;
818
	return length;
982
	return length;
819
}
983
}
820
984
Lines 996-1004 Link Here
996
	int /*long*/ lParam = OS.MAKELPARAM (point.x, point.y);
1160
	int /*long*/ lParam = OS.MAKELPARAM (point.x, point.y);
997
	int position = OS.LOWORD (OS.SendMessage (handle, OS.EM_CHARFROMPOS, 0, lParam));
1161
	int position = OS.LOWORD (OS.SendMessage (handle, OS.EM_CHARFROMPOS, 0, lParam));
998
	if (!OS.IsUnicode && OS.IsDBLocale) position = mbcsToWcsPos (position);
1162
	if (!OS.IsUnicode && OS.IsDBLocale) position = mbcsToWcsPos (position);
1163
	if (segments != null) position = untranslateOffset(position);
999
	return position;
1164
	return position;
1000
}
1165
}
1001
1166
1167
String getSegmentsText(String text) {
1168
	if (!hooks(SWT.GetSegments) && !filters(SWT.GetSegments)) return text;
1169
	Event event = new Event();
1170
	event.text = text;
1171
	event.segments = segments;
1172
	sendEvent(SWT.GetSegments, event);
1173
	segments = event.segments;
1174
	if (segments == null) return text;
1175
	int nSegments = segments.length;
1176
	if (nSegments == 0) return text;
1177
1178
	for (int i = 1, lineLength = text == null ? 0 : text.length(); i < nSegments; i++) {
1179
		if (event.segments[i] < event.segments[i - 1] || event.segments[i] > lineLength) {
1180
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
1181
		}
1182
	}
1183
	int/*64*/ limit = (int/*64*/)OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7fffffff;
1184
	OS.SendMessage (handle, OS.EM_SETLIMITTEXT, limit + Math.min(nSegments, LIMIT - limit), 0);
1185
	char[] segmentsChars = event.segmentsChars;
1186
	int length = text.length();
1187
	char[] oldChars = new char[length];
1188
	text.getChars(0, length, oldChars, 0);
1189
	char[] newChars = new char[length + nSegments];
1190
	int charCount = 0, segmentCount = 0;
1191
	char defaultSeparator = getOrientation() == SWT.RIGHT_TO_LEFT ? RTL_MARK : LTR_MARK;
1192
	while (charCount < length) {
1193
		if (segmentCount < nSegments && charCount == segments[segmentCount]) {
1194
			char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars[segmentCount] : defaultSeparator;
1195
			newChars[charCount + segmentCount++] = separator;
1196
		} else {
1197
			newChars[charCount + segmentCount] = oldChars[charCount++];
1198
		}
1199
	}
1200
	while (segmentCount < nSegments) {
1201
		segments[segmentCount] = charCount;
1202
		char separator = segmentsChars != null && segmentsChars.length > segmentCount ? segmentsChars[segmentCount] : defaultSeparator;
1203
		newChars[charCount + segmentCount++] = separator;
1204
	}
1205
	return new String(newChars, 0, newChars.length);
1206
}
1207
1002
/**
1208
/**
1003
 * Returns a <code>Point</code> whose x coordinate is the
1209
 * Returns a <code>Point</code> whose x coordinate is the
1004
 * character position representing the start of the selected
1210
 * character position representing the start of the selected
Lines 1025-1030 Link Here
1025
		start [0] = mbcsToWcsPos (start [0]);
1231
		start [0] = mbcsToWcsPos (start [0]);
1026
		end [0] = mbcsToWcsPos (end [0]);
1232
		end [0] = mbcsToWcsPos (end [0]);
1027
	}
1233
	}
1234
	if (segments != null) {
1235
		if (start[0] == end[0]) {
1236
			start [0] = end [0] = untranslateOffset (start [0]);
1237
		}
1238
		else {
1239
			start [0] = untranslateOffset (start [0]);
1240
			end [0] = untranslateOffset (end [0]);
1241
		}
1242
	}
1028
	return new Point (start [0], end [0]);
1243
	return new Point (start [0], end [0]);
1029
}
1244
}
1030
1245
Lines 1063-1068 Link Here
1063
	if (start [0] == end [0]) return "";
1278
	if (start [0] == end [0]) return "";
1064
	TCHAR buffer = new TCHAR (getCodePage (), length + 1);
1279
	TCHAR buffer = new TCHAR (getCodePage (), length + 1);
1065
	OS.GetWindowText (handle, buffer, length + 1);
1280
	OS.GetWindowText (handle, buffer, length + 1);
1281
	if (segments != null) {
1282
		String text = buffer.toString (start [0], end [0] - start [0]);
1283
		return deprocessText(text, start [0]);
1284
	}
1066
	return buffer.toString (start [0], end [0] - start [0]);
1285
	return buffer.toString (start [0], end [0] - start [0]);
1067
}
1286
}
1068
1287
Lines 1120-1126 Link Here
1120
	if (length == 0) return "";
1339
	if (length == 0) return "";
1121
	TCHAR buffer = new TCHAR (getCodePage (), length + 1);
1340
	TCHAR buffer = new TCHAR (getCodePage (), length + 1);
1122
	OS.GetWindowText (handle, buffer, length + 1);
1341
	OS.GetWindowText (handle, buffer, length + 1);
1123
	return buffer.toString (0, length);
1342
	String text = buffer.toString (0, length); 
1343
	if (segments != null) {
1344
		return deprocessText(text, 0);
1345
	}
1346
	return text;
1124
}
1347
}
1125
1348
1126
/**
1349
/**
Lines 1147-1152 Link Here
1147
	OS.GetWindowText (handle, buffer, length + 1);
1370
	OS.GetWindowText (handle, buffer, length + 1);
1148
	char [] chars = new char [length];
1371
	char [] chars = new char [length];
1149
	System.arraycopy (buffer.chars, 0, chars, 0, length);
1372
	System.arraycopy (buffer.chars, 0, chars, 0, length);
1373
	if (segments != null) return (deprocessText (buffer.toString(), 0)).toCharArray ();
1150
	return chars;
1374
	return chars;
1151
}
1375
}
1152
1376
Lines 1173-1178 Link Here
1173
	if (!(start <= end && 0 <= end)) return "";
1397
	if (!(start <= end && 0 <= end)) return "";
1174
	int length = OS.GetWindowTextLength (handle);
1398
	int length = OS.GetWindowTextLength (handle);
1175
	if (!OS.IsUnicode && OS.IsDBLocale) length = mbcsToWcsPos (length);
1399
	if (!OS.IsUnicode && OS.IsDBLocale) length = mbcsToWcsPos (length);
1400
	if (segments != null) length -= segments.length;
1176
	end = Math.min (end, length - 1);
1401
	end = Math.min (end, length - 1);
1177
	if (start > end) return "";
1402
	if (start > end) return "";
1178
	start = Math.max (0, start);
1403
	start = Math.max (0, start);
Lines 1202-1208 Link Here
1202
 */
1427
 */
1203
public int getTextLimit () {
1428
public int getTextLimit () {
1204
	checkWidget ();
1429
	checkWidget ();
1205
	return (int)/*64*/OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
1430
	int/*64*/ limit = (int)/*64*/OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
1431
	if (segments != null && limit < LIMIT) limit = Math.max(1, limit - segments.length);
1432
	return limit;
1206
}
1433
}
1207
1434
1208
/**
1435
/**
Lines 1278-1283 Link Here
1278
	checkWidget ();
1505
	checkWidget ();
1279
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1506
	if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
1280
	string = Display.withCrLf (string);
1507
	string = Display.withCrLf (string);
1508
	if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
1509
		clearSegments(true);
1510
		saveText = "";
1511
	}
1281
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
1512
	if (hooks (SWT.Verify) || filters (SWT.Verify)) {
1282
		int [] start = new int [1], end = new int [1];
1513
		int [] start = new int [1], end = new int [1];
1283
		OS.SendMessage (handle, OS.EM_GETSEL, start, end);
1514
		OS.SendMessage (handle, OS.EM_GETSEL, start, end);
Lines 1299-1304 Link Here
1299
	ignoreCharacter = true;
1530
	ignoreCharacter = true;
1300
	OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer);
1531
	OS.SendMessage (handle, OS.EM_REPLACESEL, 0, buffer);
1301
	ignoreCharacter = false;
1532
	ignoreCharacter = false;
1533
	if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
1534
		applySegments();
1535
	}
1302
}
1536
}
1303
1537
1304
int mbcsToWcsPos (int mbcsPos) {
1538
int mbcsToWcsPos (int mbcsPos) {
Lines 1390-1395 Link Here
1390
1624
1391
/**
1625
/**
1392
 * Removes the listener from the collection of listeners who will
1626
 * Removes the listener from the collection of listeners who will
1627
 * be notified when the receiver's text is modified.
1628
 *
1629
 * @param listener the listener which should no longer be notified
1630
 *
1631
 * @exception IllegalArgumentException <ul>
1632
 *    <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
1633
 * </ul>
1634
 * @exception SWTException <ul>
1635
 *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
1636
 *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
1637
 * </ul>
1638
 *
1639
 * @see SegmentListener
1640
 * @see #addSegmentListener
1641
 */
1642
public void removeSegmentListener(SegmentListener listener) {
1643
	checkWidget();
1644
	if (listener == null) SWT.error(SWT.ERROR_NULL_ARGUMENT);
1645
	clearSegments(true);
1646
	eventTable.unhook (SWT.GetSegments, listener);
1647
	applySegments();
1648
}
1649
1650
/**
1651
 * Removes the listener from the collection of listeners who will
1393
 * be notified when the control is selected by the user.
1652
 * be notified when the control is selected by the user.
1394
 *
1653
 *
1395
 * @param listener the listener which should no longer be notified
1654
 * @param listener the listener which should no longer be notified
Lines 1829-1834 Link Here
1829
 */
2088
 */
1830
public void setSelection (int start) {
2089
public void setSelection (int start) {
1831
	checkWidget ();
2090
	checkWidget ();
2091
	if (segments != null) start = translateOffset(start);
1832
	if (!OS.IsUnicode && OS.IsDBLocale) start = wcsToMbcsPos (start);
2092
	if (!OS.IsUnicode && OS.IsDBLocale) start = wcsToMbcsPos (start);
1833
	OS.SendMessage (handle, OS.EM_SETSEL, start, start);
2093
	OS.SendMessage (handle, OS.EM_SETSEL, start, start);
1834
	OS.SendMessage (handle, OS.EM_SCROLLCARET, 0, 0);
2094
	OS.SendMessage (handle, OS.EM_SCROLLCARET, 0, 0);
Lines 1861-1866 Link Here
1861
 */
2121
 */
1862
public void setSelection (int start, int end) {
2122
public void setSelection (int start, int end) {
1863
	checkWidget ();
2123
	checkWidget ();
2124
	if (segments != null) {
2125
		if (start == end) {
2126
			start = end = translateOffset(start);
2127
		} else {
2128
			start = translateOffset(start);
2129
			end = translateOffset(end);
2130
		}
2131
	}
1864
	if (!OS.IsUnicode && OS.IsDBLocale) {
2132
	if (!OS.IsUnicode && OS.IsDBLocale) {
1865
		start = wcsToMbcsPos (start);
2133
		start = wcsToMbcsPos (start);
1866
		end = wcsToMbcsPos (end);
2134
		end = wcsToMbcsPos (end);
Lines 1982-1991 Link Here
1982
		string = verifyText (string, 0, length, null);
2250
		string = verifyText (string, 0, length, null);
1983
		if (string == null) return;
2251
		if (string == null) return;
1984
	}
2252
	}
2253
	if (segments != null) clearSegments(false);
1985
	int limit = (int)/*64*/OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
2254
	int limit = (int)/*64*/OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
1986
	if (string.length () > limit) string = string.substring (0, limit);
2255
	if (string.length () > limit) string = string.substring (0, limit);
1987
	TCHAR buffer = new TCHAR (getCodePage (), string, true);
2256
	TCHAR buffer = new TCHAR (getCodePage (), string, true);
1988
	OS.SetWindowText (handle, buffer);
2257
	OS.SetWindowText (handle, buffer);
2258
	if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
2259
		applySegments();
2260
	}
1989
	/*
2261
	/*
1990
	* Bug in Windows.  When the widget is multi line
2262
	* Bug in Windows.  When the widget is multi line
1991
	* text widget, it does not send a WM_COMMAND with
2263
	* text widget, it does not send a WM_COMMAND with
Lines 2028-2033 Link Here
2028
		text = new char [string.length()];
2300
		text = new char [string.length()];
2029
		string.getChars (0, text.length, text, 0);
2301
		string.getChars (0, text.length, text, 0);
2030
	}
2302
	}
2303
	if (segments != null) clearSegments(false);
2031
	int limit = (int)/*64*/OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
2304
	int limit = (int)/*64*/OS.SendMessage (handle, OS.EM_GETLIMITTEXT, 0, 0) & 0x7FFFFFFF;
2032
	if (text.length > limit) {
2305
	if (text.length > limit) {
2033
		char [] temp = new char [limit];
2306
		char [] temp = new char [limit];
Lines 2036-2041 Link Here
2036
	}
2309
	}
2037
	TCHAR buffer = new TCHAR (getCodePage (), text, true);
2310
	TCHAR buffer = new TCHAR (getCodePage (), text, true);
2038
	OS.SetWindowText (handle, buffer);
2311
	OS.SetWindowText (handle, buffer);
2312
	if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
2313
		applySegments();
2314
	}
2039
	/*
2315
	/*
2040
	* Bug in Windows.  When the widget is multi line
2316
	* Bug in Windows.  When the widget is multi line
2041
	* text widget, it does not send a WM_COMMAND with
2317
	* text widget, it does not send a WM_COMMAND with
Lines 2077-2083 Link Here
2077
public void setTextLimit (int limit) {
2353
public void setTextLimit (int limit) {
2078
	checkWidget ();
2354
	checkWidget ();
2079
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
2355
	if (limit == 0) error (SWT.ERROR_CANNOT_BE_ZERO);
2080
	OS.SendMessage (handle, OS.EM_SETLIMITTEXT, limit, 0);
2356
	if (segments != null && limit > 0) {
2357
		OS.SendMessage (handle, OS.EM_SETLIMITTEXT, limit + Math.min(segments.length, LIMIT - limit), 0);
2358
	} else {
2359
		OS.SendMessage (handle, OS.EM_SETLIMITTEXT, limit, 0);
2360
	}
2081
}
2361
}
2082
2362
2083
/**
2363
/**
Lines 2119-2124 Link Here
2119
	OS.SendMessage (handle, OS.EM_SCROLLCARET, 0, 0);
2399
	OS.SendMessage (handle, OS.EM_SCROLLCARET, 0, 0);
2120
}
2400
}
2121
2401
2402
int translateOffset(int offset) {
2403
	if (segments == null) return offset;
2404
	for (int i = 0, nSegments = segments.length; i < nSegments && offset - i >= segments[i]; i++) {
2405
		offset++;
2406
	}	
2407
	return offset;
2408
}
2409
2410
int untranslateOffset(int offset) {
2411
	if (segments == null) return offset;
2412
	for (int i = 0, nSegments = segments.length; i < nSegments && offset > segments[i]; i++) {
2413
		offset--;
2414
	}
2415
	return offset;
2416
}
2417
2122
String verifyText (String string, int start, int end, Event keyEvent) {
2418
String verifyText (String string, int start, int end, Event keyEvent) {
2123
	if (ignoreVerify) return string;
2419
	if (ignoreVerify) return string;
2124
	Event event = new Event ();
2420
	Event event = new Event ();
Lines 2231-2236 Link Here
2231
}
2527
}
2232
2528
2233
int /*long*/ windowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
2529
int /*long*/ windowProc (int /*long*/ hwnd, int msg, int /*long*/ wParam, int /*long*/ lParam) {
2530
	boolean processSegments = false, redraw = false;
2531
	String oldText = null;
2532
	int length = -1;
2533
	int code;
2534
	if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
2535
		switch (msg) {
2536
			case OS.EM_UNDO:
2537
			case OS.WM_UNDO: {
2538
				length = getCharCount();
2539
				segments = null;
2540
				processSegments = true;
2541
				break;
2542
			}
2543
			case OS.WM_KEYDOWN: {
2544
				switch (wParam) {
2545
					case OS.VK_DELETE: {
2546
						processSegments = true;
2547
						length = getCharCount();
2548
						break;
2549
					}
2550
					case OS.VK_RIGHT:
2551
					case OS.VK_LEFT: {
2552
						processSegments = segments != null && OS.GetKeyState(OS.VK_MENU) >= 0;
2553
						break;
2554
					}
2555
				}
2556
				break;
2557
			}
2558
			case OS.WM_COPY: {
2559
				processSegments = segments != null;
2560
				break;
2561
			}
2562
			case OS.WM_CHAR: {
2563
				if (OS.GetKeyState(OS.VK_CONTROL) >= 0 && OS.GetKeyState(OS.VK_MENU) >= 0) {
2564
					processSegments = !ignoreCharacter;
2565
					if (wParam == SWT.BS) length = getCharCount();
2566
				}
2567
				break;
2568
			}
2569
			case OS.WM_PASTE:
2570
			case OS.WM_CUT:
2571
			case OS.WM_CLEAR: {
2572
				processSegments = true;
2573
				length = getCharCount();
2574
				break;
2575
			}
2576
		}
2577
	}
2578
	if (processSegments) {
2579
		if (getDrawing () && OS.IsWindowVisible (handle)) {
2580
			redraw = true;
2581
			OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0);
2582
		}
2583
		clearSegments(true);
2584
	}
2585
	if (length > -1) {
2586
		int len = OS.GetWindowTextLength (handle);
2587
		if (len == 0) oldText = "";
2588
		else {
2589
			TCHAR buffer = new TCHAR (getCodePage (), len + 1);
2590
			OS.GetWindowText (handle, buffer, len + 1);
2591
			oldText = buffer.toString (0, len);
2592
		}
2593
	}
2234
	if (msg == OS.EM_UNDO) {
2594
	if (msg == OS.EM_UNDO) {
2235
		int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
2595
		int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);
2236
		if ((bits & OS.ES_MULTILINE) == 0) {
2596
		if ((bits & OS.ES_MULTILINE) == 0) {
Lines 2238-2250 Link Here
2238
			if (result != null) return result.value;
2598
			if (result != null) return result.value;
2239
			return callWindowProc (hwnd, OS.EM_UNDO, wParam, lParam);
2599
			return callWindowProc (hwnd, OS.EM_UNDO, wParam, lParam);
2240
		}
2600
		}
2241
	}
2601
	} else if (msg == Display.SWT_RESTORECARET) {
2242
	if (msg == Display.SWT_RESTORECARET) {
2243
		callWindowProc (hwnd, OS.WM_KILLFOCUS, 0, 0);
2602
		callWindowProc (hwnd, OS.WM_KILLFOCUS, 0, 0);
2244
		callWindowProc (hwnd, OS.WM_SETFOCUS, 0, 0);
2603
		callWindowProc (hwnd, OS.WM_SETFOCUS, 0, 0);
2245
		return 1;
2604
		return 1;
2246
	}
2605
	}
2247
	return super.windowProc (hwnd, msg, wParam, lParam);
2606
	code = super.windowProc (hwnd, msg, wParam, lParam);
2607
	if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
2608
		if (length > -1 && length != getCharCount()) {
2609
			saveText = oldText;
2610
		}
2611
		if (processSegments) {
2612
			applySegments();
2613
			if (redraw) {
2614
				OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0);
2615
				if (OS.IsWinCE) {
2616
					OS.InvalidateRect (handle, null, true);
2617
				} else {
2618
					OS.RedrawWindow (handle, null, 0, OS.RDW_ERASE | OS.RDW_FRAME | OS.RDW_INVALIDATE); 
2619
				}
2620
			}
2621
		}
2622
	}
2623
	return code;
2248
}
2624
}
2249
2625
2250
LRESULT WM_CHAR (int /*long*/ wParam, int /*long*/ lParam) {
2626
LRESULT WM_CHAR (int /*long*/ wParam, int /*long*/ lParam) {
Lines 2627-2632 Link Here
2627
					style |= SWT.LEFT_TO_RIGHT;
3003
					style |= SWT.LEFT_TO_RIGHT;
2628
				}	
3004
				}	
2629
				OS.SetWindowLong (handle, OS.GWL_EXSTYLE, bits);
3005
				OS.SetWindowLong (handle, OS.GWL_EXSTYLE, bits);
3006
			} else if (hooks(SWT.GetSegments) || filters(SWT.GetSegments)) {
3007
				applySegments();
2630
			}
3008
			}
2631
			fixAlignment();
3009
			fixAlignment();
2632
			break;
3010
			break;
(-)JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Text.java (+128 lines)
Lines 17-22 Link Here
17
import org.eclipse.swt.events.*;
17
import org.eclipse.swt.events.*;
18
import org.eclipse.swt.graphics.*;
18
import org.eclipse.swt.graphics.*;
19
import org.eclipse.swt.widgets.*;
19
import org.eclipse.swt.widgets.*;
20
import org.eclipse.swt.events.SegmentListener;
20
21
21
/**
22
/**
22
 * Automated Test Suite for class org.eclipse.swt.widgets.Text
23
 * Automated Test Suite for class org.eclipse.swt.widgets.Text
Lines 1387-1392 Link Here
1387
	methodNames.addElement("test_consistency_Modify");
1388
	methodNames.addElement("test_consistency_Modify");
1388
	methodNames.addElement("test_consistency_MenuDetect");
1389
	methodNames.addElement("test_consistency_MenuDetect");
1389
	methodNames.addElement("test_consistency_DragDetect");
1390
	methodNames.addElement("test_consistency_DragDetect");
1391
	methodNames.addElement("test_consistency_Segments");
1390
	methodNames.addAll(Test_org_eclipse_swt_widgets_Scrollable.methodNames()); // add superclass method names
1392
	methodNames.addAll(Test_org_eclipse_swt_widgets_Scrollable.methodNames()); // add superclass method names
1391
	return methodNames;
1393
	return methodNames;
1392
}
1394
}
Lines 1444-1449 Link Here
1444
	else if (getName().equals("test_consistency_Modify")) test_consistency_Modify();
1446
	else if (getName().equals("test_consistency_Modify")) test_consistency_Modify();
1445
	else if (getName().equals("test_consistency_MenuDetect")) test_consistency_MenuDetect();
1447
	else if (getName().equals("test_consistency_MenuDetect")) test_consistency_MenuDetect();
1446
	else if (getName().equals("test_consistency_DragDetect")) test_consistency_DragDetect();
1448
	else if (getName().equals("test_consistency_DragDetect")) test_consistency_DragDetect();
1449
	else if (getName().equals("test_consistency_Segments")) test_consistency_Segments();
1447
	else super.runTest();
1450
	else super.runTest();
1448
}
1451
}
1449
1452
Lines 1498-1501 Link Here
1498
    consistencyEvent(30, 10, 50, 0, ConsistencyUtility.MOUSE_DRAG);
1501
    consistencyEvent(30, 10, 50, 0, ConsistencyUtility.MOUSE_DRAG);
1499
}
1502
}
1500
1503
1504
public void test_consistency_Segments () {
1505
    final SegmentListener sl1 = new SegmentListener() {
1506
        public void lineGetSegments(SegmentEvent event) {
1507
        	if ((event.text.length() & 1) == 1) {
1508
	            event.segments = new int [] {1, event.text.length()};
1509
	            event.segmentsChars = null;
1510
        	} else {
1511
	            event.segments = new int [] {0, 0, event.text.length()};
1512
	            event.segmentsChars = new char [] {':', '<', '>'};
1513
        	}
1514
            listenerCalled = true;
1515
        }
1516
    };
1517
	try {
1518
		text.addSegmentListener(null);
1519
		fail("No exception thrown for addSegmentListener(null)");
1520
	}
1521
	catch (IllegalArgumentException e) {
1522
	}
1523
	//doSegmentsTest(false);
1524
	boolean[] singleLine = {false, true};
1525
	for (int i = singleLine.length; i-- > 0;) {
1526
		makeCleanEnvironment(singleLine[i]);
1527
		listenerCalled = false;
1528
		text.addSegmentListener(sl1);
1529
		assertTrue(listenerCalled);
1530
		listenerCalled = false;
1531
		doSegmentsTest(true);
1532
	
1533
		text.addSegmentListener(sl1);
1534
		assertTrue(listenerCalled);
1535
		listenerCalled = false;
1536
		doSegmentsTest(true);
1537
	
1538
		text.removeSegmentListener(sl1);
1539
		assertTrue(listenerCalled);
1540
		listenerCalled = false;
1541
		doSegmentsTest(true);
1542
	
1543
		text.removeSegmentListener(sl1);
1544
		assertTrue(!listenerCalled);
1545
		doSegmentsTest(false);
1546
	}
1547
}
1548
1549
private void doSegmentsTest (boolean isListening) {
1550
	String string = "1234";
1551
1552
	// Test setText
1553
	text.setText(string);
1554
	assertEquals(isListening, listenerCalled);
1555
	listenerCalled = false;
1556
	assertEquals(string, text.getText());
1557
1558
	// Test append
1559
	String substr = "56";
1560
	text.append(substr);
1561
	string += substr;
1562
	assertEquals(isListening, listenerCalled);
1563
	listenerCalled = false;
1564
	assertEquals(string, text.getText());
1565
1566
	// Test limit
1567
	if ((text.getStyle() & SWT.SINGLE) != 0) {
1568
		int limit = string.length() - 1;
1569
		text.setTextLimit(limit);
1570
		assertEquals(limit, text.getTextLimit());
1571
		text.setText(string);
1572
		assertEquals(string.substring(0, limit), text.getText());
1573
	}
1574
	text.setTextLimit(Text.LIMIT);
1575
	text.setText(string);
1576
	assertEquals(string, text.getText());
1577
	//assertEquals(Text.LIMIT, text.getTextLimit());
1578
1579
	// Test selection, copy and paste
1580
	listenerCalled = false;
1581
	Point pt = new Point(1, 3);
1582
	text.setSelection(pt);
1583
	assertEquals(pt, text.getSelection());
1584
	assertFalse(listenerCalled);
1585
	text.copy();
1586
	assertEquals(isListening, listenerCalled);
1587
	listenerCalled = false;
1588
1589
	substr = string.substring(pt.x, pt.y);
1590
	pt.x = pt.y = 0;
1591
	text.setSelection(pt);
1592
	text.paste();
1593
	assertEquals(isListening, listenerCalled);
1594
	listenerCalled = false;
1595
	
1596
	pt.x = pt.y = pt.x + substr.length();
1597
	assertEquals(substr + string, text.getText());
1598
	assertEquals(pt, text.getSelection());
1599
1600
	// Test cut
1601
	pt.x = 0;
1602
	pt.y = 2;
1603
	text.setSelection(pt);
1604
	assertEquals(substr, text.getSelectionText());
1605
	assertEquals(substr, text.getText(pt.x, pt.y - 1));
1606
	text.cut();
1607
	assertEquals(isListening, listenerCalled);
1608
	listenerCalled = false;
1609
	assertEquals(string, text.getText());
1610
1611
	// Test insert
1612
	substr = "12";
1613
	pt.x = 6;
1614
	pt.y = 8;
1615
	text.setSelection(pt.x, pt.y);
1616
	text.cut();
1617
	pt.y = pt.x;
1618
	assertEquals(pt, text.getSelection());
1619
	listenerCalled = false;
1620
	pt.x = pt.y = 0;
1621
	text.setSelection(pt);
1622
	text.insert(substr);
1623
	assertEquals(isListening, listenerCalled);
1624
	listenerCalled = false;
1625
	pt.x = pt.y = pt.x + substr.length();
1626
	assertEquals(pt, text.getSelection());
1627
	assertEquals(substr + string, text.getText());
1628
}
1501
}
1629
}
(-)JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Combo.java (+162 lines)
Lines 18-23 Link Here
18
import org.eclipse.swt.events.*;
18
import org.eclipse.swt.events.*;
19
import org.eclipse.swt.graphics.*;
19
import org.eclipse.swt.graphics.*;
20
import org.eclipse.swt.widgets.*;
20
import org.eclipse.swt.widgets.*;
21
import org.eclipse.swt.events.SegmentListener;
21
22
22
/**
23
/**
23
 * Automated Test Suite for class org.eclipse.swt.widgets.Combo
24
 * Automated Test Suite for class org.eclipse.swt.widgets.Combo
Lines 825-830 Link Here
825
	methodNames.addElement("test_consistency_EnterSelection");
826
	methodNames.addElement("test_consistency_EnterSelection");
826
	methodNames.addElement("test_consistency_MenuDetect");
827
	methodNames.addElement("test_consistency_MenuDetect");
827
	methodNames.addElement("test_consistency_DragDetect");
828
	methodNames.addElement("test_consistency_DragDetect");
829
	methodNames.addElement("test_consistency_Segments");
828
	methodNames.addAll(Test_org_eclipse_swt_widgets_Composite.methodNames()); // add superclass method names
830
	methodNames.addAll(Test_org_eclipse_swt_widgets_Composite.methodNames()); // add superclass method names
829
	return methodNames;
831
	return methodNames;
830
}
832
}
Lines 838-843 Link Here
838
	else if (getName().equals("test_computeSizeIIZ")) test_computeSizeIIZ();
840
	else if (getName().equals("test_computeSizeIIZ")) test_computeSizeIIZ();
839
	else if (getName().equals("test_copy")) test_copy();
841
	else if (getName().equals("test_copy")) test_copy();
840
	else if (getName().equals("test_cut")) test_cut();
842
	else if (getName().equals("test_cut")) test_cut();
843
	else if (getName().equals("test_consistency_Segments")) test_consistency_Segments();
841
	else if (getName().equals("test_deselectAll")) test_deselectAll();
844
	else if (getName().equals("test_deselectAll")) test_deselectAll();
842
	else if (getName().equals("test_deselectI")) test_deselectI();
845
	else if (getName().equals("test_deselectI")) test_deselectI();
843
	else if (getName().equals("test_getItemCount")) test_getItemCount();
846
	else if (getName().equals("test_getItemCount")) test_getItemCount();
Lines 954-959 Link Here
954
    consistencyEvent(10, 5, 20, 10, ConsistencyUtility.MOUSE_DRAG);
957
    consistencyEvent(10, 5, 20, 10, ConsistencyUtility.MOUSE_DRAG);
955
}
958
}
956
959
960
public void test_consistency_Segments () {
961
    final SegmentListener sl1 = new SegmentListener() {
962
        public void lineGetSegments(SegmentEvent event) {
963
        	if ((event.text.length() & 1) == 1) {
964
	            event.segments = new int [] {1, event.text.length()};
965
        	} else {
966
	            event.segments = new int [] {0, 0, event.text.length()};
967
	            event.segmentsChars = new char [] {':', '<', '>'};
968
        	}
969
            listenerCalled = true;
970
        }
971
    };
972
	try {
973
		combo.addSegmentListener(null);
974
		fail("No exception thrown for addSegmentListener(null)");
975
	}
976
	catch (IllegalArgumentException e) {
977
	}
978
	listenerCalled = false;
979
980
	//doSegmentsTest(false);
981
982
	combo.addSegmentListener(sl1);
983
	assertTrue(listenerCalled);
984
	listenerCalled = false;
985
	doSegmentsTest(true);
986
987
	combo.addSegmentListener(sl1);
988
	assertTrue(listenerCalled);
989
	listenerCalled = false;
990
	doSegmentsTest(true);
991
992
	combo.removeSegmentListener(sl1);
993
	assertTrue(listenerCalled);
994
	listenerCalled = false;
995
	doSegmentsTest(true);
996
997
	combo.removeSegmentListener(sl1);
998
	assertTrue(!listenerCalled);
999
	doSegmentsTest(false);
1000
}
1001
1002
private void doSegmentsTest (boolean isListening) {
1003
	String[] items = { "1.", "2a..", "2.." };
1004
	String string = "123456";
957
1005
1006
	// Test setItems
1007
	combo.setItems(items);
1008
	assertEquals(isListening, listenerCalled);
1009
	listenerCalled = false;
1010
	assertEquals(items, combo.getItems());
1011
1012
	// Test setText
1013
	combo.setText(string);
1014
	assertEquals(isListening, listenerCalled);
1015
	listenerCalled = false;
1016
	assertEquals(string, combo.getText());
1017
1018
	// Test getItem, indexOf, select
1019
	int count = items.length;
1020
	for (int i = 0; i < count; i++) {
1021
		assertEquals(items[i], combo.getItem(i));
1022
		assertFalse(listenerCalled);
1023
		assertEquals(i, combo.indexOf(items[i]));
1024
		//assertEquals(isListening, listenerCalled);
1025
		listenerCalled = false;
1026
1027
		combo.select(i);
1028
		listenerCalled = false;
1029
		assertEquals(i, combo.getSelectionIndex());
1030
		assertEquals(items[i], combo.getText());
1031
		assertFalse(listenerCalled);
1032
1033
		String currentText = combo.getText();
1034
		combo.deselect(i ^ 1);
1035
		assertEquals(currentText, combo.getText());
1036
1037
		combo.deselect(i);
1038
		assertEquals("", combo.getText());
1039
	}
1040
1041
	for (int i = 0; i < count; i++) {
1042
		combo.setText(combo.getItem(i));
1043
		assertEquals(items[i], combo.getText());
1044
	}
1045
	listenerCalled = false;
1046
1047
	// Test limit
1048
	combo.setTextLimit(-1);
1049
	combo.setText(string);
1050
	assertEquals(string, combo.getText());
1051
1052
	int limit = 2;
1053
	combo.setTextLimit(limit);
1054
	assertEquals(limit, combo.getTextLimit());
1055
	combo.setText(string);
1056
	assertEquals(string.substring(0, limit), combo.getText());
1057
1058
	combo.select(1);
1059
	assertEquals(limit, combo.getTextLimit());
1060
1061
	combo.remove(1);
1062
	assertEquals(limit, combo.getTextLimit());
1063
	
1064
	combo.add(items[1], 1);
1065
	assertEquals(limit, combo.getTextLimit());
1066
1067
	combo.deselectAll();
1068
	assertEquals(limit, combo.getTextLimit());
1069
1070
	combo.remove(1, 2);
1071
	assertEquals(limit, combo.getTextLimit());
1072
1073
	combo.removeAll();
1074
	assertEquals(limit, combo.getTextLimit());
1075
	
1076
	combo.setItems(items);
1077
	assertEquals(limit, combo.getTextLimit());
1078
	
1079
	combo.setTextLimit(Combo.LIMIT);
1080
	combo.setText(string);
1081
	assertEquals(string, combo.getText());
1082
1083
	// Test add item
1084
	String item = "3...";
1085
	combo.add(item);
1086
	assertEquals(isListening, listenerCalled);
1087
	listenerCalled = false;
1088
	assertEquals(item, combo.getItem(count++));
1089
1090
	combo.select(1);
1091
	
1092
	// Test remove item by name
1093
	combo.remove(items[1]);
1094
	assertEquals(--count, combo.getItemCount());
1095
	assertEquals(1, combo.indexOf(items[2]));
1096
1097
	System.out.println(combo.getText());
1098
	combo.setTextLimit(Combo.LIMIT);
1099
	combo.setText(string);
1100
1101
	// Test copy and paste
1102
	combo.setSelection(new Point(1,3));
1103
	combo.copy();
1104
	assertEquals(isListening, listenerCalled);
1105
	listenerCalled = false;
1106
1107
	combo.setSelection(new Point(0,0));
1108
	combo.paste();
1109
	assertEquals(isListening, listenerCalled);
1110
	listenerCalled = false;
1111
	assertEquals(string.substring(1, 3) + string, combo.getText());
1112
1113
	// Test cut
1114
	combo.setSelection(new Point(0,2));
1115
	combo.cut();
1116
	assertEquals(isListening, listenerCalled);
1117
	listenerCalled = false;
1118
	assertEquals(string, combo.getText());
1119
}
958
1120
959
}
1121
}

Return to bug 230854