1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gtk.EditableT;
26 
27 public  import glib.Str;
28 public  import gobject.Signals;
29 public  import gtkc.gdktypes;
30 public  import gtkc.gtk;
31 public  import gtkc.gtktypes;
32 public  import std.algorithm;
33 
34 
35 /**
36  * The #GtkEditable interface is an interface which should be implemented by
37  * text editing widgets, such as #GtkEntry and #GtkSpinButton. It contains functions
38  * for generically manipulating an editable widget, a large number of action
39  * signals used for key bindings, and several signals that an application can
40  * connect to to modify the behavior of a widget.
41  * 
42  * As an example of the latter usage, by connecting
43  * the following handler to #GtkEditable::insert-text, an application
44  * can convert all entry into a widget into uppercase.
45  * 
46  * ## Forcing entry to uppercase.
47  * 
48  * |[<!-- language="C" -->
49  * #include <ctype.h>;
50  * 
51  * void
52  * insert_text_handler (GtkEditable *editable,
53  * const gchar *text,
54  * gint         length,
55  * gint        *position,
56  * gpointer     data)
57  * {
58  * gchar *result = g_utf8_strup (text, length);
59  * 
60  * g_signal_handlers_block_by_func (editable,
61  * (gpointer) insert_text_handler, data);
62  * gtk_editable_insert_text (editable, result, length, position);
63  * g_signal_handlers_unblock_by_func (editable,
64  * (gpointer) insert_text_handler, data);
65  * 
66  * g_signal_stop_emission_by_name (editable, "insert_text");
67  * 
68  * g_free (result);
69  * }
70  * ]|
71  */
72 public template EditableT(TStruct)
73 {
74 	/** Get the main Gtk struct */
75 	public GtkEditable* getEditableStruct()
76 	{
77 		return cast(GtkEditable*)getStruct();
78 	}
79 
80 
81 	/**
82 	 * Copies the contents of the currently selected content in the editable and
83 	 * puts it on the clipboard.
84 	 */
85 	public void copyClipboard()
86 	{
87 		gtk_editable_copy_clipboard(getEditableStruct());
88 	}
89 
90 	/**
91 	 * Removes the contents of the currently selected content in the editable and
92 	 * puts it on the clipboard.
93 	 */
94 	public void cutClipboard()
95 	{
96 		gtk_editable_cut_clipboard(getEditableStruct());
97 	}
98 
99 	/**
100 	 * Deletes the currently selected text of the editable.
101 	 * This call doesn’t do anything if there is no selected text.
102 	 */
103 	public void deleteSelection()
104 	{
105 		gtk_editable_delete_selection(getEditableStruct());
106 	}
107 
108 	/**
109 	 * Deletes a sequence of characters. The characters that are deleted are
110 	 * those characters at positions from @start_pos up to, but not including
111 	 * @end_pos. If @end_pos is negative, then the characters deleted
112 	 * are those from @start_pos to the end of the text.
113 	 *
114 	 * Note that the positions are specified in characters, not bytes.
115 	 *
116 	 * Params:
117 	 *     startPos = start position
118 	 *     endPos = end position
119 	 */
120 	public void deleteText(int startPos, int endPos)
121 	{
122 		gtk_editable_delete_text(getEditableStruct(), startPos, endPos);
123 	}
124 
125 	/**
126 	 * Retrieves a sequence of characters. The characters that are retrieved
127 	 * are those characters at positions from @start_pos up to, but not
128 	 * including @end_pos. If @end_pos is negative, then the characters
129 	 * retrieved are those characters from @start_pos to the end of the text.
130 	 *
131 	 * Note that positions are specified in characters, not bytes.
132 	 *
133 	 * Params:
134 	 *     startPos = start of text
135 	 *     endPos = end of text
136 	 *
137 	 * Return: a pointer to the contents of the widget as a
138 	 *     string. This string is allocated by the #GtkEditable
139 	 *     implementation and should be freed by the caller.
140 	 */
141 	public string getChars(int startPos, int endPos)
142 	{
143 		auto retStr = gtk_editable_get_chars(getEditableStruct(), startPos, endPos);
144 		
145 		scope(exit) Str.freeString(retStr);
146 		return Str.toString(retStr);
147 	}
148 
149 	/**
150 	 * Retrieves whether @editable is editable. See
151 	 * gtk_editable_set_editable().
152 	 *
153 	 * Return: %TRUE if @editable is editable.
154 	 */
155 	public bool getEditable()
156 	{
157 		return gtk_editable_get_editable(getEditableStruct()) != 0;
158 	}
159 
160 	/**
161 	 * Retrieves the current position of the cursor relative to the start
162 	 * of the content of the editable.
163 	 *
164 	 * Note that this position is in characters, not in bytes.
165 	 *
166 	 * Return: the cursor position
167 	 */
168 	public int getPosition()
169 	{
170 		return gtk_editable_get_position(getEditableStruct());
171 	}
172 
173 	/**
174 	 * Retrieves the selection bound of the editable. start_pos will be filled
175 	 * with the start of the selection and @end_pos with end. If no text was
176 	 * selected both will be identical and %FALSE will be returned.
177 	 *
178 	 * Note that positions are specified in characters, not bytes.
179 	 *
180 	 * Params:
181 	 *     startPos = location to store the starting position, or %NULL
182 	 *     endPos = location to store the end position, or %NULL
183 	 *
184 	 * Return: %TRUE if an area is selected, %FALSE otherwise
185 	 */
186 	public bool getSelectionBounds(out int startPos, out int endPos)
187 	{
188 		return gtk_editable_get_selection_bounds(getEditableStruct(), &startPos, &endPos) != 0;
189 	}
190 
191 	/**
192 	 * Inserts @new_text_length bytes of @new_text into the contents of the
193 	 * widget, at position @position.
194 	 *
195 	 * Note that the position is in characters, not in bytes.
196 	 * The function updates @position to point after the newly inserted text.
197 	 *
198 	 * Params:
199 	 *     newText = the text to append
200 	 *     newTextLength = the length of the text in bytes, or -1
201 	 *     position = location of the position text will be inserted at
202 	 */
203 	public void insertText(string newText, int newTextLength, ref int position)
204 	{
205 		gtk_editable_insert_text(getEditableStruct(), Str.toStringz(newText), newTextLength, &position);
206 	}
207 
208 	/**
209 	 * Pastes the content of the clipboard to the current position of the
210 	 * cursor in the editable.
211 	 */
212 	public void pasteClipboard()
213 	{
214 		gtk_editable_paste_clipboard(getEditableStruct());
215 	}
216 
217 	/**
218 	 * Selects a region of text. The characters that are selected are
219 	 * those characters at positions from @start_pos up to, but not
220 	 * including @end_pos. If @end_pos is negative, then the
221 	 * characters selected are those characters from @start_pos to
222 	 * the end of the text.
223 	 *
224 	 * Note that positions are specified in characters, not bytes.
225 	 *
226 	 * Params:
227 	 *     startPos = start of region
228 	 *     endPos = end of region
229 	 */
230 	public void selectRegion(int startPos, int endPos)
231 	{
232 		gtk_editable_select_region(getEditableStruct(), startPos, endPos);
233 	}
234 
235 	/**
236 	 * Determines if the user can edit the text in the editable
237 	 * widget or not.
238 	 *
239 	 * Params:
240 	 *     isEditable = %TRUE if the user is allowed to edit the text
241 	 *         in the widget
242 	 */
243 	public void setEditable(bool isEditable)
244 	{
245 		gtk_editable_set_editable(getEditableStruct(), isEditable);
246 	}
247 
248 	/**
249 	 * Sets the cursor position in the editable to the given value.
250 	 *
251 	 * The cursor is displayed before the character with the given (base 0)
252 	 * index in the contents of the editable. The value must be less than or
253 	 * equal to the number of characters in the editable. A value of -1
254 	 * indicates that the position should be set after the last character
255 	 * of the editable. Note that @position is in characters, not in bytes.
256 	 *
257 	 * Params:
258 	 *     position = the position of the cursor
259 	 */
260 	public void setPosition(int position)
261 	{
262 		gtk_editable_set_position(getEditableStruct(), position);
263 	}
264 
265 	protected class OnChangedDelegateWrapper
266 	{
267 		void delegate(EditableIF) dlg;
268 		gulong handlerId;
269 		ConnectFlags flags;
270 		this(void delegate(EditableIF) dlg, gulong handlerId, ConnectFlags flags)
271 		{
272 			this.dlg = dlg;
273 			this.handlerId = handlerId;
274 			this.flags = flags;
275 		}
276 	}
277 	protected OnChangedDelegateWrapper[] onChangedListeners;
278 
279 	/**
280 	 * The ::changed signal is emitted at the end of a single
281 	 * user-visible operation on the contents of the #GtkEditable.
282 	 *
283 	 * E.g., a paste operation that replaces the contents of the
284 	 * selection will cause only one signal emission (even though it
285 	 * is implemented by first deleting the selection, then inserting
286 	 * the new content, and may cause multiple ::notify::text signals
287 	 * to be emitted).
288 	 */
289 	gulong addOnChanged(void delegate(EditableIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
290 	{
291 		onChangedListeners ~= new OnChangedDelegateWrapper(dlg, 0, connectFlags);
292 		onChangedListeners[onChangedListeners.length - 1].handlerId = Signals.connectData(
293 			this,
294 			"changed",
295 			cast(GCallback)&callBackChanged,
296 			cast(void*)onChangedListeners[onChangedListeners.length - 1],
297 			cast(GClosureNotify)&callBackChangedDestroy,
298 			connectFlags);
299 		return onChangedListeners[onChangedListeners.length - 1].handlerId;
300 	}
301 	
302 	extern(C) static void callBackChanged(GtkEditable* editableStruct,OnChangedDelegateWrapper wrapper)
303 	{
304 		wrapper.dlg(wrapper.outer);
305 	}
306 	
307 	extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure)
308 	{
309 		wrapper.outer.internalRemoveOnChanged(wrapper);
310 	}
311 
312 	protected void internalRemoveOnChanged(OnChangedDelegateWrapper source)
313 	{
314 		foreach(index, wrapper; onChangedListeners)
315 		{
316 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
317 			{
318 				onChangedListeners[index] = null;
319 				onChangedListeners = std.algorithm.remove(onChangedListeners, index);
320 				break;
321 			}
322 		}
323 	}
324 	
325 
326 	protected class OnDeleteTextDelegateWrapper
327 	{
328 		void delegate(int, int, EditableIF) dlg;
329 		gulong handlerId;
330 		ConnectFlags flags;
331 		this(void delegate(int, int, EditableIF) dlg, gulong handlerId, ConnectFlags flags)
332 		{
333 			this.dlg = dlg;
334 			this.handlerId = handlerId;
335 			this.flags = flags;
336 		}
337 	}
338 	protected OnDeleteTextDelegateWrapper[] onDeleteTextListeners;
339 
340 	/**
341 	 * This signal is emitted when text is deleted from
342 	 * the widget by the user. The default handler for
343 	 * this signal will normally be responsible for deleting
344 	 * the text, so by connecting to this signal and then
345 	 * stopping the signal with g_signal_stop_emission(), it
346 	 * is possible to modify the range of deleted text, or
347 	 * prevent it from being deleted entirely. The @start_pos
348 	 * and @end_pos parameters are interpreted as for
349 	 * gtk_editable_delete_text().
350 	 *
351 	 * Params:
352 	 *     startPos = the starting position
353 	 *     endPos = the end position
354 	 */
355 	gulong addOnDeleteText(void delegate(int, int, EditableIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
356 	{
357 		onDeleteTextListeners ~= new OnDeleteTextDelegateWrapper(dlg, 0, connectFlags);
358 		onDeleteTextListeners[onDeleteTextListeners.length - 1].handlerId = Signals.connectData(
359 			this,
360 			"delete-text",
361 			cast(GCallback)&callBackDeleteText,
362 			cast(void*)onDeleteTextListeners[onDeleteTextListeners.length - 1],
363 			cast(GClosureNotify)&callBackDeleteTextDestroy,
364 			connectFlags);
365 		return onDeleteTextListeners[onDeleteTextListeners.length - 1].handlerId;
366 	}
367 	
368 	extern(C) static void callBackDeleteText(GtkEditable* editableStruct, int startPos, int endPos,OnDeleteTextDelegateWrapper wrapper)
369 	{
370 		wrapper.dlg(startPos, endPos, wrapper.outer);
371 	}
372 	
373 	extern(C) static void callBackDeleteTextDestroy(OnDeleteTextDelegateWrapper wrapper, GClosure* closure)
374 	{
375 		wrapper.outer.internalRemoveOnDeleteText(wrapper);
376 	}
377 
378 	protected void internalRemoveOnDeleteText(OnDeleteTextDelegateWrapper source)
379 	{
380 		foreach(index, wrapper; onDeleteTextListeners)
381 		{
382 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
383 			{
384 				onDeleteTextListeners[index] = null;
385 				onDeleteTextListeners = std.algorithm.remove(onDeleteTextListeners, index);
386 				break;
387 			}
388 		}
389 	}
390 	
391 
392 	protected class OnInsertTextDelegateWrapper
393 	{
394 		void delegate(string, int, void*, EditableIF) dlg;
395 		gulong handlerId;
396 		ConnectFlags flags;
397 		this(void delegate(string, int, void*, EditableIF) dlg, gulong handlerId, ConnectFlags flags)
398 		{
399 			this.dlg = dlg;
400 			this.handlerId = handlerId;
401 			this.flags = flags;
402 		}
403 	}
404 	protected OnInsertTextDelegateWrapper[] onInsertTextListeners;
405 
406 	/**
407 	 * This signal is emitted when text is inserted into
408 	 * the widget by the user. The default handler for
409 	 * this signal will normally be responsible for inserting
410 	 * the text, so by connecting to this signal and then
411 	 * stopping the signal with g_signal_stop_emission(), it
412 	 * is possible to modify the inserted text, or prevent
413 	 * it from being inserted entirely.
414 	 *
415 	 * Params:
416 	 *     newText = the new text to insert
417 	 *     newTextLength = the length of the new text, in bytes,
418 	 *         or -1 if new_text is nul-terminated
419 	 *     position = the position, in characters,
420 	 *         at which to insert the new text. this is an in-out
421 	 *         parameter.  After the signal emission is finished, it
422 	 *         should point after the newly inserted text.
423 	 */
424 	gulong addOnInsertText(void delegate(string, int, void*, EditableIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
425 	{
426 		onInsertTextListeners ~= new OnInsertTextDelegateWrapper(dlg, 0, connectFlags);
427 		onInsertTextListeners[onInsertTextListeners.length - 1].handlerId = Signals.connectData(
428 			this,
429 			"insert-text",
430 			cast(GCallback)&callBackInsertText,
431 			cast(void*)onInsertTextListeners[onInsertTextListeners.length - 1],
432 			cast(GClosureNotify)&callBackInsertTextDestroy,
433 			connectFlags);
434 		return onInsertTextListeners[onInsertTextListeners.length - 1].handlerId;
435 	}
436 	
437 	extern(C) static void callBackInsertText(GtkEditable* editableStruct, char* newText, int newTextLength, void* position,OnInsertTextDelegateWrapper wrapper)
438 	{
439 		wrapper.dlg(Str.toString(newText), newTextLength, position, wrapper.outer);
440 	}
441 	
442 	extern(C) static void callBackInsertTextDestroy(OnInsertTextDelegateWrapper wrapper, GClosure* closure)
443 	{
444 		wrapper.outer.internalRemoveOnInsertText(wrapper);
445 	}
446 
447 	protected void internalRemoveOnInsertText(OnInsertTextDelegateWrapper source)
448 	{
449 		foreach(index, wrapper; onInsertTextListeners)
450 		{
451 			if (wrapper.dlg == source.dlg && wrapper.flags == source.flags && wrapper.handlerId == source.handlerId)
452 			{
453 				onInsertTextListeners[index] = null;
454 				onInsertTextListeners = std.algorithm.remove(onInsertTextListeners, index);
455 				break;
456 			}
457 		}
458 	}
459 	
460 }