Mercurial > projects > dwt-linux
annotate dwt/widgets/Text.d @ 259:c0d810de7093
Update SWT 3.4M7 to 3.4
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 29 Jun 2008 14:33:38 +0200 |
parents | 5a30aa9820f3 |
children |
rev | line source |
---|---|
72 | 1 /******************************************************************************* |
259 | 2 * Copyright (c) 2000, 2008 IBM Corporation and others. |
60 | 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 | |
72 | 10 * Port to the D programming language: |
11 * Frank Benoit <benoit@tionex.de> | |
60 | 12 *******************************************************************************/ |
13 module dwt.widgets.Text; | |
14 | |
238 | 15 import dwt.dwthelper.utils; |
16 | |
60 | 17 |
71 | 18 import dwt.DWT; |
60 | 19 import dwt.internal.gtk.OS; |
20 import dwt.graphics.Rectangle; | |
21 import dwt.events.ModifyListener; | |
22 import dwt.widgets.TypedListener; | |
23 import dwt.events.SelectionListener; | |
24 import dwt.events.SelectionEvent; | |
25 import dwt.events.VerifyListener; | |
26 import dwt.widgets.Event; | |
27 import dwt.widgets.Scrollable; | |
28 import dwt.widgets.Composite; | |
29 | |
30 import Math = tango.math.Math; | |
31 static import tango.stdc.string; | |
32 | |
33 /** | |
34 * Instances of this class are selectable user interface | |
35 * objects that allow the user to enter and modify text. | |
259 | 36 * Text controls can be either single or multi-line. |
37 * When a text control is created with a border, the | |
38 * operating system includes a platform specific inset | |
39 * around the contents of the control. When created | |
40 * without a border, an effort is made to remove the | |
41 * inset such that the preferred size of the control | |
42 * is the same size as the contents. | |
60 | 43 * <p> |
44 * <dl> | |
45 * <dt><b>Styles:</b></dt> | |
46 * <dd>CANCEL, CENTER, LEFT, MULTI, PASSWORD, SEARCH, SINGLE, RIGHT, READ_ONLY, WRAP</dd> | |
47 * <dt><b>Events:</b></dt> | |
48 * <dd>DefaultSelection, Modify, Verify</dd> | |
49 * </dl> | |
50 * <p> | |
51 * Note: Only one of the styles MULTI and SINGLE may be specified, | |
52 * and only one of the styles LEFT, CENTER, and RIGHT may be specified. | |
53 * </p><p> | |
54 * IMPORTANT: This class is <em>not</em> intended to be subclassed. | |
55 * </p> | |
259 | 56 * |
57 * @see <a href="http://www.eclipse.org/swt/snippets/#text">Text snippets</a> | |
58 * @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: ControlExample</a> | |
59 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> | |
60 | 60 */ |
61 public class Text : Scrollable { | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
62 |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
63 alias Scrollable.computeSize computeSize; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
64 alias Scrollable.dragDetect dragDetect; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
65 alias Scrollable.setBackgroundColor setBackgroundColor; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
66 alias Scrollable.setCursor setCursor; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
67 alias Scrollable.setOrientation setOrientation; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
68 alias Scrollable.translateTraversal translateTraversal; |
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
69 |
60 | 70 GtkTextBuffer* bufferHandle; |
71 int tabs = 8, lastEventTime = 0; | |
72 GdkEventKey* gdkEventKey; | |
73 int fixStart = -1, fixEnd = -1; | |
74 bool doubleClick; | |
238 | 75 String message = ""; |
60 | 76 |
77 static const int INNER_BORDER = 2; | |
78 //static const int ITER_SIZEOF = GtkTextIter.sizeof; | |
79 | |
80 /** | |
81 * The maximum number of characters that can be entered | |
82 * into a text widget. | |
83 * <p> | |
84 * Note that this value is platform dependent, based upon | |
85 * the native widget implementation. | |
86 * </p> | |
87 */ | |
88 public const static int LIMIT = 0x7FFFFFFF; | |
89 /** | |
90 * The delimiter used by multi-line text widgets. When text | |
91 * is queried and from the widget, it will be delimited using | |
92 * this delimiter. | |
93 */ | |
238 | 94 public const static String DELIMITER = "\n"; |
60 | 95 /* |
96 * These values can be different on different platforms. | |
97 * Therefore they are not initialized in the declaration | |
98 * to stop the compiler from inlining. | |
99 */ | |
100 // <keinfarbton> avoid static ctor | |
101 //static { | |
102 // LIMIT = 0x7FFFFFFF; | |
103 // DELIMITER = "\n"; | |
104 //} | |
105 | |
106 /** | |
107 * Constructs a new instance of this class given its parent | |
108 * and a style value describing its behavior and appearance. | |
109 * <p> | |
110 * The style value is either one of the style constants defined in | |
71 | 111 * class <code>DWT</code> which is applicable to instances of this |
60 | 112 * class, or must be built by <em>bitwise OR</em>'ing together |
113 * (that is, using the <code>int</code> "|" operator) two or more | |
71 | 114 * of those <code>DWT</code> style constants. The class description |
60 | 115 * lists the style constants that are applicable to the class. |
116 * Style bits are also inherited from superclasses. | |
117 * </p> | |
118 * | |
119 * @param parent a composite control which will be the parent of the new instance (cannot be null) | |
120 * @param style the style of control to construct | |
121 * | |
122 * @exception IllegalArgumentException <ul> | |
123 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> | |
124 * </ul> | |
71 | 125 * @exception DWTException <ul> |
60 | 126 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
127 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> | |
128 * </ul> | |
129 * | |
71 | 130 * @see DWT#SINGLE |
131 * @see DWT#MULTI | |
132 * @see DWT#READ_ONLY | |
133 * @see DWT#WRAP | |
60 | 134 * @see Widget#checkSubclass |
135 * @see Widget#getStyle | |
136 */ | |
137 public this (Composite parent, int style) { | |
138 super (parent, checkStyle (style)); | |
139 } | |
140 | |
141 static int checkStyle (int style) { | |
71 | 142 if ((style & DWT.SEARCH) !is 0) { |
143 style |= DWT.SINGLE | DWT.BORDER; | |
144 style &= ~DWT.PASSWORD; | |
60 | 145 } |
71 | 146 style &= ~DWT.SEARCH; |
147 if ((style & DWT.SINGLE) !is 0 && (style & DWT.MULTI) !is 0) { | |
148 style &= ~DWT.MULTI; | |
60 | 149 } |
71 | 150 style = checkBits (style, DWT.LEFT, DWT.CENTER, DWT.RIGHT, 0, 0, 0); |
151 if ((style & DWT.SINGLE) !is 0) style &= ~(DWT.H_SCROLL | DWT.V_SCROLL | DWT.WRAP); | |
152 if ((style & DWT.WRAP) !is 0) { | |
153 style |= DWT.MULTI; | |
154 style &= ~DWT.H_SCROLL; | |
60 | 155 } |
71 | 156 if ((style & DWT.MULTI) !is 0) style &= ~DWT.PASSWORD; |
157 if ((style & (DWT.SINGLE | DWT.MULTI)) !is 0) return style; | |
158 if ((style & (DWT.H_SCROLL | DWT.V_SCROLL)) !is 0) return style | DWT.MULTI; | |
159 return style | DWT.SINGLE; | |
60 | 160 } |
161 | |
162 override void createHandle (int index) { | |
163 state |= HANDLE | MENU; | |
164 fixedHandle = cast(GtkWidget*) OS.g_object_new (display.gtk_fixed_get_type (), null); | |
71 | 165 if (fixedHandle is null) error (DWT.ERROR_NO_HANDLES); |
60 | 166 OS.gtk_fixed_set_has_window (cast(GtkFixed*)fixedHandle, true); |
71 | 167 if ((style & DWT.SINGLE) !is 0) { |
60 | 168 handle = OS.gtk_entry_new (); |
71 | 169 if (handle is null) error (DWT.ERROR_NO_HANDLES); |
60 | 170 OS.gtk_container_add (cast(GtkContainer*)fixedHandle, handle); |
71 | 171 OS.gtk_editable_set_editable (cast(GtkEditable*)handle, (style & DWT.READ_ONLY) is 0); |
172 OS.gtk_entry_set_has_frame (cast(GtkEntry*)handle, (style & DWT.BORDER) !is 0); | |
173 OS.gtk_entry_set_visibility (cast(GtkEntry*)handle, (style & DWT.PASSWORD) is 0); | |
60 | 174 float alignment = 0.0f; |
71 | 175 if ((style & DWT.CENTER) !is 0) alignment = 0.5f; |
176 if ((style & DWT.RIGHT) !is 0) alignment = 1.0f; | |
60 | 177 if (alignment > 0.0f) { |
178 OS.gtk_entry_set_alignment (cast(GtkEntry*)handle, alignment); | |
179 } | |
180 } else { | |
181 scrolledHandle = cast(GtkWidget*) OS.gtk_scrolled_window_new (null, null); | |
71 | 182 if (scrolledHandle is null) error (DWT.ERROR_NO_HANDLES); |
60 | 183 handle = OS.gtk_text_view_new (); |
71 | 184 if (handle is null) error (DWT.ERROR_NO_HANDLES); |
60 | 185 bufferHandle = OS.gtk_text_view_get_buffer (cast(GtkTextView*)handle); |
71 | 186 if (bufferHandle is null) error (DWT.ERROR_NO_HANDLES); |
60 | 187 OS.gtk_container_add (cast(GtkContainer*)fixedHandle, scrolledHandle); |
188 OS.gtk_container_add (cast(GtkContainer*)scrolledHandle, handle); | |
71 | 189 OS.gtk_text_view_set_editable (cast(GtkTextView*)handle, (style & DWT.READ_ONLY) is 0); |
240 | 190 if ((style & DWT.WRAP) !is 0) OS.gtk_text_view_set_wrap_mode (cast(GtkTextView*)handle, OS.GTK_WRAP_WORD_CHAR); |
71 | 191 int hsp = (style & DWT.H_SCROLL) !is 0 ? OS.GTK_POLICY_ALWAYS : OS.GTK_POLICY_NEVER; |
192 int vsp = (style & DWT.V_SCROLL) !is 0 ? OS.GTK_POLICY_ALWAYS : OS.GTK_POLICY_NEVER; | |
60 | 193 OS.gtk_scrolled_window_set_policy (cast(GtkScrolledWindow*)scrolledHandle, hsp, vsp); |
71 | 194 if ((style & DWT.BORDER) !is 0) { |
60 | 195 OS.gtk_scrolled_window_set_shadow_type (cast(GtkScrolledWindow*)scrolledHandle, OS.GTK_SHADOW_ETCHED_IN); |
196 } | |
197 int just = OS.GTK_JUSTIFY_LEFT; | |
71 | 198 if ((style & DWT.CENTER) !is 0) just = OS.GTK_JUSTIFY_CENTER; |
199 if ((style & DWT.RIGHT) !is 0) just = OS.GTK_JUSTIFY_RIGHT; | |
60 | 200 OS.gtk_text_view_set_justification (cast(GtkTextView*)handle, just); |
201 } | |
202 } | |
203 | |
204 override void createWidget (int index) { | |
205 super.createWidget (index); | |
206 doubleClick = true; | |
207 } | |
208 | |
209 /** | |
210 * Adds the listener to the collection of listeners who will | |
211 * be notified when the receiver's text is modified, by sending | |
212 * it one of the messages defined in the <code>ModifyListener</code> | |
213 * interface. | |
214 * | |
215 * @param listener the listener which should be notified | |
216 * | |
217 * @exception IllegalArgumentException <ul> | |
218 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
219 * </ul> | |
71 | 220 * @exception DWTException <ul> |
60 | 221 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
222 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
223 * </ul> | |
224 * | |
225 * @see ModifyListener | |
226 * @see #removeModifyListener | |
227 */ | |
228 public void addModifyListener (ModifyListener listener) { | |
229 checkWidget (); | |
71 | 230 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 231 TypedListener typedListener = new TypedListener (listener); |
71 | 232 addListener (DWT.Modify, typedListener); |
60 | 233 } |
234 | |
235 /** | |
236 * Adds the listener to the collection of listeners who will | |
237 * be notified when the control is selected by the user, by sending | |
238 * it one of the messages defined in the <code>SelectionListener</code> | |
239 * interface. | |
240 * <p> | |
241 * <code>widgetSelected</code> is not called for texts. | |
242 * <code>widgetDefaultSelected</code> is typically called when ENTER is pressed in a single-line text, | |
71 | 243 * or when ENTER is pressed in a search text. If the receiver has the <code>DWT.SEARCH | DWT.CANCEL</code> style |
244 * and the user cancels the search, the event object detail field contains the value <code>DWT.CANCEL</code>. | |
60 | 245 * </p> |
246 * | |
247 * @param listener the listener which should be notified when the control is selected by the user | |
248 * | |
249 * @exception IllegalArgumentException <ul> | |
250 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
251 * </ul> | |
71 | 252 * @exception DWTException <ul> |
60 | 253 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
254 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
255 * </ul> | |
256 * | |
257 * @see SelectionListener | |
258 * @see #removeSelectionListener | |
259 * @see SelectionEvent | |
260 */ | |
261 public void addSelectionListener(SelectionListener listener) { | |
262 checkWidget (); | |
71 | 263 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 264 TypedListener typedListener = new TypedListener(listener); |
71 | 265 addListener(DWT.Selection,typedListener); |
266 addListener(DWT.DefaultSelection,typedListener); | |
60 | 267 } |
268 | |
269 /** | |
270 * Adds the listener to the collection of listeners who will | |
271 * be notified when the receiver's text is verified, by sending | |
272 * it one of the messages defined in the <code>VerifyListener</code> | |
273 * interface. | |
274 * | |
275 * @param listener the listener which should be notified | |
276 * | |
277 * @exception IllegalArgumentException <ul> | |
278 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
279 * </ul> | |
71 | 280 * @exception DWTException <ul> |
60 | 281 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
282 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
283 * </ul> | |
284 * | |
285 * @see VerifyListener | |
286 * @see #removeVerifyListener | |
287 */ | |
288 public void addVerifyListener (VerifyListener listener) { | |
289 checkWidget(); | |
71 | 290 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 291 TypedListener typedListener = new TypedListener (listener); |
71 | 292 addListener (DWT.Verify, typedListener); |
60 | 293 } |
294 | |
295 /** | |
296 * Appends a string. | |
297 * <p> | |
298 * The new text is appended to the text at | |
299 * the end of the widget. | |
300 * </p> | |
301 * | |
302 * @param string the string to be appended | |
303 * | |
71 | 304 * @exception DWTException <ul> |
60 | 305 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
306 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
307 * </ul> | |
308 */ | |
238 | 309 public void append (String string) { |
60 | 310 checkWidget (); |
255
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
311 // DWT extension: allow null for zero length string |
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
312 //if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
71 | 313 if ((style & DWT.SINGLE) !is 0) { |
60 | 314 int dummy = -1; |
315 OS.gtk_editable_insert_text (cast(GtkEditable*)handle, string.ptr, string.length, &dummy ); | |
316 OS.gtk_editable_set_position (cast(GtkEditable*)handle, -1); | |
317 } else { | |
318 GtkTextIter position; | |
319 OS.gtk_text_buffer_get_end_iter (bufferHandle, &position); | |
320 OS.gtk_text_buffer_insert (bufferHandle, &position, string.ptr, string.length); | |
321 OS.gtk_text_buffer_place_cursor (bufferHandle, &position); | |
322 auto mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
323 OS.gtk_text_view_scroll_mark_onscreen (cast(GtkTextView*)handle, mark); | |
324 } | |
325 } | |
326 | |
327 /** | |
328 * Clears the selection. | |
329 * | |
71 | 330 * @exception DWTException <ul> |
60 | 331 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
332 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
333 * </ul> | |
334 */ | |
335 public void clearSelection () { | |
336 checkWidget (); | |
71 | 337 if ((style & DWT.SINGLE) !is 0) { |
60 | 338 int position = OS.gtk_editable_get_position (cast(GtkEditable*)handle); |
339 OS.gtk_editable_select_region (cast(GtkEditable*)handle, position, position); | |
340 } else { | |
341 GtkTextIter position; | |
342 auto insertMark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
343 auto selectionMark = OS.gtk_text_buffer_get_selection_bound (bufferHandle); | |
344 OS.gtk_text_buffer_get_iter_at_mark (bufferHandle, &position, insertMark); | |
345 OS.gtk_text_buffer_move_mark (bufferHandle, selectionMark, &position); | |
346 OS.gtk_text_buffer_move_mark (bufferHandle, insertMark, &position); | |
347 } | |
348 } | |
349 | |
350 override public Point computeSize (int wHint, int hHint, bool changed) { | |
351 checkWidget (); | |
71 | 352 if (wHint !is DWT.DEFAULT && wHint < 0) wHint = 0; |
353 if (hHint !is DWT.DEFAULT && hHint < 0) hHint = 0; | |
60 | 354 int w , h; |
71 | 355 if ((style & DWT.SINGLE) !is 0) { |
60 | 356 OS.gtk_widget_realize (handle); |
357 auto layout = OS.gtk_entry_get_layout (cast(GtkEntry*)handle); | |
358 OS.pango_layout_get_size (layout, &w, &h); | |
359 } else { | |
360 GtkTextIter start; | |
361 GtkTextIter end; | |
362 OS.gtk_text_buffer_get_bounds (bufferHandle, &start, &end); | |
363 auto text = OS.gtk_text_buffer_get_text (bufferHandle, &start, &end, true); | |
364 auto layout = OS.gtk_widget_create_pango_layout (handle, text); | |
365 OS.g_free (text); | |
366 OS.pango_layout_set_width (layout, wHint * OS.PANGO_SCALE); | |
367 OS.pango_layout_get_size (layout, &w, &h); | |
368 OS.g_object_unref (layout); | |
369 } | |
370 int width = OS.PANGO_PIXELS (w); | |
371 int height = OS.PANGO_PIXELS (h); | |
372 //This code is intentionally commented | |
71 | 373 // if ((style & DWT.SEARCH) !is 0 && message.length () !is 0) { |
60 | 374 // GC gc = new GC (this); |
375 // Point size = gc.stringExtent (message); | |
376 // width = Math.max (width, size.x); | |
377 // gc.dispose (); | |
378 // } | |
379 if (width is 0) width = DEFAULT_WIDTH; | |
380 if (height is 0) height = DEFAULT_HEIGHT; | |
71 | 381 width = wHint is DWT.DEFAULT ? width : wHint; |
382 height = hHint is DWT.DEFAULT ? height : hHint; | |
60 | 383 Rectangle trim = computeTrim (0, 0, width, height); |
384 return new Point (trim.width, trim.height); | |
385 } | |
386 | |
387 override public Rectangle computeTrim (int x, int y, int width, int height) { | |
388 checkWidget (); | |
389 Rectangle trim = super.computeTrim (x, y, width, height); | |
390 int xborder = 0, yborder = 0; | |
71 | 391 if ((style & DWT.SINGLE) !is 0) { |
392 if ((style & DWT.BORDER) !is 0) { | |
60 | 393 auto style = OS.gtk_widget_get_style (handle); |
394 xborder += OS.gtk_style_get_xthickness (style); | |
395 yborder += OS.gtk_style_get_ythickness (style); | |
396 } | |
397 xborder += INNER_BORDER; | |
398 yborder += INNER_BORDER; | |
399 } else { | |
400 int borderWidth = OS.gtk_container_get_border_width (cast(GtkContainer*)handle); | |
401 xborder += borderWidth; | |
402 yborder += borderWidth; | |
403 } | |
404 int property; | |
405 OS.gtk_widget_style_get1 (handle, OS.interior_focus.ptr, &property); | |
406 if (property is 0) { | |
407 OS.gtk_widget_style_get1 (handle, OS.focus_line_width.ptr, &property); | |
408 xborder += property; | |
409 yborder += property; | |
410 } | |
411 trim.x -= xborder; | |
412 trim.y -= yborder; | |
413 trim.width += 2 * xborder; | |
414 trim.height += 2 * yborder; | |
415 return new Rectangle (trim.x, trim.y, trim.width, trim.height); | |
416 } | |
417 | |
418 /** | |
419 * Copies the selected text. | |
420 * <p> | |
421 * The current selection is copied to the clipboard. | |
422 * </p> | |
423 * | |
71 | 424 * @exception DWTException <ul> |
60 | 425 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
426 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
427 * </ul> | |
428 */ | |
429 public void copy () { | |
430 checkWidget (); | |
71 | 431 if ((style & DWT.SINGLE) !is 0) { |
60 | 432 OS.gtk_editable_copy_clipboard (cast(GtkEditable*)handle); |
433 } else { | |
434 auto clipboard = OS.gtk_clipboard_get (cast(void*)OS.GDK_NONE); | |
435 OS.gtk_text_buffer_copy_clipboard (bufferHandle, clipboard); | |
436 } | |
437 } | |
438 | |
439 /** | |
440 * Cuts the selected text. | |
441 * <p> | |
442 * The current selection is first copied to the | |
443 * clipboard and then deleted from the widget. | |
444 * </p> | |
445 * | |
71 | 446 * @exception DWTException <ul> |
60 | 447 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
448 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
449 * </ul> | |
450 */ | |
451 public void cut () { | |
452 checkWidget (); | |
71 | 453 if ((style & DWT.SINGLE) !is 0) { |
60 | 454 OS.gtk_editable_cut_clipboard (cast(GtkEditable*)handle); |
455 } else { | |
456 auto clipboard = OS.gtk_clipboard_get (cast(void*)OS.GDK_NONE); | |
457 OS.gtk_text_buffer_cut_clipboard (bufferHandle, clipboard, OS.gtk_text_view_get_editable (cast(GtkTextView*)handle)); | |
458 } | |
459 } | |
460 | |
461 override void deregister () { | |
462 super.deregister (); | |
463 if (bufferHandle !is null) display.removeWidget (cast(GtkWidget*)bufferHandle); | |
464 auto imContext = imContext (); | |
465 if (imContext !is null) display.removeWidget (cast(GtkWidget*)imContext); | |
466 } | |
467 | |
468 override bool dragDetect (int x, int y, bool filter, bool* consume) { | |
469 if (filter) { | |
470 int start = 0, end = 0; | |
71 | 471 if ((style & DWT.SINGLE) !is 0) { |
60 | 472 int s, e; |
473 OS.gtk_editable_get_selection_bounds (cast(GtkEditable*)handle, &s, &e); | |
474 start = s; | |
475 end = e; | |
476 } else { | |
477 GtkTextIter s; | |
478 GtkTextIter e; | |
479 OS.gtk_text_buffer_get_selection_bounds (bufferHandle, &s, &e); | |
480 start = OS.gtk_text_iter_get_offset (&s); | |
481 end = OS.gtk_text_iter_get_offset (&e); | |
482 } | |
483 if (start !is end) { | |
484 if (end < start) { | |
485 int temp = end; | |
486 end = start; | |
487 start = temp; | |
488 } | |
489 int position = -1; | |
71 | 490 if ((style & DWT.SINGLE) !is 0) { |
60 | 491 int index; |
492 int trailing; | |
493 auto layout = OS.gtk_entry_get_layout (cast(GtkEntry*)handle); | |
494 OS.pango_layout_xy_to_index (layout, x * OS.PANGO_SCALE, y * OS.PANGO_SCALE, &index, &trailing); | |
495 auto ptr = OS.pango_layout_get_text (layout); | |
496 position = cast(int)/*64*/OS.g_utf8_pointer_to_offset (ptr, ptr + index) + trailing; | |
497 } else { | |
498 GtkTextIter p; | |
499 OS.gtk_text_view_get_iter_at_location (cast(GtkTextView*)handle, &p, x, y); | |
500 position = OS.gtk_text_iter_get_offset (&p); | |
501 } | |
502 if (start <= position && position < end) { | |
503 if (super.dragDetect (x, y, filter, consume)) { | |
504 if (consume !is null) consume [0] = true; | |
505 return true; | |
506 } | |
507 } | |
508 } | |
509 return false; | |
510 } | |
511 return super.dragDetect (x, y, filter, consume); | |
512 } | |
513 | |
514 override GdkDrawable* eventWindow () { | |
515 return paintWindow (); | |
516 } | |
517 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
518 override bool filterKey (int keyval, GdkEventKey* event) { |
60 | 519 int time = OS.gdk_event_get_time (cast(GdkEvent*)event); |
520 if (time !is lastEventTime) { | |
521 lastEventTime = time; | |
522 auto imContext = imContext (); | |
523 if (imContext !is null) { | |
524 return cast(bool)OS.gtk_im_context_filter_keypress (imContext, event); | |
525 } | |
526 } | |
527 gdkEventKey = event; | |
528 return false; | |
529 } | |
530 | |
531 void fixIM () { | |
532 /* | |
533 * The IM filter has to be called one time for each key press event. | |
534 * When the IM is open the key events are duplicated. The first event | |
71 | 535 * is filtered by DWT and the second event is filtered by GTK. In some |
60 | 536 * cases the GTK handler does not run (the widget is destroyed, the |
537 * application code consumes the event, etc), for these cases the IM | |
71 | 538 * filter has to be called by DWT. |
60 | 539 */ |
540 if (gdkEventKey !is null && gdkEventKey !is cast(GdkEventKey*)-1) { | |
541 auto imContext = imContext (); | |
542 if (imContext !is null) { | |
543 OS.gtk_im_context_filter_keypress (imContext, gdkEventKey); | |
544 gdkEventKey = cast(GdkEventKey*)-1; | |
545 return; | |
546 } | |
547 } | |
548 gdkEventKey = null; | |
549 } | |
550 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
551 override GdkColor* getBackgroundColor () { |
60 | 552 return getBaseColor (); |
553 } | |
554 | |
150
f2e04420fd6c
reworked overrides and superclass aliases
Frank Benoit <benoit@tionex.de>
parents:
139
diff
changeset
|
555 public override int getBorderWidth () { |
60 | 556 checkWidget(); |
71 | 557 if ((style & DWT.MULTI) !is 0) return super.getBorderWidth (); |
60 | 558 auto style = OS.gtk_widget_get_style (handle); |
71 | 559 if ((this.style & DWT.BORDER) !is 0) { |
60 | 560 return OS.gtk_style_get_xthickness (style); |
561 } | |
562 return 0; | |
563 } | |
564 | |
565 /** | |
566 * Returns the line number of the caret. | |
567 * <p> | |
568 * The line number of the caret is returned. | |
569 * </p> | |
570 * | |
571 * @return the line number | |
572 * | |
71 | 573 * @exception DWTException <ul> |
60 | 574 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
575 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
576 * </ul> | |
577 */ | |
578 public int getCaretLineNumber () { | |
579 checkWidget (); | |
71 | 580 if ((style & DWT.SINGLE) !is 0) return 1; |
60 | 581 GtkTextIter position; |
582 auto mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
583 OS.gtk_text_buffer_get_iter_at_mark (bufferHandle, &position, mark); | |
584 return OS.gtk_text_iter_get_line (&position); | |
585 } | |
586 | |
587 /** | |
588 * Returns a point describing the receiver's location relative | |
589 * to its parent (or its display if its parent is null). | |
590 * <p> | |
591 * The location of the caret is returned. | |
592 * </p> | |
593 * | |
594 * @return a point, the location of the caret | |
595 * | |
71 | 596 * @exception DWTException <ul> |
60 | 597 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
598 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
599 * </ul> | |
600 */ | |
601 public Point getCaretLocation () { | |
602 checkWidget (); | |
71 | 603 if ((style & DWT.SINGLE) !is 0) { |
60 | 604 int index = OS.gtk_editable_get_position (cast(GtkEditable*)handle); |
605 if (OS.GTK_VERSION >= OS.buildVERSION (2, 6, 0)) { | |
606 index = OS.gtk_entry_text_index_to_layout_index (cast(GtkEntry*)handle, index); | |
607 } | |
608 int offset_x, offset_y; | |
609 OS.gtk_entry_get_layout_offsets (cast(GtkEntry*)handle, &offset_x, &offset_y); | |
610 auto layout = OS.gtk_entry_get_layout (cast(GtkEntry*)handle); | |
611 PangoRectangle pos; | |
612 OS.pango_layout_index_to_pos (layout, index, &pos); | |
613 int x = offset_x + OS.PANGO_PIXELS (pos.x) - getBorderWidth (); | |
614 int y = offset_y + OS.PANGO_PIXELS (pos.y); | |
615 return new Point (x, y); | |
616 } | |
617 GtkTextIter position; | |
618 auto mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
619 OS.gtk_text_buffer_get_iter_at_mark (bufferHandle, &position, mark); | |
620 GdkRectangle rect; | |
621 OS.gtk_text_view_get_iter_location (cast(GtkTextView*)handle, &position, &rect); | |
622 int x; | |
623 int y; | |
624 OS.gtk_text_view_buffer_to_window_coords (cast(GtkTextView*)handle, OS.GTK_TEXT_WINDOW_TEXT, rect.x, rect.y, &x, &y); | |
625 return new Point (x, y); | |
626 } | |
627 | |
628 /** | |
629 * Returns the character position of the caret. | |
630 * <p> | |
631 * Indexing is zero based. | |
632 * </p> | |
633 * | |
634 * @return the position of the caret | |
635 * | |
71 | 636 * @exception DWTException <ul> |
60 | 637 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
638 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
639 * </ul> | |
640 */ | |
641 public int getCaretPosition () { | |
642 checkWidget (); | |
71 | 643 if ((style & DWT.SINGLE) !is 0) { |
60 | 644 return OS.gtk_editable_get_position (cast(GtkEditable*)handle); |
645 } | |
646 GtkTextIter position; | |
647 auto mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
648 OS.gtk_text_buffer_get_iter_at_mark (bufferHandle, &position, mark); | |
649 return OS.gtk_text_iter_get_offset (&position); | |
650 } | |
651 | |
652 /** | |
653 * Returns the number of characters. | |
654 * | |
655 * @return number of characters in the widget | |
656 * | |
71 | 657 * @exception DWTException <ul> |
60 | 658 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
659 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
660 * </ul> | |
661 */ | |
662 public int getCharCount () { | |
663 checkWidget (); | |
71 | 664 if ((style & DWT.SINGLE) !is 0) { |
60 | 665 auto ptr = OS.gtk_entry_get_text (cast(GtkEntry*)handle); |
666 return cast(int)/*64*/OS.g_utf8_strlen (ptr, -1); | |
667 } | |
668 return OS.gtk_text_buffer_get_char_count (bufferHandle); | |
669 } | |
670 | |
671 /** | |
672 * Returns the double click enabled flag. | |
673 * <p> | |
674 * The double click flag enables or disables the | |
675 * default action of the text widget when the user | |
676 * double clicks. | |
677 * </p> | |
678 * | |
679 * @return whether or not double click is enabled | |
680 * | |
71 | 681 * @exception DWTException <ul> |
60 | 682 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
683 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
684 * </ul> | |
685 */ | |
686 public bool getDoubleClickEnabled () { | |
687 checkWidget (); | |
688 return doubleClick; | |
689 } | |
690 | |
691 /** | |
692 * Returns the echo character. | |
693 * <p> | |
694 * The echo character is the character that is | |
695 * displayed when the user enters text or the | |
696 * text is changed by the programmer. | |
697 * </p> | |
698 * | |
699 * @return the echo character | |
700 * | |
71 | 701 * @exception DWTException <ul> |
60 | 702 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
703 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
704 * </ul> | |
705 * | |
706 * @see #setEchoChar | |
707 */ | |
708 public char getEchoChar () { | |
709 checkWidget (); | |
71 | 710 if ((style & DWT.SINGLE) !is 0) { |
60 | 711 if (!OS.gtk_entry_get_visibility (cast(GtkEntry*)handle)) { |
712 return OS.gtk_entry_get_invisible_char (cast(GtkEntry*)handle); | |
713 } | |
714 } | |
715 return '\0'; | |
716 } | |
717 | |
718 /** | |
719 * Returns the editable state. | |
720 * | |
721 * @return whether or not the receiver is editable | |
722 * | |
71 | 723 * @exception DWTException <ul> |
60 | 724 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
725 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
726 * </ul> | |
727 */ | |
728 public bool getEditable () { | |
729 checkWidget (); | |
71 | 730 if ((style & DWT.SINGLE) !is 0) { |
60 | 731 return cast(bool)OS.gtk_editable_get_editable (cast(GtkEditable*)handle); |
732 } | |
733 return cast(bool)OS.gtk_text_view_get_editable (cast(GtkTextView*)handle); | |
734 } | |
735 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
736 override GdkColor* getForegroundColor () { |
60 | 737 return getTextColor (); |
738 } | |
739 | |
740 /** | |
741 * Returns the number of lines. | |
742 * | |
743 * @return the number of lines in the widget | |
744 * | |
71 | 745 * @exception DWTException <ul> |
60 | 746 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
747 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
748 * </ul> | |
749 */ | |
750 public int getLineCount () { | |
751 checkWidget (); | |
71 | 752 if ((style & DWT.SINGLE) !is 0) return 1; |
60 | 753 return OS.gtk_text_buffer_get_line_count (bufferHandle); |
754 } | |
755 | |
756 /** | |
757 * Returns the line delimiter. | |
758 * | |
759 * @return a string that is the line delimiter | |
760 * | |
71 | 761 * @exception DWTException <ul> |
60 | 762 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
763 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
764 * </ul> | |
765 * | |
766 * @see #DELIMITER | |
767 */ | |
238 | 768 public String getLineDelimiter () { |
60 | 769 checkWidget (); |
770 return "\n"; | |
771 } | |
772 | |
773 /** | |
774 * Returns the height of a line. | |
775 * | |
776 * @return the height of a row of text | |
777 * | |
71 | 778 * @exception DWTException <ul> |
60 | 779 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
780 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
781 * </ul> | |
782 */ | |
783 public int getLineHeight () { | |
784 checkWidget (); | |
785 return fontHeight (getFontDescription (), handle); | |
786 } | |
787 | |
788 /** | |
789 * Returns the widget message. When the widget is created | |
71 | 790 * with the style <code>DWT.SEARCH</code>, the message text |
60 | 791 * is displayed as a hint for the user, indicating the |
792 * purpose of the field. | |
793 * <p> | |
794 * Note: This operation is a <em>HINT</em> and is not | |
795 * supported on platforms that do not have this concept. | |
796 * </p> | |
797 * | |
798 * @return the widget message | |
799 * | |
71 | 800 * @exception DWTException <ul> |
60 | 801 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
802 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
803 * </ul> | |
804 * | |
805 * @since 3.3 | |
806 */ | |
238 | 807 public String getMessage () { |
60 | 808 checkWidget (); |
809 return message; | |
810 } | |
811 | |
812 /** | |
813 * Returns the orientation of the receiver, which will be one of the | |
71 | 814 * constants <code>DWT.LEFT_TO_RIGHT</code> or <code>DWT.RIGHT_TO_LEFT</code>. |
60 | 815 * |
816 * @return the orientation style | |
817 * | |
71 | 818 * @exception DWTException <ul> |
60 | 819 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
820 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
821 * </ul> | |
822 * | |
823 * @since 2.1.2 | |
824 */ | |
825 public int getOrientation () { | |
826 checkWidget(); | |
71 | 827 return style & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT); |
60 | 828 } |
829 | |
830 /*public*/ int getPosition (Point point) { | |
831 checkWidget (); | |
71 | 832 if (point is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 833 int position = -1; |
71 | 834 if ((style & DWT.SINGLE) !is 0) { |
60 | 835 int index; |
836 int trailing; | |
837 auto layout = OS.gtk_entry_get_layout (cast(GtkEntry*)handle); | |
838 OS.pango_layout_xy_to_index (layout, point.x * OS.PANGO_SCALE, point.y * OS.PANGO_SCALE, &index, &trailing); | |
839 auto ptr = OS.pango_layout_get_text (layout); | |
840 position = cast(int)/*64*/OS.g_utf8_pointer_to_offset (ptr, ptr + index) + trailing; | |
841 } else { | |
842 GtkTextIter p; | |
843 OS.gtk_text_view_get_iter_at_location (cast(GtkTextView*)handle, &p, point.x, point.y); | |
844 position = OS.gtk_text_iter_get_offset (&p); | |
845 } | |
846 return position; | |
847 } | |
848 | |
849 /** | |
850 * Returns a <code>Point</code> whose x coordinate is the | |
851 * character position representing the start of the selected | |
852 * text, and whose y coordinate is the character position | |
853 * representing the end of the selection. An "empty" selection | |
854 * is indicated by the x and y coordinates having the same value. | |
855 * <p> | |
856 * Indexing is zero based. The range of a selection is from | |
857 * 0..N where N is the number of characters in the widget. | |
858 * </p> | |
859 * | |
860 * @return a point representing the selection start and end | |
861 * | |
71 | 862 * @exception DWTException <ul> |
60 | 863 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
864 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
865 * </ul> | |
866 */ | |
867 public Point getSelection () { | |
868 checkWidget (); | |
71 | 869 if ((style & DWT.SINGLE) !is 0) { |
60 | 870 int start; |
871 int end; | |
872 OS.gtk_editable_get_selection_bounds (cast(GtkEditable*)handle, &start, &end); | |
873 return new Point (start, end); | |
874 } | |
875 GtkTextIter start; | |
876 GtkTextIter end; | |
877 OS.gtk_text_buffer_get_selection_bounds (bufferHandle, &start, &end); | |
878 return new Point (OS.gtk_text_iter_get_offset (&start), OS.gtk_text_iter_get_offset (&end)); | |
879 } | |
880 | |
881 /** | |
882 * Returns the number of selected characters. | |
883 * | |
884 * @return the number of selected characters. | |
885 * | |
71 | 886 * @exception DWTException <ul> |
60 | 887 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
888 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
889 * </ul> | |
890 */ | |
891 public int getSelectionCount () { | |
892 checkWidget (); | |
893 Point selection = getSelection (); | |
894 return Math.abs (selection.y - selection.x); | |
895 } | |
896 | |
897 /** | |
898 * Gets the selected text, or an empty string if there is no current selection. | |
899 * | |
900 * @return the selected text | |
901 * | |
71 | 902 * @exception DWTException <ul> |
60 | 903 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
904 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
905 * </ul> | |
906 */ | |
238 | 907 public String getSelectionText () { |
60 | 908 checkWidget (); |
909 Point selection = getSelection (); | |
910 return getText ()[ selection.x .. selection.y ]; | |
911 } | |
912 | |
913 /** | |
914 * Returns the number of tabs. | |
915 * <p> | |
916 * Tab stop spacing is specified in terms of the | |
917 * space (' ') character. The width of a single | |
918 * tab stop is the pixel width of the spaces. | |
919 * </p> | |
920 * | |
921 * @return the number of tab characters | |
922 * | |
71 | 923 * @exception DWTException <ul> |
60 | 924 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
925 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
926 * </ul> | |
927 */ | |
928 public int getTabs () { | |
929 checkWidget (); | |
930 return tabs; | |
931 } | |
932 | |
933 int getTabWidth (int tabs) { | |
934 auto layout = OS.gtk_widget_create_pango_layout (handle, " ".ptr ); | |
935 int width; | |
936 int height; | |
937 OS.pango_layout_get_size (layout, &width, &height); | |
938 OS.g_object_unref (layout); | |
939 return width * tabs; | |
940 } | |
941 | |
942 /** | |
943 * Returns the widget text. | |
944 * <p> | |
945 * The text for a text widget is the characters in the widget, or | |
946 * an empty string if this has never been set. | |
947 * </p> | |
948 * | |
949 * @return the widget text | |
950 * | |
71 | 951 * @exception DWTException <ul> |
60 | 952 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
953 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
954 * </ul> | |
955 */ | |
238 | 956 public String getText () { |
60 | 957 checkWidget (); |
958 char* address; | |
71 | 959 if ((style & DWT.SINGLE) !is 0) { |
60 | 960 address = OS.gtk_entry_get_text (cast(GtkEntry*)handle); |
961 } else { | |
962 GtkTextIter start; | |
963 GtkTextIter end; | |
964 OS.gtk_text_buffer_get_bounds (bufferHandle, &start, &end); | |
965 address = OS.gtk_text_buffer_get_text (bufferHandle, &start, &end, true); | |
966 } | |
967 if (address is null) return ""; | |
238 | 968 String res = fromStringz( address ).dup; |
71 | 969 if ((style & DWT.MULTI) !is 0) OS.g_free (address); |
60 | 970 return res; |
971 } | |
972 | |
973 /** | |
974 * Returns a range of text. Returns an empty string if the | |
975 * start of the range is greater than the end. | |
976 * <p> | |
977 * Indexing is zero based. The range of | |
978 * a selection is from 0..N-1 where N is | |
979 * the number of characters in the widget. | |
980 * </p> | |
981 * | |
982 * @param start the start of the range | |
983 * @param end the end of the range | |
984 * @return the range of text | |
985 * | |
71 | 986 * @exception DWTException <ul> |
60 | 987 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
988 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
989 * </ul> | |
990 */ | |
238 | 991 public String getText (int start, int end) { |
60 | 992 checkWidget (); |
993 if (!(start <= end && 0 <= end)) return ""; | |
994 start = Math.max (0, start); | |
995 char* address; | |
71 | 996 if ((style & DWT.SINGLE) !is 0) { |
60 | 997 address = OS.gtk_editable_get_chars (cast(GtkEditable*)handle, start, end + 1); |
998 } else { | |
999 int length = OS.gtk_text_buffer_get_char_count (bufferHandle); | |
1000 end = Math.min (end, length - 1); | |
1001 GtkTextIter startIter; | |
1002 GtkTextIter endIter; | |
1003 OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, &startIter, start); | |
1004 OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, &endIter, end + 1); | |
1005 address = OS.gtk_text_buffer_get_text (bufferHandle, &startIter, &endIter, true); | |
1006 } | |
71 | 1007 if (address is null) error (DWT.ERROR_CANNOT_GET_TEXT); |
238 | 1008 String res = fromStringz( address ).dup; |
60 | 1009 OS.g_free (address); |
1010 return res; | |
1011 } | |
1012 | |
1013 /** | |
1014 * Returns the maximum number of characters that the receiver is capable of holding. | |
1015 * <p> | |
1016 * If this has not been changed by <code>setTextLimit()</code>, | |
1017 * it will be the constant <code>Text.LIMIT</code>. | |
1018 * </p> | |
1019 * | |
1020 * @return the text limit | |
1021 * | |
71 | 1022 * @exception DWTException <ul> |
60 | 1023 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1024 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1025 * </ul> | |
1026 * | |
1027 * @see #LIMIT | |
1028 */ | |
1029 public int getTextLimit () { | |
1030 checkWidget (); | |
71 | 1031 if ((style & DWT.MULTI) !is 0) return LIMIT; |
60 | 1032 int limit = OS.gtk_entry_get_max_length (cast(GtkEntry*)handle); |
1033 return limit is 0 ? 0xFFFF : limit; | |
1034 } | |
1035 | |
1036 /** | |
1037 * Returns the zero-relative index of the line which is currently | |
1038 * at the top of the receiver. | |
1039 * <p> | |
1040 * This index can change when lines are scrolled or new lines are added or removed. | |
1041 * </p> | |
1042 * | |
1043 * @return the index of the top line | |
1044 * | |
71 | 1045 * @exception DWTException <ul> |
60 | 1046 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1047 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1048 * </ul> | |
1049 */ | |
1050 public int getTopIndex () { | |
1051 checkWidget (); | |
71 | 1052 if ((style & DWT.SINGLE) !is 0) return 0; |
60 | 1053 GtkTextIter position; |
1054 GdkRectangle rect; | |
1055 OS.gtk_text_view_get_visible_rect (cast(GtkTextView*)handle, &rect); | |
1056 OS.gtk_text_view_get_line_at_y (cast(GtkTextView*)handle, &position, rect.y, null); | |
1057 return OS.gtk_text_iter_get_line (&position); | |
1058 } | |
1059 | |
1060 /** | |
1061 * Returns the top pixel. | |
1062 * <p> | |
1063 * The top pixel is the pixel position of the line | |
1064 * that is currently at the top of the widget. On | |
1065 * some platforms, a text widget can be scrolled by | |
1066 * pixels instead of lines so that a partial line | |
1067 * is displayed at the top of the widget. | |
1068 * </p><p> | |
1069 * The top pixel changes when the widget is scrolled. | |
1070 * The top pixel does not include the widget trimming. | |
1071 * </p> | |
1072 * | |
1073 * @return the pixel position of the top line | |
1074 * | |
71 | 1075 * @exception DWTException <ul> |
60 | 1076 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1077 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1078 * </ul> | |
1079 */ | |
1080 public int getTopPixel () { | |
1081 checkWidget (); | |
71 | 1082 if ((style & DWT.SINGLE) !is 0) return 0; |
60 | 1083 GtkTextIter position; |
1084 GdkRectangle rect; | |
1085 OS.gtk_text_view_get_visible_rect (cast(GtkTextView*)handle, &rect); | |
1086 int lineTop; | |
1087 OS.gtk_text_view_get_line_at_y (cast(GtkTextView*)handle, &position, rect.y, &lineTop); | |
1088 return lineTop; | |
1089 } | |
1090 | |
1091 override int /*long*/ gtk_activate (GtkWidget* widget) { | |
71 | 1092 postEvent (DWT.DefaultSelection); |
60 | 1093 return 0; |
1094 } | |
1095 | |
1096 override int /*long*/ gtk_button_press_event (GtkWidget* widget, GdkEventButton* gdkEvent) { | |
1097 auto result = super.gtk_button_press_event (widget, gdkEvent); | |
1098 if (result !is 0) return result; | |
1099 if (!doubleClick) { | |
1100 switch (gdkEvent.type) { | |
1101 case OS.GDK_2BUTTON_PRESS: | |
1102 case OS.GDK_3BUTTON_PRESS: | |
1103 return 1; | |
1104 default: | |
1105 } | |
1106 } | |
1107 return result; | |
1108 } | |
1109 | |
1110 | |
1111 override int /*long*/ gtk_changed (GtkWidget* widget) { | |
1112 /* | |
1113 * Feature in GTK. When the user types, GTK positions | |
1114 * the caret after sending the changed signal. This | |
1115 * means that application code that attempts to position | |
1116 * the caret during a changed signal will fail. The fix | |
1117 * is to post the modify event when the user is typing. | |
1118 */ | |
1119 bool keyPress = false; | |
1120 auto eventPtr = OS.gtk_get_current_event (); | |
1121 if (eventPtr !is null) { | |
1122 GdkEventKey* gdkEvent = cast(GdkEventKey*)eventPtr; | |
1123 switch (gdkEvent.type) { | |
1124 case OS.GDK_KEY_PRESS: | |
1125 keyPress = true; | |
1126 break; | |
1127 default: | |
1128 } | |
1129 OS.gdk_event_free (eventPtr); | |
1130 } | |
1131 if (keyPress) { | |
71 | 1132 postEvent (DWT.Modify); |
60 | 1133 } else { |
71 | 1134 sendEvent (DWT.Modify); |
60 | 1135 } |
1136 return 0; | |
1137 } | |
1138 | |
1139 override int /*long*/ gtk_commit (GtkIMContext* imcontext, char* text) { | |
1140 if (text is null) return 0; | |
71 | 1141 if ((style & DWT.SINGLE) !is 0) { |
60 | 1142 if (!OS.gtk_editable_get_editable (cast(GtkEditable*)handle)) return 0; |
1143 } | |
158
de2578a843a7
Tango update to rev 3158, TracedException>Exception, fromUtf8z>fromStringz,Fix Bug in MenuItem Thanx to nascent for the report.
Frank Benoit <benoit@tionex.de>
parents:
152
diff
changeset
|
1144 char [] chars = fromStringz( text ).dup; |
60 | 1145 if (chars.length is 0) return 0; |
71 | 1146 char [] newChars = sendIMKeyEvent (DWT.KeyDown, null, chars); |
60 | 1147 if (newChars is null) return 0; |
1148 /* | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1149 * Feature in GTK. For a GtkEntry, during the insert-text signal, |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1150 * GTK allows the programmer to change only the caret location, |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1151 * not the selection. If the programmer changes the selection, |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1152 * the new selection is lost. The fix is to detect a selection |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1153 * change and set it after the insert-text signal has completed. |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1154 */ |
60 | 1155 fixStart = fixEnd = -1; |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1156 OS.g_signal_handlers_block_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCOMMIT); |
60 | 1157 int id = OS.g_signal_lookup (OS.commit.ptr, OS.gtk_im_context_get_type ()); |
1158 int mask = OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID; | |
1159 OS.g_signal_handlers_unblock_matched (imContext, mask, id, 0, null, null, cast(void*)handle); | |
1160 if (newChars is chars) { | |
1161 OS.g_signal_emit_by_name1 (imContext, OS.commit.ptr, cast(int)text); | |
1162 } else { | |
1163 OS.g_signal_emit_by_name1 (imContext, OS.commit.ptr, cast(int)toStringz(newChars) ); | |
1164 } | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1165 OS.g_signal_handlers_unblock_matched (imContext, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCOMMIT ); |
60 | 1166 OS.g_signal_handlers_block_matched (imContext, mask, id, 0, null, null, cast(void*)handle); |
71 | 1167 if ((style & DWT.SINGLE) !is 0) { |
60 | 1168 if (fixStart !is -1 && fixEnd !is -1) { |
1169 OS.gtk_editable_set_position (cast(GtkEditable*)handle, fixStart); | |
1170 OS.gtk_editable_select_region (cast(GtkEditable*)handle, fixStart, fixEnd); | |
1171 } | |
1172 } | |
1173 fixStart = fixEnd = -1; | |
1174 return 0; | |
1175 } | |
1176 | |
1177 override int /*long*/ gtk_delete_range (GtkWidget* widget, int /*long*/ iter1, int /*long*/ iter2) { | |
71 | 1178 if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
60 | 1179 GtkTextIter startIter = *cast(GtkTextIter*)iter1; |
1180 GtkTextIter endIter = *cast(GtkTextIter*)iter2; | |
1181 int start = OS.gtk_text_iter_get_offset (&startIter); | |
1182 int end = OS.gtk_text_iter_get_offset (&endIter); | |
238 | 1183 String newText = verifyText ("", start, end); |
60 | 1184 if (newText is null) { |
1185 /* Remember the selection when the text was deleted */ | |
1186 OS.gtk_text_buffer_get_selection_bounds (bufferHandle, &startIter, &endIter); | |
1187 start = OS.gtk_text_iter_get_offset (&startIter); | |
1188 end = OS.gtk_text_iter_get_offset (&endIter); | |
1189 if (start !is end) { | |
1190 fixStart = start; | |
1191 fixEnd = end; | |
1192 } | |
1193 OS.g_signal_stop_emission_by_name (bufferHandle, OS.delete_range.ptr); | |
1194 } else { | |
1195 if (newText.length > 0) { | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1196 OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1197 OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_RANGE); |
60 | 1198 OS.gtk_text_buffer_delete (bufferHandle, &startIter, &endIter); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1199 OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_RANGE); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1200 OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1201 OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEXT_BUFFER_INSERT_TEXT); |
60 | 1202 OS.gtk_text_buffer_insert (bufferHandle, &startIter, newText.ptr, newText.length); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1203 OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEXT_BUFFER_INSERT_TEXT); |
60 | 1204 OS.g_signal_stop_emission_by_name (bufferHandle, OS.delete_range.ptr); |
1205 } | |
1206 } | |
1207 return 0; | |
1208 } | |
1209 | |
1210 override int /*long*/ gtk_delete_text (GtkWidget* widget, int /*long*/ start_pos, int /*long*/ end_pos) { | |
71 | 1211 if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
238 | 1212 String newText = verifyText ("", cast(int)/*64*/start_pos, cast(int)/*64*/end_pos); |
60 | 1213 if (newText is null) { |
1214 /* Remember the selection when the text was deleted */ | |
1215 int newStart, newEnd; | |
1216 OS.gtk_editable_get_selection_bounds (cast(GtkEditable*)handle, &newStart, &newEnd); | |
1217 if (newStart !is newEnd) { | |
1218 fixStart = newStart; | |
1219 fixEnd = newEnd; | |
1220 } | |
1221 OS.g_signal_stop_emission_by_name (handle, OS.delete_text.ptr); | |
1222 } else { | |
1223 if (newText.length > 0) { | |
1224 int pos; | |
1225 pos = cast(int)/*64*/end_pos; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1226 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1227 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
60 | 1228 OS.gtk_editable_insert_text (cast(GtkEditable*)handle, newText.ptr, newText.length, &pos); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1229 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1230 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
60 | 1231 OS.gtk_editable_set_position (cast(GtkEditable*)handle, pos); |
1232 } | |
1233 } | |
1234 return 0; | |
1235 } | |
1236 | |
1237 override int /*long*/ gtk_event_after (GtkWidget* widget, GdkEvent* event) { | |
113
1401263f71b0
renamed setCursor(Gtk..) to gtk_setCursor, so the public interface do not need a cast for passing null
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1238 if (cursor !is null) gtk_setCursor (cursor.handle); |
60 | 1239 /* |
1240 * Feature in GTK. The gtk-entry-select-on-focus property is a global | |
1241 * setting. Return it to its default value after the GtkEntry has done | |
1242 * its focus in processing so that other widgets (such as the combo) | |
1243 * use the correct value. | |
1244 */ | |
71 | 1245 if ((style & DWT.SINGLE) !is 0 && display.entrySelectOnFocus) { |
60 | 1246 switch (event.type) { |
1247 case OS.GDK_FOCUS_CHANGE: | |
1248 GdkEventFocus* gdkEventFocus = cast(GdkEventFocus*)event; | |
1249 if (gdkEventFocus.in_ is 0) { | |
1250 auto settings = OS.gtk_settings_get_default (); | |
1251 OS.g_object_set1 (settings, OS.gtk_entry_select_on_focus.ptr, true ); | |
1252 } | |
1253 break; | |
1254 default: | |
1255 } | |
1256 } | |
1257 return super.gtk_event_after (widget, event); | |
1258 } | |
1259 | |
1260 override int /*long*/ gtk_focus_out_event (GtkWidget* widget, GdkEventFocus* event) { | |
1261 fixIM (); | |
1262 return super.gtk_focus_out_event (widget, event); | |
1263 } | |
1264 | |
1265 override int /*long*/ gtk_grab_focus (GtkWidget* widget) { | |
1266 auto result = super.gtk_grab_focus (widget); | |
1267 /* | |
1268 * Feature in GTK. GtkEntry widgets select their text on focus in, | |
1269 * clearing the previous selection. This behavior is controlled by | |
1270 * the gtk-entry-select-on-focus property. The fix is to disable | |
1271 * this property when a GtkEntry is given focus and restore it after | |
1272 * the entry has done focus in processing. | |
1273 */ | |
71 | 1274 if ((style & DWT.SINGLE) !is 0 && display.entrySelectOnFocus) { |
60 | 1275 auto settings = OS.gtk_settings_get_default (); |
1276 OS.g_object_set1 (settings, OS.gtk_entry_select_on_focus.ptr, false ); | |
1277 } | |
1278 return result; | |
1279 } | |
1280 | |
1281 override int /*long*/ gtk_insert_text (GtkEditable* widget, char* new_text, int new_text_length, int position) { | |
71 | 1282 if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
60 | 1283 if (new_text is null || new_text_length is 0) return 0; |
238 | 1284 String oldText = (cast(char*)new_text)[ 0 .. new_text_length ].dup; |
60 | 1285 int pos; |
1286 pos = *cast(int*)position; | |
1287 if (pos is -1) { | |
1288 auto ptr = OS.gtk_entry_get_text (cast(GtkEntry*)handle); | |
1289 pos = cast(int)/*64*/OS.g_utf8_strlen (ptr, -1); | |
1290 } | |
1291 /* Use the selection when the text was deleted */ | |
1292 int start = pos, end = pos; | |
1293 if (fixStart !is -1 && fixEnd !is -1) { | |
1294 start = pos = fixStart; | |
1295 end = fixEnd; | |
1296 fixStart = fixEnd = -1; | |
1297 } | |
238 | 1298 String newText = verifyText (oldText, start, end); |
60 | 1299 if (newText !is oldText) { |
1300 int newStart, newEnd; | |
1301 OS.gtk_editable_get_selection_bounds (cast(GtkEditable*)handle, &newStart, &newEnd); | |
1302 if (newText !is null) { | |
1303 if (newStart !is newEnd) { | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1304 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1305 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
60 | 1306 OS.gtk_editable_delete_selection (cast(GtkEditable*)handle); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1307 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1308 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
60 | 1309 } |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1310 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
60 | 1311 OS.gtk_editable_insert_text (cast(GtkEditable*)handle, newText.ptr, newText.length, &pos); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1312 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
60 | 1313 newStart = newEnd = pos; |
1314 } | |
1315 pos = newEnd; | |
1316 if (newStart !is newEnd) { | |
1317 fixStart = newStart; | |
1318 fixEnd = newEnd; | |
1319 } | |
1320 *cast(int*)position = pos; | |
1321 OS.g_signal_stop_emission_by_name (handle, OS.insert_text.ptr); | |
1322 } | |
1323 return 0; | |
1324 } | |
1325 | |
1326 override int /*long*/ gtk_key_press_event (GtkWidget* widget, GdkEventKey* event) { | |
1327 auto result = super.gtk_key_press_event (widget, event); | |
1328 if (result !is 0) fixIM (); | |
1329 if (gdkEventKey is cast(GdkEventKey*)-1) result = 1; | |
1330 gdkEventKey = null; | |
1331 return result; | |
1332 } | |
1333 | |
240 | 1334 override int /*long*/ gtk_populate_popup (GtkWidget* widget, GtkWidget* menu) { |
1335 if ((style & DWT.RIGHT_TO_LEFT) !is 0) { | |
1336 OS.gtk_widget_set_direction (menu, OS.GTK_TEXT_DIR_RTL); | |
1337 display.doSetDirectionProc (menu, OS.GTK_TEXT_DIR_RTL); | |
1338 } | |
1339 return 0; | |
1340 } | |
1341 | |
60 | 1342 override int /*long*/ gtk_text_buffer_insert_text (GtkTextBuffer *widget, GtkTextIter *iter, char *text, int len) { |
71 | 1343 if (!hooks (DWT.Verify) && !filters (DWT.Verify)) return 0; |
60 | 1344 GtkTextIter position = *iter; |
1345 /* Use the selection when the text was deleted */ | |
1346 int start = OS.gtk_text_iter_get_offset (&position), end = start; | |
1347 if (fixStart !is -1 && fixEnd !is -1) { | |
1348 start = fixStart; | |
1349 end = fixEnd; | |
1350 fixStart = fixEnd = -1; | |
1351 } | |
238 | 1352 String oldText = text[ 0 .. len ]; |
1353 String newText = verifyText (oldText, start, end); | |
60 | 1354 if (newText is null) { |
1355 OS.g_signal_stop_emission_by_name (bufferHandle, OS.insert_text.ptr); | |
1356 } else { | |
1357 if (newText !is oldText) { | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1358 OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEXT_BUFFER_INSERT_TEXT); |
60 | 1359 OS.gtk_text_buffer_insert (bufferHandle, iter, newText.ptr, newText.length); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1360 OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEXT_BUFFER_INSERT_TEXT); |
60 | 1361 OS.g_signal_stop_emission_by_name (bufferHandle, OS.insert_text.ptr); |
1362 } | |
1363 } | |
1364 return 0; | |
1365 } | |
1366 | |
1367 override void hookEvents () { | |
1368 super.hookEvents(); | |
71 | 1369 if ((style & DWT.SINGLE) !is 0) { |
60 | 1370 OS.g_signal_connect_closure (handle, OS.changed.ptr, display.closures [CHANGED], true); |
1371 OS.g_signal_connect_closure (handle, OS.insert_text.ptr, display.closures [INSERT_TEXT], false); | |
1372 OS.g_signal_connect_closure (handle, OS.delete_text.ptr, display.closures [DELETE_TEXT], false); | |
1373 OS.g_signal_connect_closure (handle, OS.activate.ptr, display.closures [ACTIVATE], false); | |
1374 OS.g_signal_connect_closure (handle, OS.grab_focus.ptr, display.closures [GRAB_FOCUS], false); | |
240 | 1375 OS.g_signal_connect_closure (handle, OS.populate_popup.ptr, display.closures [POPULATE_POPUP], false); |
60 | 1376 } else { |
1377 OS.g_signal_connect_closure (bufferHandle, OS.changed.ptr, display.closures [CHANGED], false); | |
1378 OS.g_signal_connect_closure (bufferHandle, OS.insert_text.ptr, display.closures [TEXT_BUFFER_INSERT_TEXT], false); | |
1379 OS.g_signal_connect_closure (bufferHandle, OS.delete_range.ptr, display.closures [DELETE_RANGE], false); | |
240 | 1380 OS.g_signal_connect_closure (handle, OS.populate_popup.ptr, display.closures [POPULATE_POPUP], false); |
60 | 1381 } |
1382 auto imContext = imContext (); | |
1383 if (imContext !is null) { | |
1384 OS.g_signal_connect_closure (imContext, OS.commit.ptr, display.closures [COMMIT], false); | |
1385 int id = OS.g_signal_lookup (OS.commit.ptr, OS.gtk_im_context_get_type ()); | |
1386 int mask = OS.G_SIGNAL_MATCH_DATA | OS.G_SIGNAL_MATCH_ID; | |
1387 OS.g_signal_handlers_block_matched (imContext, mask, id, 0, null, null, cast(void*)handle); | |
1388 } | |
1389 } | |
1390 | |
1391 GtkIMContext* imContext () { | |
240 | 1392 if ((style & DWT.SINGLE) !is 0) { |
1393 return OS.gtk_editable_get_editable (handle) ? OS.GTK_ENTRY_IM_CONTEXT (handle) : null; | |
1394 } | |
1395 return OS.GTK_TEXTVIEW_IM_CONTEXT (cast(GtkTextView*)handle); | |
60 | 1396 } |
1397 | |
1398 /** | |
1399 * Inserts a string. | |
1400 * <p> | |
1401 * The old selection is replaced with the new text. | |
1402 * </p> | |
1403 * | |
1404 * @param string the string | |
1405 * | |
71 | 1406 * @exception DWTException <ul> |
60 | 1407 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1408 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1409 * </ul> | |
1410 */ | |
238 | 1411 public void insert (String string) { |
60 | 1412 checkWidget (); |
255
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1413 // DWT extension: allow null for zero length string |
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1414 //if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
71 | 1415 if ((style & DWT.SINGLE) !is 0) { |
60 | 1416 int start, end; |
1417 OS.gtk_editable_get_selection_bounds (cast(GtkEditable*)handle, &start, &end); | |
1418 OS.gtk_editable_delete_selection (cast(GtkEditable*)handle); | |
1419 OS.gtk_editable_insert_text (cast(GtkEditable*)handle, string.ptr, string.length, &start); | |
1420 OS.gtk_editable_set_position (cast(GtkEditable*)handle, start); | |
1421 } else { | |
1422 GtkTextIter start; | |
1423 GtkTextIter end; | |
1424 if (OS.gtk_text_buffer_get_selection_bounds (bufferHandle, &start, &end)) { | |
1425 OS.gtk_text_buffer_delete (bufferHandle, &start, &end); | |
1426 } | |
1427 OS.gtk_text_buffer_insert (bufferHandle, &start, string.ptr, string.length); | |
1428 OS.gtk_text_buffer_place_cursor (bufferHandle, &start); | |
1429 auto mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
1430 OS.gtk_text_view_scroll_mark_onscreen (cast(GtkTextView*)handle, mark); | |
1431 } | |
1432 } | |
1433 | |
1434 override GdkDrawable* paintWindow () { | |
71 | 1435 if ((style & DWT.SINGLE) !is 0) { |
60 | 1436 auto window = super.paintWindow (); |
1437 auto children = OS.gdk_window_get_children (window); | |
1438 if (children !is null) window = cast(GdkDrawable*) OS.g_list_data (children); | |
1439 OS.g_list_free (children); | |
1440 return window; | |
1441 } | |
1442 OS.gtk_widget_realize (handle); | |
1443 return OS.gtk_text_view_get_window (cast(GtkTextView*)handle, OS.GTK_TEXT_WINDOW_TEXT); | |
1444 } | |
1445 | |
1446 /** | |
1447 * Pastes text from clipboard. | |
1448 * <p> | |
1449 * The selected text is deleted from the widget | |
1450 * and new text inserted from the clipboard. | |
1451 * </p> | |
1452 * | |
71 | 1453 * @exception DWTException <ul> |
60 | 1454 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1455 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1456 * </ul> | |
1457 */ | |
1458 public void paste () { | |
1459 checkWidget (); | |
71 | 1460 if ((style & DWT.SINGLE) !is 0) { |
60 | 1461 OS.gtk_editable_paste_clipboard (cast(GtkEditable*)handle); |
1462 } else { | |
1463 auto clipboard = OS.gtk_clipboard_get (cast(void*)OS.GDK_NONE); | |
1464 OS.gtk_text_buffer_paste_clipboard (bufferHandle, clipboard, null, OS.gtk_text_view_get_editable (cast(GtkTextView*)handle)); | |
1465 } | |
1466 } | |
1467 | |
1468 override void register () { | |
1469 super.register (); | |
1470 if (bufferHandle !is null) display.addWidget (cast(GtkWidget*)bufferHandle, this); | |
1471 auto imContext = imContext (); | |
1472 if (imContext !is null) display.addWidget (cast(GtkWidget*)imContext, this); | |
1473 } | |
1474 | |
1475 override void releaseWidget () { | |
1476 super.releaseWidget (); | |
1477 fixIM (); | |
1478 if (OS.GTK_VERSION < OS.buildVERSION (2, 6, 0)) { | |
1479 /* | |
1480 * Bug in GTK. Any text copied into the clipboard will be lost when | |
1481 * the GtkTextView is destroyed. The fix is to paste the contents as | |
1482 * the widget is being destroyed to reference the text buffer, keeping | |
1483 * it around until ownership of the clipboard is lost. | |
1484 */ | |
71 | 1485 if ((style & DWT.MULTI) !is 0) { |
60 | 1486 auto clipboard = OS.gtk_clipboard_get (cast(void*)OS.GDK_NONE); |
1487 OS.gtk_text_buffer_paste_clipboard (bufferHandle, clipboard, null, OS.gtk_text_view_get_editable (cast(GtkTextView*)handle)); | |
1488 } | |
1489 } | |
1490 message = null; | |
1491 } | |
1492 | |
1493 /** | |
1494 * Removes the listener from the collection of listeners who will | |
1495 * be notified when the receiver's text is modified. | |
1496 * | |
1497 * @param listener the listener which should no longer be notified | |
1498 * | |
1499 * @exception IllegalArgumentException <ul> | |
1500 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1501 * </ul> | |
71 | 1502 * @exception DWTException <ul> |
60 | 1503 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1504 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1505 * </ul> | |
1506 * | |
1507 * @see ModifyListener | |
1508 * @see #addModifyListener | |
1509 */ | |
1510 public void removeModifyListener (ModifyListener listener) { | |
1511 checkWidget (); | |
71 | 1512 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 1513 if (eventTable is null) return; |
71 | 1514 eventTable.unhook (DWT.Modify, listener); |
60 | 1515 } |
1516 | |
1517 /** | |
1518 * Removes the listener from the collection of listeners who will | |
1519 * be notified when the control is selected by the user. | |
1520 * | |
1521 * @param listener the listener which should no longer be notified | |
1522 * | |
1523 * @exception IllegalArgumentException <ul> | |
1524 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1525 * </ul> | |
71 | 1526 * @exception DWTException <ul> |
60 | 1527 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1528 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1529 * </ul> | |
1530 * | |
1531 * @see SelectionListener | |
1532 * @see #addSelectionListener | |
1533 */ | |
1534 public void removeSelectionListener(SelectionListener listener) { | |
1535 checkWidget (); | |
71 | 1536 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 1537 if (eventTable is null) return; |
71 | 1538 eventTable.unhook(DWT.Selection, listener); |
1539 eventTable.unhook(DWT.DefaultSelection,listener); | |
60 | 1540 } |
1541 | |
1542 /** | |
1543 * Removes the listener from the collection of listeners who will | |
1544 * be notified when the control is verified. | |
1545 * | |
1546 * @param listener the listener which should no longer be notified | |
1547 * | |
1548 * @exception IllegalArgumentException <ul> | |
1549 * <li>ERROR_NULL_ARGUMENT - if the listener is null</li> | |
1550 * </ul> | |
71 | 1551 * @exception DWTException <ul> |
60 | 1552 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1553 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1554 * </ul> | |
1555 * | |
1556 * @see VerifyListener | |
1557 * @see #addVerifyListener | |
1558 */ | |
1559 public void removeVerifyListener (VerifyListener listener) { | |
1560 checkWidget (); | |
71 | 1561 if (listener is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 1562 if (eventTable is null) return; |
71 | 1563 eventTable.unhook (DWT.Verify, listener); |
60 | 1564 } |
1565 | |
1566 /** | |
1567 * Selects all the text in the receiver. | |
1568 * | |
71 | 1569 * @exception DWTException <ul> |
60 | 1570 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1571 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1572 * </ul> | |
1573 */ | |
1574 public void selectAll () { | |
1575 checkWidget (); | |
71 | 1576 if ((style & DWT.SINGLE) !is 0) { |
60 | 1577 OS.gtk_editable_select_region (cast(GtkEditable*)handle, 0, -1); |
1578 } else { | |
1579 GtkTextIter start; | |
1580 GtkTextIter end; | |
1581 OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, &start, 0); | |
1582 OS.gtk_text_buffer_get_end_iter (bufferHandle, &end); | |
1583 auto insertMark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
1584 auto selectionMark = OS.gtk_text_buffer_get_selection_bound (bufferHandle); | |
1585 OS.gtk_text_buffer_move_mark (bufferHandle, selectionMark, &start); | |
1586 OS.gtk_text_buffer_move_mark (bufferHandle, insertMark, &end); | |
1587 } | |
1588 } | |
1589 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1590 override void setBackgroundColor (GdkColor* color) { |
60 | 1591 super.setBackgroundColor (color); |
1592 OS.gtk_widget_modify_base (handle, 0, color); | |
1593 } | |
1594 | |
113
1401263f71b0
renamed setCursor(Gtk..) to gtk_setCursor, so the public interface do not need a cast for passing null
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1595 override void gtk_setCursor (GdkCursor* cursor) { |
60 | 1596 GdkCursor* defaultCursor; |
1597 if (cursor is null) defaultCursor = OS.gdk_cursor_new (OS.GDK_XTERM); | |
113
1401263f71b0
renamed setCursor(Gtk..) to gtk_setCursor, so the public interface do not need a cast for passing null
Frank Benoit <benoit@tionex.de>
parents:
72
diff
changeset
|
1598 super.gtk_setCursor (cursor !is null ? cursor : defaultCursor); |
60 | 1599 if (cursor is null) OS.gdk_cursor_destroy (defaultCursor); |
1600 } | |
1601 | |
1602 /** | |
1603 * Sets the double click enabled flag. | |
1604 * <p> | |
1605 * The double click flag enables or disables the | |
1606 * default action of the text widget when the user | |
1607 * double clicks. | |
1608 * </p><p> | |
1609 * Note: This operation is a hint and is not supported on | |
1610 * platforms that do not have this concept. | |
1611 * </p> | |
1612 * | |
1613 * @param doubleClick the new double click flag | |
1614 * | |
71 | 1615 * @exception DWTException <ul> |
60 | 1616 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1617 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1618 * </ul> | |
1619 */ | |
1620 public void setDoubleClickEnabled (bool doubleClick) { | |
1621 checkWidget (); | |
1622 this.doubleClick = doubleClick; | |
1623 } | |
1624 | |
1625 /** | |
1626 * Sets the echo character. | |
1627 * <p> | |
1628 * The echo character is the character that is | |
1629 * displayed when the user enters text or the | |
1630 * text is changed by the programmer. Setting | |
1631 * the echo character to '\0' clears the echo | |
1632 * character and redraws the original text. | |
1633 * If for any reason the echo character is invalid, | |
1634 * or if the platform does not allow modification | |
1635 * of the echo character, the default echo character | |
1636 * for the platform is used. | |
1637 * </p> | |
1638 * | |
1639 * @param echo the new echo character | |
1640 * | |
71 | 1641 * @exception DWTException <ul> |
60 | 1642 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1643 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1644 * </ul> | |
1645 */ | |
1646 public void setEchoChar (char echo) { | |
1647 checkWidget (); | |
71 | 1648 if ((style & DWT.SINGLE) !is 0) { |
60 | 1649 OS.gtk_entry_set_visibility (cast(GtkEntry*)handle, echo is '\0'); |
1650 OS.gtk_entry_set_invisible_char (cast(GtkEntry*)handle, echo); | |
1651 } | |
1652 } | |
1653 | |
1654 /** | |
1655 * Sets the editable state. | |
1656 * | |
1657 * @param editable the new editable state | |
1658 * | |
71 | 1659 * @exception DWTException <ul> |
60 | 1660 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1661 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1662 * </ul> | |
1663 */ | |
1664 public void setEditable (bool editable) { | |
1665 checkWidget (); | |
71 | 1666 style &= ~DWT.READ_ONLY; |
1667 if (!editable) style |= DWT.READ_ONLY; | |
1668 if ((style & DWT.SINGLE) !is 0) { | |
60 | 1669 OS.gtk_editable_set_editable (cast(GtkEditable*)handle, editable); |
1670 } else { | |
1671 OS.gtk_text_view_set_editable (cast(GtkTextView*)handle, editable); | |
1672 } | |
1673 } | |
1674 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1675 override void setFontDescription (PangoFontDescription* font) { |
60 | 1676 super.setFontDescription (font); |
1677 setTabStops (tabs); | |
1678 } | |
1679 | |
1680 /** | |
1681 * Sets the widget message. When the widget is created | |
71 | 1682 * with the style <code>DWT.SEARCH</code>, the message text |
60 | 1683 * is displayed as a hint for the user, indicating the |
1684 * purpose of the field. | |
1685 * <p> | |
1686 * Note: This operation is a <em>HINT</em> and is not | |
1687 * supported on platforms that do not have this concept. | |
1688 * </p> | |
1689 * | |
1690 * @param message the new message | |
1691 * | |
1692 * @exception IllegalArgumentException <ul> | |
1693 * <li>ERROR_NULL_ARGUMENT - if the message is null</li> | |
1694 * </ul> | |
71 | 1695 * @exception DWTException <ul> |
60 | 1696 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1697 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1698 * </ul> | |
1699 * | |
1700 * @since 3.3 | |
1701 */ | |
238 | 1702 public void setMessage (String message) { |
60 | 1703 checkWidget (); |
255
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1704 // DWT extension: allow null for zero length string |
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1705 //if (message is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 1706 this.message = message; |
1707 } | |
1708 | |
1709 /** | |
1710 * Sets the orientation of the receiver, which must be one | |
71 | 1711 * of the constants <code>DWT.LEFT_TO_RIGHT</code> or <code>DWT.RIGHT_TO_LEFT</code>. |
60 | 1712 * <p> |
1713 * Note: This operation is a hint and is not supported on | |
1714 * platforms that do not have this concept. | |
1715 * </p> | |
1716 * | |
1717 * @param orientation new orientation style | |
1718 * | |
71 | 1719 * @exception DWTException <ul> |
60 | 1720 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1721 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1722 * </ul> | |
1723 * | |
1724 * @since 2.1.2 | |
1725 */ | |
1726 public void setOrientation (int orientation) { | |
1727 checkWidget(); | |
1728 } | |
1729 | |
1730 /** | |
1731 * Sets the selection. | |
1732 * <p> | |
1733 * Indexing is zero based. The range of | |
1734 * a selection is from 0..N where N is | |
1735 * the number of characters in the widget. | |
1736 * </p><p> | |
1737 * Text selections are specified in terms of | |
1738 * caret positions. In a text widget that | |
1739 * contains N characters, there are N+1 caret | |
1740 * positions, ranging from 0..N. This differs | |
1741 * from other functions that address character | |
1742 * position such as getText () that use the | |
1743 * regular array indexing rules. | |
1744 * </p> | |
1745 * | |
1746 * @param start new caret position | |
1747 * | |
71 | 1748 * @exception DWTException <ul> |
60 | 1749 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1750 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1751 * </ul> | |
1752 */ | |
1753 public void setSelection (int start) { | |
1754 checkWidget (); | |
71 | 1755 if ((style & DWT.SINGLE) !is 0) { |
60 | 1756 OS.gtk_editable_set_position (cast(GtkEditable*)handle, start); |
1757 } else { | |
1758 GtkTextIter position; | |
1759 OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, &position, start); | |
1760 OS.gtk_text_buffer_place_cursor (bufferHandle, &position); | |
1761 auto mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
1762 OS.gtk_text_view_scroll_mark_onscreen (cast(GtkTextView*)handle, mark); | |
1763 } | |
1764 } | |
1765 | |
1766 /** | |
1767 * Sets the selection to the range specified | |
1768 * by the given start and end indices. | |
1769 * <p> | |
1770 * Indexing is zero based. The range of | |
1771 * a selection is from 0..N where N is | |
1772 * the number of characters in the widget. | |
1773 * </p><p> | |
1774 * Text selections are specified in terms of | |
1775 * caret positions. In a text widget that | |
1776 * contains N characters, there are N+1 caret | |
1777 * positions, ranging from 0..N. This differs | |
1778 * from other functions that address character | |
1779 * position such as getText () that use the | |
1780 * usual array indexing rules. | |
1781 * </p> | |
1782 * | |
1783 * @param start the start of the range | |
1784 * @param end the end of the range | |
1785 * | |
71 | 1786 * @exception DWTException <ul> |
60 | 1787 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1788 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1789 * </ul> | |
1790 */ | |
1791 public void setSelection (int start, int end) { | |
1792 checkWidget (); | |
71 | 1793 if ((style & DWT.SINGLE) !is 0) { |
60 | 1794 OS.gtk_editable_set_position (cast(GtkEditable*)handle, start); |
1795 OS.gtk_editable_select_region (cast(GtkEditable*)handle, start, end); | |
1796 } else { | |
1797 GtkTextIter startIter; | |
1798 GtkTextIter endIter; | |
1799 OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, &startIter, start); | |
1800 OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, &endIter, end); | |
1801 auto insertMark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
1802 auto selectionMark = OS.gtk_text_buffer_get_selection_bound (bufferHandle); | |
1803 OS.gtk_text_buffer_move_mark (bufferHandle, selectionMark, &startIter); | |
1804 OS.gtk_text_buffer_move_mark (bufferHandle, insertMark, &endIter); | |
1805 } | |
1806 } | |
1807 | |
1808 /** | |
1809 * Sets the selection to the range specified | |
1810 * by the given point, where the x coordinate | |
1811 * represents the start index and the y coordinate | |
1812 * represents the end index. | |
1813 * <p> | |
1814 * Indexing is zero based. The range of | |
1815 * a selection is from 0..N where N is | |
1816 * the number of characters in the widget. | |
1817 * </p><p> | |
1818 * Text selections are specified in terms of | |
1819 * caret positions. In a text widget that | |
1820 * contains N characters, there are N+1 caret | |
1821 * positions, ranging from 0..N. This differs | |
1822 * from other functions that address character | |
1823 * position such as getText () that use the | |
1824 * usual array indexing rules. | |
1825 * </p> | |
1826 * | |
1827 * @param selection the point | |
1828 * | |
1829 * @exception IllegalArgumentException <ul> | |
1830 * <li>ERROR_NULL_ARGUMENT - if the point is null</li> | |
1831 * </ul> | |
71 | 1832 * @exception DWTException <ul> |
60 | 1833 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1834 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1835 * </ul> | |
1836 */ | |
1837 public void setSelection (Point selection) { | |
1838 checkWidget (); | |
71 | 1839 if (selection is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 1840 setSelection (selection.x, selection.y); |
1841 } | |
1842 | |
1843 /** | |
1844 * Sets the number of tabs. | |
1845 * <p> | |
1846 * Tab stop spacing is specified in terms of the | |
1847 * space (' ') character. The width of a single | |
1848 * tab stop is the pixel width of the spaces. | |
1849 * </p> | |
1850 * | |
1851 * @param tabs the number of tabs | |
1852 * | |
1853 * </ul> | |
71 | 1854 * @exception DWTException <ul> |
60 | 1855 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1856 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1857 * </ul> | |
1858 */ | |
1859 public void setTabs (int tabs) { | |
1860 checkWidget (); | |
1861 if (tabs < 0) return; | |
1862 setTabStops (this.tabs = tabs); | |
1863 } | |
1864 | |
1865 void setTabStops (int tabs) { | |
71 | 1866 if ((style & DWT.SINGLE) !is 0) return; |
60 | 1867 int tabWidth = getTabWidth (tabs); |
1868 auto tabArray = OS.pango_tab_array_new (1, false); | |
1869 OS.pango_tab_array_set_tab (tabArray, 0, OS.PANGO_TAB_LEFT, tabWidth); | |
1870 OS.gtk_text_view_set_tabs (cast(GtkTextView*)handle, tabArray); | |
1871 OS.pango_tab_array_free (tabArray); | |
1872 } | |
1873 | |
1874 /** | |
1875 * Sets the contents of the receiver to the given string. If the receiver has style | |
1876 * SINGLE and the argument contains multiple lines of text, the result of this | |
1877 * operation is undefined and may vary from platform to platform. | |
1878 * | |
1879 * @param string the new text | |
1880 * | |
71 | 1881 * @exception DWTException <ul> |
60 | 1882 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1883 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1884 * </ul> | |
1885 */ | |
238 | 1886 public void setText (String string) { |
60 | 1887 checkWidget (); |
255
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1888 // DWT extension: allow null for zero length string |
5a30aa9820f3
removed tango.stdc.stringz imports and allow null for arrays and string arguments.
Frank Benoit <benoit@tionex.de>
parents:
240
diff
changeset
|
1889 //if (string is null) error (DWT.ERROR_NULL_ARGUMENT); |
60 | 1890 /* |
1891 * Feature in gtk. When text is set in gtk, separate events are fired for the deletion and | |
1892 * insertion of the text. This is not wrong, but is inconsistent with other platforms. The | |
1893 * fix is to block the firing of these events and fire them ourselves in a consistent manner. | |
1894 */ | |
71 | 1895 if (hooks (DWT.Verify) || filters (DWT.Verify)) { |
60 | 1896 string = verifyText (string, 0, getCharCount ()); |
1897 if (string is null) return; | |
1898 } | |
71 | 1899 if ((style & DWT.SINGLE) !is 0) { |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1900 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1901 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1902 OS.g_signal_handlers_block_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
60 | 1903 OS.gtk_entry_set_text (cast(GtkEntry*)handle, toStringz(string) ); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1904 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1905 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_TEXT); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1906 OS.g_signal_handlers_unblock_matched (handle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udINSERT_TEXT); |
60 | 1907 } else { |
1908 GtkTextIter position; | |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1909 OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1910 OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_RANGE); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1911 OS.g_signal_handlers_block_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEXT_BUFFER_INSERT_TEXT); |
60 | 1912 OS.gtk_text_buffer_set_text (bufferHandle, string.ptr, string.length); |
66
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1913 OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udCHANGED); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1914 OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udDELETE_RANGE); |
bb2217c09e61
Fixed signal blocking/unblocking:
Frank Benoit <benoit@tionex.de>
parents:
60
diff
changeset
|
1915 OS.g_signal_handlers_unblock_matched (bufferHandle, OS.G_SIGNAL_MATCH_DATA, 0, 0, null, null, udTEXT_BUFFER_INSERT_TEXT); |
60 | 1916 OS.gtk_text_buffer_get_iter_at_offset (bufferHandle, &position, 0); |
1917 OS.gtk_text_buffer_place_cursor (bufferHandle, &position); | |
1918 auto mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
1919 OS.gtk_text_view_scroll_mark_onscreen (cast(GtkTextView*)handle, mark); | |
1920 } | |
71 | 1921 sendEvent (DWT.Modify); |
60 | 1922 } |
1923 | |
1924 /** | |
1925 * Sets the maximum number of characters that the receiver | |
1926 * is capable of holding to be the argument. | |
1927 * <p> | |
1928 * Instead of trying to set the text limit to zero, consider | |
1929 * creating a read-only text widget. | |
1930 * </p><p> | |
1931 * To reset this value to the default, use <code>setTextLimit(Text.LIMIT)</code>. | |
1932 * Specifying a limit value larger than <code>Text.LIMIT</code> sets the | |
1933 * receiver's limit to <code>Text.LIMIT</code>. | |
1934 * </p> | |
1935 * | |
1936 * @param limit new text limit | |
1937 * | |
1938 * @exception IllegalArgumentException <ul> | |
1939 * <li>ERROR_CANNOT_BE_ZERO - if the limit is zero</li> | |
1940 * </ul> | |
71 | 1941 * @exception DWTException <ul> |
60 | 1942 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1943 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1944 * </ul> | |
1945 * | |
1946 * @see #LIMIT | |
1947 */ | |
1948 public void setTextLimit (int limit) { | |
1949 checkWidget (); | |
71 | 1950 if (limit is 0) error (DWT.ERROR_CANNOT_BE_ZERO); |
1951 if ((style & DWT.SINGLE) !is 0) OS.gtk_entry_set_max_length (cast(GtkEntry*)handle, limit); | |
60 | 1952 } |
1953 | |
1954 /** | |
1955 * Sets the zero-relative index of the line which is currently | |
1956 * at the top of the receiver. This index can change when lines | |
1957 * are scrolled or new lines are added and removed. | |
1958 * | |
1959 * @param index the index of the top item | |
1960 * | |
71 | 1961 * @exception DWTException <ul> |
60 | 1962 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1963 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1964 * </ul> | |
1965 */ | |
1966 public void setTopIndex (int index) { | |
1967 checkWidget (); | |
71 | 1968 if ((style & DWT.SINGLE) !is 0) return; |
60 | 1969 GtkTextIter position; |
1970 OS.gtk_text_buffer_get_iter_at_line (bufferHandle, &position, index); | |
1971 OS.gtk_text_view_scroll_to_iter (cast(GtkTextView*)handle, &position, 0, true, 0, 0); | |
1972 } | |
1973 | |
1974 /** | |
1975 * Shows the selection. | |
1976 * <p> | |
1977 * If the selection is already showing | |
1978 * in the receiver, this method simply returns. Otherwise, | |
1979 * lines are scrolled until the selection is visible. | |
1980 * </p> | |
1981 * | |
71 | 1982 * @exception DWTException <ul> |
60 | 1983 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
1984 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
1985 * </ul> | |
1986 */ | |
1987 public void showSelection () { | |
1988 checkWidget (); | |
71 | 1989 if ((style & DWT.SINGLE) !is 0) return; |
60 | 1990 auto mark = OS.gtk_text_buffer_get_selection_bound (bufferHandle); |
1991 OS.gtk_text_view_scroll_mark_onscreen (cast(GtkTextView*)handle, mark); | |
1992 mark = OS.gtk_text_buffer_get_insert (bufferHandle); | |
1993 OS.gtk_text_view_scroll_mark_onscreen (cast(GtkTextView*)handle, mark); | |
1994 } | |
1995 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
1996 override bool translateTraversal (GdkEventKey* keyEvent) { |
60 | 1997 int key = keyEvent.keyval; |
1998 switch (key) { | |
1999 case OS.GDK_KP_Enter: | |
2000 case OS.GDK_Return: { | |
2001 auto imContext = imContext (); | |
2002 if (imContext !is null) { | |
2003 char* preeditString; | |
2004 OS.gtk_im_context_get_preedit_string (imContext, &preeditString, null, null); | |
2005 if (preeditString !is null) { | |
2006 int length = tango.stdc.string.strlen (preeditString); | |
2007 OS.g_free (preeditString); | |
2008 if (length !is 0) return false; | |
2009 } | |
2010 } | |
2011 default: | |
2012 } | |
2013 } | |
2014 return super.translateTraversal (keyEvent); | |
2015 } | |
2016 | |
152
17f8449522fd
overloads second walkthrough
Frank Benoit <benoit@tionex.de>
parents:
150
diff
changeset
|
2017 override int traversalCode (int key, GdkEventKey* event) { |
60 | 2018 int bits = super.traversalCode (key, event); |
71 | 2019 if ((style & DWT.READ_ONLY) !is 0) return bits; |
2020 if ((style & DWT.MULTI) !is 0) { | |
2021 bits &= ~DWT.TRAVERSE_RETURN; | |
60 | 2022 if (key is OS.GDK_Tab && event !is null) { |
2023 bool next = (event.state & OS.GDK_SHIFT_MASK) is 0; | |
2024 if (next && (event.state & OS.GDK_CONTROL_MASK) is 0) { | |
71 | 2025 bits &= ~(DWT.TRAVERSE_TAB_NEXT | DWT.TRAVERSE_TAB_PREVIOUS); |
60 | 2026 } |
2027 } | |
2028 } | |
2029 return bits; | |
2030 } | |
2031 | |
238 | 2032 String verifyText (String string, int start, int end) { |
60 | 2033 if (string.length is 0 && start is end) return null; |
2034 Event event = new Event (); | |
2035 event.text = string; | |
2036 event.start = start; | |
2037 event.end = end; | |
2038 auto eventPtr = OS.gtk_get_current_event (); | |
2039 if (eventPtr !is null) { | |
2040 GdkEventKey* gdkEvent = cast(GdkEventKey*)eventPtr; | |
2041 switch (gdkEvent.type) { | |
2042 case OS.GDK_KEY_PRESS: | |
2043 setKeyState (event, gdkEvent); | |
2044 break; | |
2045 default: | |
2046 } | |
2047 OS.gdk_event_free (eventPtr); | |
2048 } | |
2049 /* | |
2050 * It is possible (but unlikely), that application | |
2051 * code could have disposed the widget in the verify | |
2052 * event. If this happens, answer null to cancel | |
2053 * the operation. | |
2054 */ | |
71 | 2055 sendEvent (DWT.Verify, event); |
60 | 2056 if (!event.doit || isDisposed ()) return null; |
2057 return event.text; | |
2058 } | |
2059 | |
2060 } |