]> Pileus Git - ~andy/gtk/blob - gtk/gtkeditable.c
gdk/x11: Add gdk_x11_device_manager_lookup()
[~andy/gtk] / gtk / gtkeditable.c
1 /* GTK - The GIMP Toolkit
2  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GTK+ Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /**
28  * SECTION:gtkeditable
29  * @Short_description: Interface for text-editing widgets
30  * @Title: GtkEditable
31  *
32  * The #GtkEditable interface is an interface which should be implemented by
33  * text editing widgets, such as #GtkEntry and #GtkText. It contains functions
34  * for generically manipulating an editable widget, a large number of action
35  * signals used for key bindings, and several signals that an application can
36  * connect to to modify the behavior of a widget.
37  *
38  * As an example of the latter usage, by connecting
39  * the following handler to "insert_text", an application
40  * can convert all entry into a widget into uppercase.
41  *
42  * <example>
43  * <title>Forcing entry to uppercase.</title>
44  * <programlisting>
45  * #include &lt;ctype.h&gt;
46  *
47  * void
48  * insert_text_handler (GtkEditable &ast;editable,
49  *                      const gchar &ast;text,
50  *                      gint         length,
51  *                      gint        &ast;position,
52  *                      gpointer     data)
53  * {
54  *   gchar &ast;result = g_utf8_strup (text, length);
55  *
56  *   g_signal_handlers_block_by_func (editable,
57  *                                (gpointer) insert_text_handler, data);
58  *   gtk_editable_insert_text (editable, result, length, position);
59  *   g_signal_handlers_unblock_by_func (editable,
60  *                                      (gpointer) insert_text_handler, data);
61  *
62  *   g_signal_stop_emission_by_name (editable, "insert_text");
63  *
64  *   g_free (result);
65  * }
66  * </programlisting>
67  * </example>
68  */
69
70 #include "config.h"
71 #include <string.h>
72
73 #include "gtkeditable.h"
74 #include "gtkmarshalers.h"
75 #include "gtkintl.h"
76
77
78 static void gtk_editable_base_init (gpointer g_class);
79
80
81 GType
82 gtk_editable_get_type (void)
83 {
84   static GType editable_type = 0;
85
86   if (!editable_type)
87     {
88       const GTypeInfo editable_info =
89       {
90         sizeof (GtkEditableInterface),  /* class_size */
91         gtk_editable_base_init,     /* base_init */
92         NULL,                       /* base_finalize */
93       };
94
95       editable_type = g_type_register_static (G_TYPE_INTERFACE, I_("GtkEditable"),
96                                               &editable_info, 0);
97     }
98
99   return editable_type;
100 }
101
102 static void
103 gtk_editable_base_init (gpointer g_class)
104 {
105   static gboolean initialized = FALSE;
106
107   if (! initialized)
108     {
109       /**
110        * GtkEditable::insert-text:
111        * @editable: the object which received the signal
112        * @new_text: the new text to insert
113        * @new_text_length: the length of the new text, in bytes,
114        *     or -1 if new_text is nul-terminated
115        * @position: (inout) (type int): the position, in characters,
116        *     at which to insert the new text. this is an in-out
117        *     parameter.  After the signal emission is finished, it
118        *     should point after the newly inserted text.
119        *
120        * This signal is emitted when text is inserted into
121        * the widget by the user. The default handler for
122        * this signal will normally be responsible for inserting
123        * the text, so by connecting to this signal and then
124        * stopping the signal with g_signal_stop_emission(), it
125        * is possible to modify the inserted text, or prevent
126        * it from being inserted entirely.
127        */
128       g_signal_new (I_("insert-text"),
129                     GTK_TYPE_EDITABLE,
130                     G_SIGNAL_RUN_LAST,
131                     G_STRUCT_OFFSET (GtkEditableInterface, insert_text),
132                     NULL, NULL,
133                     _gtk_marshal_VOID__STRING_INT_POINTER,
134                     G_TYPE_NONE, 3,
135                     G_TYPE_STRING,
136                     G_TYPE_INT,
137                     G_TYPE_POINTER);
138
139       /**
140        * GtkEditable::delete-text:
141        * @editable: the object which received the signal
142        * @start_pos: the starting position
143        * @end_pos: the end position
144        * 
145        * This signal is emitted when text is deleted from
146        * the widget by the user. The default handler for
147        * this signal will normally be responsible for deleting
148        * the text, so by connecting to this signal and then
149        * stopping the signal with g_signal_stop_emission(), it
150        * is possible to modify the range of deleted text, or
151        * prevent it from being deleted entirely. The @start_pos
152        * and @end_pos parameters are interpreted as for
153        * gtk_editable_delete_text().
154        */
155       g_signal_new (I_("delete-text"),
156                     GTK_TYPE_EDITABLE,
157                     G_SIGNAL_RUN_LAST,
158                     G_STRUCT_OFFSET (GtkEditableInterface, delete_text),
159                     NULL, NULL,
160                     _gtk_marshal_VOID__INT_INT,
161                     G_TYPE_NONE, 2,
162                     G_TYPE_INT,
163                     G_TYPE_INT);
164       /**
165        * GtkEditable::changed:
166        * @editable: the object which received the signal
167        *
168        * The ::changed signal is emitted at the end of a single
169        * user-visible operation on the contents of the #GtkEditable.
170        *
171        * E.g., a paste operation that replaces the contents of the
172        * selection will cause only one signal emission (even though it
173        * is implemented by first deleting the selection, then inserting
174        * the new content, and may cause multiple ::notify::text signals
175        * to be emitted).
176        */ 
177       g_signal_new (I_("changed"),
178                     GTK_TYPE_EDITABLE,
179                     G_SIGNAL_RUN_LAST,
180                     G_STRUCT_OFFSET (GtkEditableInterface, changed),
181                     NULL, NULL,
182                     _gtk_marshal_VOID__VOID,
183                     G_TYPE_NONE, 0);
184
185       initialized = TRUE;
186     }
187 }
188
189 /**
190  * gtk_editable_insert_text:
191  * @editable: a #GtkEditable
192  * @new_text: the text to append
193  * @new_text_length: the length of the text in bytes, or -1
194  * @position: (inout): location of the position text will be inserted at
195  *
196  * Inserts @new_text_length bytes of @new_text into the contents of the
197  * widget, at position @position.
198  *
199  * Note that the position is in characters, not in bytes. 
200  * The function updates @position to point after the newly inserted text.
201  *
202  * Virtual: do_insert_text
203  */
204 void
205 gtk_editable_insert_text (GtkEditable *editable,
206                           const gchar *new_text,
207                           gint         new_text_length,
208                           gint        *position)
209 {
210   g_return_if_fail (GTK_IS_EDITABLE (editable));
211   g_return_if_fail (position != NULL);
212
213   if (new_text_length < 0)
214     new_text_length = strlen (new_text);
215   
216   GTK_EDITABLE_GET_IFACE (editable)->do_insert_text (editable, new_text, new_text_length, position);
217 }
218
219 /**
220  * gtk_editable_delete_text:
221  * @editable: a #GtkEditable
222  * @start_pos: start position
223  * @end_pos: end position
224  *
225  * Deletes a sequence of characters. The characters that are deleted are 
226  * those characters at positions from @start_pos up to, but not including 
227  * @end_pos. If @end_pos is negative, then the the characters deleted
228  * are those from @start_pos to the end of the text.
229  *
230  * Note that the positions are specified in characters, not bytes.
231  *
232  * Virtual: do_delete_text
233  */
234 void
235 gtk_editable_delete_text (GtkEditable *editable,
236                           gint         start_pos,
237                           gint         end_pos)
238 {
239   g_return_if_fail (GTK_IS_EDITABLE (editable));
240
241   GTK_EDITABLE_GET_IFACE (editable)->do_delete_text (editable, start_pos, end_pos);
242 }
243
244 /**
245  * gtk_editable_get_chars:
246  * @editable: a #GtkEditable
247  * @start_pos: start of text
248  * @end_pos: end of text
249  *
250  * Retrieves a sequence of characters. The characters that are retrieved 
251  * are those characters at positions from @start_pos up to, but not 
252  * including @end_pos. If @end_pos is negative, then the the characters 
253  * retrieved are those characters from @start_pos to the end of the text.
254  * 
255  * Note that positions are specified in characters, not bytes.
256  *
257  * Return value: a pointer to the contents of the widget as a
258  *      string. This string is allocated by the #GtkEditable
259  *      implementation and should be freed by the caller.
260  */
261 gchar *    
262 gtk_editable_get_chars (GtkEditable *editable,
263                         gint         start_pos,
264                         gint         end_pos)
265 {
266   g_return_val_if_fail (GTK_IS_EDITABLE (editable), NULL);
267
268   return GTK_EDITABLE_GET_IFACE (editable)->get_chars (editable, start_pos, end_pos);
269 }
270
271 /**
272  * gtk_editable_set_position:
273  * @editable: a #GtkEditable
274  * @position: the position of the cursor 
275  *
276  * Sets the cursor position in the editable to the given value.
277  *
278  * The cursor is displayed before the character with the given (base 0) 
279  * index in the contents of the editable. The value must be less than or 
280  * equal to the number of characters in the editable. A value of -1 
281  * indicates that the position should be set after the last character 
282  * of the editable. Note that @position is in characters, not in bytes.
283  */
284 void
285 gtk_editable_set_position (GtkEditable      *editable,
286                            gint              position)
287 {
288   g_return_if_fail (GTK_IS_EDITABLE (editable));
289
290   GTK_EDITABLE_GET_IFACE (editable)->set_position (editable, position);
291 }
292
293 /**
294  * gtk_editable_get_position:
295  * @editable: a #GtkEditable
296  *
297  * Retrieves the current position of the cursor relative to the start
298  * of the content of the editable. 
299  * 
300  * Note that this position is in characters, not in bytes.
301  *
302  * Return value: the cursor position
303  */
304 gint
305 gtk_editable_get_position (GtkEditable *editable)
306 {
307   g_return_val_if_fail (GTK_IS_EDITABLE (editable), 0);
308
309   return GTK_EDITABLE_GET_IFACE (editable)->get_position (editable);
310 }
311
312 /**
313  * gtk_editable_get_selection_bounds:
314  * @editable: a #GtkEditable
315  * @start_pos: (out) (allow-none): location to store the starting position, or %NULL
316  * @end_pos: (out) (allow-none): location to store the end position, or %NULL
317  *
318  * Retrieves the selection bound of the editable. start_pos will be filled
319  * with the start of the selection and @end_pos with end. If no text was
320  * selected both will be identical and %FALSE will be returned.
321  *
322  * Note that positions are specified in characters, not bytes.
323  *
324  * Return value: %TRUE if an area is selected, %FALSE otherwise
325  */
326 gboolean
327 gtk_editable_get_selection_bounds (GtkEditable *editable,
328                                    gint        *start_pos,
329                                    gint        *end_pos)
330 {
331   gint tmp_start, tmp_end;
332   gboolean result;
333   
334   g_return_val_if_fail (GTK_IS_EDITABLE (editable), FALSE);
335
336   result = GTK_EDITABLE_GET_IFACE (editable)->get_selection_bounds (editable, &tmp_start, &tmp_end);
337
338   if (start_pos)
339     *start_pos = MIN (tmp_start, tmp_end);
340   if (end_pos)
341     *end_pos = MAX (tmp_start, tmp_end);
342
343   return result;
344 }
345
346 /**
347  * gtk_editable_delete_selection:
348  * @editable: a #GtkEditable
349  *
350  * Deletes the currently selected text of the editable.
351  * This call doesn't do anything if there is no selected text.
352  */
353 void
354 gtk_editable_delete_selection (GtkEditable *editable)
355 {
356   gint start, end;
357
358   g_return_if_fail (GTK_IS_EDITABLE (editable));
359
360   if (gtk_editable_get_selection_bounds (editable, &start, &end))
361     gtk_editable_delete_text (editable, start, end);
362 }
363
364 /**
365  * gtk_editable_select_region:
366  * @editable: a #GtkEditable
367  * @start_pos: start of region
368  * @end_pos: end of region
369  *
370  * Selects a region of text. The characters that are selected are 
371  * those characters at positions from @start_pos up to, but not 
372  * including @end_pos. If @end_pos is negative, then the the 
373  * characters selected are those characters from @start_pos to 
374  * the end of the text.
375  * 
376  * Note that positions are specified in characters, not bytes.
377  *
378  * Virtual: set_selection_bounds
379  */
380 void
381 gtk_editable_select_region (GtkEditable *editable,
382                             gint         start_pos,
383                             gint         end_pos)
384 {
385   g_return_if_fail (GTK_IS_EDITABLE (editable));
386   
387   GTK_EDITABLE_GET_IFACE (editable)->set_selection_bounds (editable, start_pos, end_pos);
388 }
389
390 /**
391  * gtk_editable_cut_clipboard:
392  * @editable: a #GtkEditable
393  *
394  * Removes the contents of the currently selected content in the editable and
395  * puts it on the clipboard.
396  */
397 void
398 gtk_editable_cut_clipboard (GtkEditable *editable)
399 {
400   g_return_if_fail (GTK_IS_EDITABLE (editable));
401   
402   g_signal_emit_by_name (editable, "cut-clipboard");
403 }
404
405 /**
406  * gtk_editable_copy_clipboard:
407  * @editable: a #GtkEditable
408  *
409  * Copies the contents of the currently selected content in the editable and
410  * puts it on the clipboard.
411  */
412 void
413 gtk_editable_copy_clipboard (GtkEditable *editable)
414 {
415   g_return_if_fail (GTK_IS_EDITABLE (editable));
416   
417   g_signal_emit_by_name (editable, "copy-clipboard");
418 }
419
420 /**
421  * gtk_editable_paste_clipboard:
422  * @editable: a #GtkEditable
423  *
424  * Pastes the content of the clipboard to the current position of the
425  * cursor in the editable.
426  */
427 void
428 gtk_editable_paste_clipboard (GtkEditable *editable)
429 {
430   g_return_if_fail (GTK_IS_EDITABLE (editable));
431   
432   g_signal_emit_by_name (editable, "paste-clipboard");
433 }
434
435 /**
436  * gtk_editable_set_editable:
437  * @editable: a #GtkEditable
438  * @is_editable: %TRUE if the user is allowed to edit the text
439  *   in the widget
440  *
441  * Determines if the user can edit the text in the editable
442  * widget or not. 
443  */
444 void
445 gtk_editable_set_editable (GtkEditable    *editable,
446                            gboolean        is_editable)
447 {
448   g_return_if_fail (GTK_IS_EDITABLE (editable));
449
450   g_object_set (editable,
451                 "editable", is_editable != FALSE,
452                 NULL);
453 }
454
455 /**
456  * gtk_editable_get_editable:
457  * @editable: a #GtkEditable
458  *
459  * Retrieves whether @editable is editable. See
460  * gtk_editable_set_editable().
461  *
462  * Return value: %TRUE if @editable is editable.
463  */
464 gboolean
465 gtk_editable_get_editable (GtkEditable *editable)
466 {
467   gboolean value;
468
469   g_return_val_if_fail (GTK_IS_EDITABLE (editable), FALSE);
470
471   g_object_get (editable, "editable", &value, NULL);
472
473   return value;
474 }