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 gtk.c.functions;
30 public  import gtk.c.types;
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(bool transferOwnership = false)
76 	{
77 		if (transferOwnership)
78 			ownedRef = false;
79 		return cast(GtkEditable*)getStruct();
80 	}
81 
82 
83 	/**
84 	 * Copies the contents of the currently selected content in the editable and
85 	 * puts it on the clipboard.
86 	 */
87 	public void copyClipboard()
88 	{
89 		gtk_editable_copy_clipboard(getEditableStruct());
90 	}
91 
92 	/**
93 	 * Removes the contents of the currently selected content in the editable and
94 	 * puts it on the clipboard.
95 	 */
96 	public void cutClipboard()
97 	{
98 		gtk_editable_cut_clipboard(getEditableStruct());
99 	}
100 
101 	/**
102 	 * Deletes the currently selected text of the editable.
103 	 * This call doesn’t do anything if there is no selected text.
104 	 */
105 	public void deleteSelection()
106 	{
107 		gtk_editable_delete_selection(getEditableStruct());
108 	}
109 
110 	/**
111 	 * Deletes a sequence of characters. The characters that are deleted are
112 	 * those characters at positions from @start_pos up to, but not including
113 	 * @end_pos. If @end_pos is negative, then the characters deleted
114 	 * are those from @start_pos to the end of the text.
115 	 *
116 	 * Note that the positions are specified in characters, not bytes.
117 	 *
118 	 * Params:
119 	 *     startPos = start position
120 	 *     endPos = end position
121 	 */
122 	public void deleteText(int startPos, int endPos)
123 	{
124 		gtk_editable_delete_text(getEditableStruct(), startPos, endPos);
125 	}
126 
127 	/**
128 	 * Retrieves a sequence of characters. The characters that are retrieved
129 	 * are those characters at positions from @start_pos up to, but not
130 	 * including @end_pos. If @end_pos is negative, then the characters
131 	 * retrieved are those characters from @start_pos to the end of the text.
132 	 *
133 	 * Note that positions are specified in characters, not bytes.
134 	 *
135 	 * Params:
136 	 *     startPos = start of text
137 	 *     endPos = end of text
138 	 *
139 	 * Returns: a pointer to the contents of the widget as a
140 	 *     string. This string is allocated by the #GtkEditable
141 	 *     implementation and should be freed by the caller.
142 	 */
143 	public string getChars(int startPos, int endPos)
144 	{
145 		auto retStr = gtk_editable_get_chars(getEditableStruct(), startPos, endPos);
146 
147 		scope(exit) Str.freeString(retStr);
148 		return Str.toString(retStr);
149 	}
150 
151 	/**
152 	 * Retrieves whether @editable is editable. See
153 	 * gtk_editable_set_editable().
154 	 *
155 	 * Returns: %TRUE if @editable is editable.
156 	 */
157 	public bool getEditable()
158 	{
159 		return gtk_editable_get_editable(getEditableStruct()) != 0;
160 	}
161 
162 	/**
163 	 * Retrieves the current position of the cursor relative to the start
164 	 * of the content of the editable.
165 	 *
166 	 * Note that this position is in characters, not in bytes.
167 	 *
168 	 * Returns: the cursor position
169 	 */
170 	public int getPosition()
171 	{
172 		return gtk_editable_get_position(getEditableStruct());
173 	}
174 
175 	/**
176 	 * Retrieves the selection bound of the editable. start_pos will be filled
177 	 * with the start of the selection and @end_pos with end. If no text was
178 	 * selected both will be identical and %FALSE will be returned.
179 	 *
180 	 * Note that positions are specified in characters, not bytes.
181 	 *
182 	 * Params:
183 	 *     startPos = location to store the starting position, or %NULL
184 	 *     endPos = location to store the end position, or %NULL
185 	 *
186 	 * Returns: %TRUE if an area is selected, %FALSE otherwise
187 	 */
188 	public bool getSelectionBounds(out int startPos, out int endPos)
189 	{
190 		return gtk_editable_get_selection_bounds(getEditableStruct(), &startPos, &endPos) != 0;
191 	}
192 
193 	/**
194 	 * Inserts @new_text_length bytes of @new_text into the contents of the
195 	 * widget, at position @position.
196 	 *
197 	 * Note that the position is in characters, not in bytes.
198 	 * The function updates @position to point after the newly inserted text.
199 	 *
200 	 * Params:
201 	 *     newText = the text to append
202 	 *     newTextLength = the length of the text in bytes, or -1
203 	 *     position = location of the position text will be inserted at
204 	 */
205 	public void insertText(string newText, int newTextLength, ref int position)
206 	{
207 		gtk_editable_insert_text(getEditableStruct(), Str.toStringz(newText), newTextLength, &position);
208 	}
209 
210 	/**
211 	 * Pastes the content of the clipboard to the current position of the
212 	 * cursor in the editable.
213 	 */
214 	public void pasteClipboard()
215 	{
216 		gtk_editable_paste_clipboard(getEditableStruct());
217 	}
218 
219 	/**
220 	 * Selects a region of text. The characters that are selected are
221 	 * those characters at positions from @start_pos up to, but not
222 	 * including @end_pos. If @end_pos is negative, then the
223 	 * characters selected are those characters from @start_pos to
224 	 * the end of the text.
225 	 *
226 	 * Note that positions are specified in characters, not bytes.
227 	 *
228 	 * Params:
229 	 *     startPos = start of region
230 	 *     endPos = end of region
231 	 */
232 	public void selectRegion(int startPos, int endPos)
233 	{
234 		gtk_editable_select_region(getEditableStruct(), startPos, endPos);
235 	}
236 
237 	/**
238 	 * Determines if the user can edit the text in the editable
239 	 * widget or not.
240 	 *
241 	 * Params:
242 	 *     isEditable = %TRUE if the user is allowed to edit the text
243 	 *         in the widget
244 	 */
245 	public void setEditable(bool isEditable)
246 	{
247 		gtk_editable_set_editable(getEditableStruct(), isEditable);
248 	}
249 
250 	/**
251 	 * Sets the cursor position in the editable to the given value.
252 	 *
253 	 * The cursor is displayed before the character with the given (base 0)
254 	 * index in the contents of the editable. The value must be less than or
255 	 * equal to the number of characters in the editable. A value of -1
256 	 * indicates that the position should be set after the last character
257 	 * of the editable. Note that @position is in characters, not in bytes.
258 	 *
259 	 * Params:
260 	 *     position = the position of the cursor
261 	 */
262 	public void setPosition(int position)
263 	{
264 		gtk_editable_set_position(getEditableStruct(), position);
265 	}
266 
267 	protected class OnChangedDelegateWrapper
268 	{
269 		void delegate(EditableIF) dlg;
270 		gulong handlerId;
271 
272 		this(void delegate(EditableIF) dlg)
273 		{
274 			this.dlg = dlg;
275 			onChangedListeners ~= this;
276 		}
277 
278 		void remove(OnChangedDelegateWrapper source)
279 		{
280 			foreach(index, wrapper; onChangedListeners)
281 			{
282 				if (wrapper.handlerId == source.handlerId)
283 				{
284 					onChangedListeners[index] = null;
285 					onChangedListeners = std.algorithm.remove(onChangedListeners, index);
286 					break;
287 				}
288 			}
289 		}
290 	}
291 	OnChangedDelegateWrapper[] onChangedListeners;
292 
293 	/**
294 	 * The ::changed signal is emitted at the end of a single
295 	 * user-visible operation on the contents of the #GtkEditable.
296 	 *
297 	 * E.g., a paste operation that replaces the contents of the
298 	 * selection will cause only one signal emission (even though it
299 	 * is implemented by first deleting the selection, then inserting
300 	 * the new content, and may cause multiple ::notify::text signals
301 	 * to be emitted).
302 	 */
303 	gulong addOnChanged(void delegate(EditableIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
304 	{
305 		auto wrapper = new OnChangedDelegateWrapper(dlg);
306 		wrapper.handlerId = Signals.connectData(
307 			this,
308 			"changed",
309 			cast(GCallback)&callBackChanged,
310 			cast(void*)wrapper,
311 			cast(GClosureNotify)&callBackChangedDestroy,
312 			connectFlags);
313 		return wrapper.handlerId;
314 	}
315 
316 	extern(C) static void callBackChanged(GtkEditable* editableStruct, OnChangedDelegateWrapper wrapper)
317 	{
318 		wrapper.dlg(wrapper.outer);
319 	}
320 
321 	extern(C) static void callBackChangedDestroy(OnChangedDelegateWrapper wrapper, GClosure* closure)
322 	{
323 		wrapper.remove(wrapper);
324 	}
325 
326 	protected class OnDeleteTextDelegateWrapper
327 	{
328 		void delegate(int, int, EditableIF) dlg;
329 		gulong handlerId;
330 
331 		this(void delegate(int, int, EditableIF) dlg)
332 		{
333 			this.dlg = dlg;
334 			onDeleteTextListeners ~= this;
335 		}
336 
337 		void remove(OnDeleteTextDelegateWrapper source)
338 		{
339 			foreach(index, wrapper; onDeleteTextListeners)
340 			{
341 				if (wrapper.handlerId == source.handlerId)
342 				{
343 					onDeleteTextListeners[index] = null;
344 					onDeleteTextListeners = std.algorithm.remove(onDeleteTextListeners, index);
345 					break;
346 				}
347 			}
348 		}
349 	}
350 	OnDeleteTextDelegateWrapper[] onDeleteTextListeners;
351 
352 	/**
353 	 * This signal is emitted when text is deleted from
354 	 * the widget by the user. The default handler for
355 	 * this signal will normally be responsible for deleting
356 	 * the text, so by connecting to this signal and then
357 	 * stopping the signal with g_signal_stop_emission(), it
358 	 * is possible to modify the range of deleted text, or
359 	 * prevent it from being deleted entirely. The @start_pos
360 	 * and @end_pos parameters are interpreted as for
361 	 * gtk_editable_delete_text().
362 	 *
363 	 * Params:
364 	 *     startPos = the starting position
365 	 *     endPos = the end position
366 	 */
367 	gulong addOnDeleteText(void delegate(int, int, EditableIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
368 	{
369 		auto wrapper = new OnDeleteTextDelegateWrapper(dlg);
370 		wrapper.handlerId = Signals.connectData(
371 			this,
372 			"delete-text",
373 			cast(GCallback)&callBackDeleteText,
374 			cast(void*)wrapper,
375 			cast(GClosureNotify)&callBackDeleteTextDestroy,
376 			connectFlags);
377 		return wrapper.handlerId;
378 	}
379 
380 	extern(C) static void callBackDeleteText(GtkEditable* editableStruct, int startPos, int endPos, OnDeleteTextDelegateWrapper wrapper)
381 	{
382 		wrapper.dlg(startPos, endPos, wrapper.outer);
383 	}
384 
385 	extern(C) static void callBackDeleteTextDestroy(OnDeleteTextDelegateWrapper wrapper, GClosure* closure)
386 	{
387 		wrapper.remove(wrapper);
388 	}
389 
390 	protected class OnInsertTextDelegateWrapper
391 	{
392 		void delegate(string, int, void*, EditableIF) dlg;
393 		gulong handlerId;
394 
395 		this(void delegate(string, int, void*, EditableIF) dlg)
396 		{
397 			this.dlg = dlg;
398 			onInsertTextListeners ~= this;
399 		}
400 
401 		void remove(OnInsertTextDelegateWrapper source)
402 		{
403 			foreach(index, wrapper; onInsertTextListeners)
404 			{
405 				if (wrapper.handlerId == source.handlerId)
406 				{
407 					onInsertTextListeners[index] = null;
408 					onInsertTextListeners = std.algorithm.remove(onInsertTextListeners, index);
409 					break;
410 				}
411 			}
412 		}
413 	}
414 	OnInsertTextDelegateWrapper[] onInsertTextListeners;
415 
416 	/**
417 	 * This signal is emitted when text is inserted into
418 	 * the widget by the user. The default handler for
419 	 * this signal will normally be responsible for inserting
420 	 * the text, so by connecting to this signal and then
421 	 * stopping the signal with g_signal_stop_emission(), it
422 	 * is possible to modify the inserted text, or prevent
423 	 * it from being inserted entirely.
424 	 *
425 	 * Params:
426 	 *     newText = the new text to insert
427 	 *     newTextLength = the length of the new text, in bytes,
428 	 *         or -1 if new_text is nul-terminated
429 	 *     position = the position, in characters,
430 	 *         at which to insert the new text. this is an in-out
431 	 *         parameter.  After the signal emission is finished, it
432 	 *         should point after the newly inserted text.
433 	 */
434 	gulong addOnInsertText(void delegate(string, int, void*, EditableIF) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
435 	{
436 		auto wrapper = new OnInsertTextDelegateWrapper(dlg);
437 		wrapper.handlerId = Signals.connectData(
438 			this,
439 			"insert-text",
440 			cast(GCallback)&callBackInsertText,
441 			cast(void*)wrapper,
442 			cast(GClosureNotify)&callBackInsertTextDestroy,
443 			connectFlags);
444 		return wrapper.handlerId;
445 	}
446 
447 	extern(C) static void callBackInsertText(GtkEditable* editableStruct, char* newText, int newTextLength, void* position, OnInsertTextDelegateWrapper wrapper)
448 	{
449 		wrapper.dlg(Str.toString(newText), newTextLength, position, wrapper.outer);
450 	}
451 
452 	extern(C) static void callBackInsertTextDestroy(OnInsertTextDelegateWrapper wrapper, GClosure* closure)
453 	{
454 		wrapper.remove(wrapper);
455 	}
456 }