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