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 #undef GTK_DISABLE_DEPRECATED
28
29 #include "config.h"
30 #include <string.h>
31 #include "gdk/gdkkeysyms.h"
32 #include "gdk/gdki18n.h"
33 #include "gtkclipboard.h"
34 #include "gtkoldeditable.h"
35 #include "gtkmain.h"
36 #include "gtkmarshalers.h"
37 #include "gtkselection.h"
38 #include "gtksignal.h"
39 #include "gtkintl.h"
40
41 #include "gtkalias.h"
42
43 #define MIN_EDITABLE_WIDTH 150
44 #define DRAW_TIMEOUT 20
45 #define INNER_BORDER 2
46
47 enum {
48 /* Binding actions */
49 ACTIVATE,
50 SET_EDITABLE,
51 MOVE_CURSOR,
52 MOVE_WORD,
53 MOVE_PAGE,
54 MOVE_TO_ROW,
55 MOVE_TO_COLUMN,
56 KILL_CHAR,
57 KILL_WORD,
58 KILL_LINE,
59 CUT_CLIPBOARD,
60 COPY_CLIPBOARD,
61 PASTE_CLIPBOARD,
62 LAST_SIGNAL
63 };
64
65 enum {
66 ARG_0,
67 ARG_TEXT_POSITION,
68 ARG_EDITABLE
69 };
70
71 /* values for selection info */
72
73 enum {
74 TARGET_STRING,
75 TARGET_TEXT,
76 TARGET_COMPOUND_TEXT
77 };
78
79 static void gtk_old_editable_editable_init (GtkEditableClass *iface);
80 static void gtk_old_editable_set_arg (GtkObject *object,
81 GtkArg *arg,
82 guint arg_id);
83 static void gtk_old_editable_get_arg (GtkObject *object,
84 GtkArg *arg,
85 guint arg_id);
86 static void *gtk_old_editable_get_public_chars (GtkOldEditable *old_editable,
87 gint start,
88 gint end);
89
90 static gint gtk_old_editable_selection_clear (GtkWidget *widget,
91 GdkEventSelection *event);
92 static void gtk_old_editable_selection_get (GtkWidget *widget,
93 GtkSelectionData *selection_data,
94 guint info,
95 guint time);
96 static void gtk_old_editable_selection_received (GtkWidget *widget,
97 GtkSelectionData *selection_data,
98 guint time);
99
100 static void gtk_old_editable_set_selection (GtkOldEditable *old_editable,
101 gint start,
102 gint end);
103
104 static void gtk_old_editable_real_set_editable (GtkOldEditable *old_editable,
105 gboolean is_editable);
106 static void gtk_old_editable_real_cut_clipboard (GtkOldEditable *old_editable);
107 static void gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable);
108 static void gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable);
109
110 static void gtk_old_editable_insert_text (GtkEditable *editable,
111 const gchar *new_text,
112 gint new_text_length,
113 gint *position);
114 static void gtk_old_editable_delete_text (GtkEditable *editable,
115 gint start_pos,
116 gint end_pos);
117 static gchar * gtk_old_editable_get_chars (GtkEditable *editable,
118 gint start,
119 gint end);
120 static void gtk_old_editable_set_selection_bounds (GtkEditable *editable,
121 gint start,
122 gint end);
123 static gboolean gtk_old_editable_get_selection_bounds (GtkEditable *editable,
124 gint *start,
125 gint *end);
126 static void gtk_old_editable_set_position (GtkEditable *editable,
127 gint position);
128 static gint gtk_old_editable_get_position (GtkEditable *editable);
129 static void gtk_old_editable_finalize (GObject *object);
130
131 static guint editable_signals[LAST_SIGNAL] = { 0 };
132
G_DEFINE_ABSTRACT_TYPE_WITH_CODE(GtkOldEditable,gtk_old_editable,GTK_TYPE_WIDGET,G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,gtk_old_editable_editable_init))133 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkOldEditable, gtk_old_editable, GTK_TYPE_WIDGET,
134 G_IMPLEMENT_INTERFACE (GTK_TYPE_EDITABLE,
135 gtk_old_editable_editable_init))
136
137 static void
138 gtk_old_editable_class_init (GtkOldEditableClass *class)
139 {
140 GObjectClass *gobject_class;
141 GtkObjectClass *object_class;
142 GtkWidgetClass *widget_class;
143
144 gobject_class = (GObjectClass*) class;
145 object_class = (GtkObjectClass*) class;
146 widget_class = (GtkWidgetClass*) class;
147
148 gobject_class->finalize = gtk_old_editable_finalize;
149
150 object_class->set_arg = gtk_old_editable_set_arg;
151 object_class->get_arg = gtk_old_editable_get_arg;
152
153 widget_class->selection_clear_event = gtk_old_editable_selection_clear;
154 widget_class->selection_received = gtk_old_editable_selection_received;
155 widget_class->selection_get = gtk_old_editable_selection_get;
156
157 class->activate = NULL;
158 class->set_editable = gtk_old_editable_real_set_editable;
159
160 class->move_cursor = NULL;
161 class->move_word = NULL;
162 class->move_page = NULL;
163 class->move_to_row = NULL;
164 class->move_to_column = NULL;
165
166 class->kill_char = NULL;
167 class->kill_word = NULL;
168 class->kill_line = NULL;
169
170 class->cut_clipboard = gtk_old_editable_real_cut_clipboard;
171 class->copy_clipboard = gtk_old_editable_real_copy_clipboard;
172 class->paste_clipboard = gtk_old_editable_real_paste_clipboard;
173
174 class->update_text = NULL;
175 class->get_chars = NULL;
176 class->set_selection = NULL;
177 class->set_position = NULL;
178
179 editable_signals[ACTIVATE] =
180 gtk_signal_new (I_("activate"),
181 GTK_RUN_LAST | GTK_RUN_ACTION,
182 GTK_CLASS_TYPE (object_class),
183 GTK_SIGNAL_OFFSET (GtkOldEditableClass, activate),
184 _gtk_marshal_VOID__VOID,
185 GTK_TYPE_NONE, 0);
186 widget_class->activate_signal = editable_signals[ACTIVATE];
187
188 editable_signals[SET_EDITABLE] =
189 gtk_signal_new (I_("set-editable"),
190 GTK_RUN_LAST | GTK_RUN_ACTION,
191 GTK_CLASS_TYPE (object_class),
192 GTK_SIGNAL_OFFSET (GtkOldEditableClass, set_editable),
193 _gtk_marshal_VOID__BOOLEAN,
194 GTK_TYPE_NONE, 1,
195 GTK_TYPE_BOOL);
196
197 editable_signals[MOVE_CURSOR] =
198 gtk_signal_new (I_("move-cursor"),
199 GTK_RUN_LAST | GTK_RUN_ACTION,
200 GTK_CLASS_TYPE (object_class),
201 GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_cursor),
202 _gtk_marshal_VOID__INT_INT,
203 GTK_TYPE_NONE, 2,
204 GTK_TYPE_INT,
205 GTK_TYPE_INT);
206
207 editable_signals[MOVE_WORD] =
208 gtk_signal_new (I_("move-word"),
209 GTK_RUN_LAST | GTK_RUN_ACTION,
210 GTK_CLASS_TYPE (object_class),
211 GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_word),
212 _gtk_marshal_VOID__INT,
213 GTK_TYPE_NONE, 1,
214 GTK_TYPE_INT);
215
216 editable_signals[MOVE_PAGE] =
217 gtk_signal_new (I_("move-page"),
218 GTK_RUN_LAST | GTK_RUN_ACTION,
219 GTK_CLASS_TYPE (object_class),
220 GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_page),
221 _gtk_marshal_VOID__INT_INT,
222 GTK_TYPE_NONE, 2,
223 GTK_TYPE_INT,
224 GTK_TYPE_INT);
225
226 editable_signals[MOVE_TO_ROW] =
227 gtk_signal_new (I_("move-to-row"),
228 GTK_RUN_LAST | GTK_RUN_ACTION,
229 GTK_CLASS_TYPE (object_class),
230 GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_row),
231 _gtk_marshal_VOID__INT,
232 GTK_TYPE_NONE, 1,
233 GTK_TYPE_INT);
234
235 editable_signals[MOVE_TO_COLUMN] =
236 gtk_signal_new (I_("move-to-column"),
237 GTK_RUN_LAST | GTK_RUN_ACTION,
238 GTK_CLASS_TYPE (object_class),
239 GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_column),
240 _gtk_marshal_VOID__INT,
241 GTK_TYPE_NONE, 1,
242 GTK_TYPE_INT);
243
244 editable_signals[KILL_CHAR] =
245 gtk_signal_new (I_("kill-char"),
246 GTK_RUN_LAST | GTK_RUN_ACTION,
247 GTK_CLASS_TYPE (object_class),
248 GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_char),
249 _gtk_marshal_VOID__INT,
250 GTK_TYPE_NONE, 1,
251 GTK_TYPE_INT);
252
253 editable_signals[KILL_WORD] =
254 gtk_signal_new (I_("kill-word"),
255 GTK_RUN_LAST | GTK_RUN_ACTION,
256 GTK_CLASS_TYPE (object_class),
257 GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_word),
258 _gtk_marshal_VOID__INT,
259 GTK_TYPE_NONE, 1,
260 GTK_TYPE_INT);
261
262 editable_signals[KILL_LINE] =
263 gtk_signal_new (I_("kill-line"),
264 GTK_RUN_LAST | GTK_RUN_ACTION,
265 GTK_CLASS_TYPE (object_class),
266 GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_line),
267 _gtk_marshal_VOID__INT,
268 GTK_TYPE_NONE, 1,
269 GTK_TYPE_INT);
270
271 editable_signals[CUT_CLIPBOARD] =
272 gtk_signal_new (I_("cut-clipboard"),
273 GTK_RUN_LAST | GTK_RUN_ACTION,
274 GTK_CLASS_TYPE (object_class),
275 GTK_SIGNAL_OFFSET (GtkOldEditableClass, cut_clipboard),
276 _gtk_marshal_VOID__VOID,
277 GTK_TYPE_NONE, 0);
278
279 editable_signals[COPY_CLIPBOARD] =
280 gtk_signal_new (I_("copy-clipboard"),
281 GTK_RUN_LAST | GTK_RUN_ACTION,
282 GTK_CLASS_TYPE (object_class),
283 GTK_SIGNAL_OFFSET (GtkOldEditableClass, copy_clipboard),
284 _gtk_marshal_VOID__VOID,
285 GTK_TYPE_NONE, 0);
286
287 editable_signals[PASTE_CLIPBOARD] =
288 gtk_signal_new (I_("paste-clipboard"),
289 GTK_RUN_LAST | GTK_RUN_ACTION,
290 GTK_CLASS_TYPE (object_class),
291 GTK_SIGNAL_OFFSET (GtkOldEditableClass, paste_clipboard),
292 _gtk_marshal_VOID__VOID,
293 GTK_TYPE_NONE, 0);
294
295 gtk_object_add_arg_type ("GtkOldEditable::text-position", GTK_TYPE_INT, GTK_ARG_READWRITE | G_PARAM_STATIC_NAME, ARG_TEXT_POSITION);
296 gtk_object_add_arg_type ("GtkOldEditable::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE | G_PARAM_STATIC_NAME, ARG_EDITABLE);
297 }
298
299 static void
gtk_old_editable_editable_init(GtkEditableClass * iface)300 gtk_old_editable_editable_init (GtkEditableClass *iface)
301 {
302 iface->do_insert_text = gtk_old_editable_insert_text;
303 iface->do_delete_text = gtk_old_editable_delete_text;
304 iface->get_chars = gtk_old_editable_get_chars;
305 iface->set_selection_bounds = gtk_old_editable_set_selection_bounds;
306 iface->get_selection_bounds = gtk_old_editable_get_selection_bounds;
307 iface->set_position = gtk_old_editable_set_position;
308 iface->get_position = gtk_old_editable_get_position;
309 }
310
311 static void
gtk_old_editable_set_arg(GtkObject * object,GtkArg * arg,guint arg_id)312 gtk_old_editable_set_arg (GtkObject *object,
313 GtkArg *arg,
314 guint arg_id)
315 {
316 GtkEditable *editable = GTK_EDITABLE (object);
317
318 switch (arg_id)
319 {
320 case ARG_TEXT_POSITION:
321 gtk_editable_set_position (editable, GTK_VALUE_INT (*arg));
322 break;
323 case ARG_EDITABLE:
324 gtk_signal_emit (object, editable_signals[SET_EDITABLE],
325 GTK_VALUE_BOOL (*arg) != FALSE);
326 break;
327 default:
328 break;
329 }
330 }
331
332 static void
gtk_old_editable_get_arg(GtkObject * object,GtkArg * arg,guint arg_id)333 gtk_old_editable_get_arg (GtkObject *object,
334 GtkArg *arg,
335 guint arg_id)
336 {
337 GtkOldEditable *old_editable;
338
339 old_editable = GTK_OLD_EDITABLE (object);
340
341 switch (arg_id)
342 {
343 case ARG_TEXT_POSITION:
344 GTK_VALUE_INT (*arg) = old_editable->current_pos;
345 break;
346 case ARG_EDITABLE:
347 GTK_VALUE_BOOL (*arg) = old_editable->editable;
348 break;
349 default:
350 arg->type = GTK_TYPE_INVALID;
351 break;
352 }
353 }
354
355 static void
gtk_old_editable_init(GtkOldEditable * old_editable)356 gtk_old_editable_init (GtkOldEditable *old_editable)
357 {
358 static const GtkTargetEntry targets[] = {
359 { "UTF8_STRING", 0, 0 },
360 { "STRING", 0, 0 },
361 { "TEXT", 0, 0 },
362 { "COMPOUND_TEXT", 0, 0 }
363 };
364
365 gtk_widget_set_can_focus (GTK_WIDGET (old_editable), TRUE);
366
367 old_editable->selection_start_pos = 0;
368 old_editable->selection_end_pos = 0;
369 old_editable->has_selection = FALSE;
370 old_editable->editable = 1;
371 old_editable->visible = 1;
372 old_editable->clipboard_text = NULL;
373
374 gtk_selection_add_targets (GTK_WIDGET (old_editable), GDK_SELECTION_PRIMARY,
375 targets, G_N_ELEMENTS (targets));
376 }
377
378 static void
gtk_old_editable_finalize(GObject * object)379 gtk_old_editable_finalize (GObject *object)
380 {
381 gtk_selection_clear_targets (GTK_WIDGET (object), GDK_SELECTION_PRIMARY);
382
383 G_OBJECT_CLASS (gtk_old_editable_parent_class)->finalize (object);
384 }
385
386 static void
gtk_old_editable_insert_text(GtkEditable * editable,const gchar * new_text,gint new_text_length,gint * position)387 gtk_old_editable_insert_text (GtkEditable *editable,
388 const gchar *new_text,
389 gint new_text_length,
390 gint *position)
391 {
392 gchar buf[64];
393 gchar *text;
394
395 g_object_ref (editable);
396
397 if (new_text_length <= 63)
398 text = buf;
399 else
400 text = g_new (gchar, new_text_length + 1);
401
402 text[new_text_length] = '\0';
403 strncpy (text, new_text, new_text_length);
404
405 g_signal_emit_by_name (editable, "insert-text", text, new_text_length,
406 position);
407 g_signal_emit_by_name (editable, "changed");
408
409 if (new_text_length > 63)
410 g_free (text);
411
412 g_object_unref (editable);
413 }
414
415 static void
gtk_old_editable_delete_text(GtkEditable * editable,gint start_pos,gint end_pos)416 gtk_old_editable_delete_text (GtkEditable *editable,
417 gint start_pos,
418 gint end_pos)
419 {
420 GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
421
422 g_object_ref (old_editable);
423
424 g_signal_emit_by_name (editable, "delete-text", start_pos, end_pos);
425 g_signal_emit_by_name (editable, "changed");
426
427 if (old_editable->selection_start_pos == old_editable->selection_end_pos &&
428 old_editable->has_selection)
429 gtk_old_editable_claim_selection (old_editable, FALSE, GDK_CURRENT_TIME);
430
431 g_object_unref (old_editable);
432 }
433
434 static void
gtk_old_editable_update_text(GtkOldEditable * old_editable,gint start_pos,gint end_pos)435 gtk_old_editable_update_text (GtkOldEditable *old_editable,
436 gint start_pos,
437 gint end_pos)
438 {
439 GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
440 klass->update_text (GTK_OLD_EDITABLE (old_editable), start_pos, end_pos);
441 }
442
443 static gchar *
gtk_old_editable_get_chars(GtkEditable * editable,gint start,gint end)444 gtk_old_editable_get_chars (GtkEditable *editable,
445 gint start,
446 gint end)
447 {
448 GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
449 return klass->get_chars (GTK_OLD_EDITABLE (editable), start, end);
450 }
451
452 /*
453 * Like gtk_editable_get_chars, but if the editable is not
454 * visible, return asterisks; also convert result to UTF-8.
455 */
456 static void *
gtk_old_editable_get_public_chars(GtkOldEditable * old_editable,gint start,gint end)457 gtk_old_editable_get_public_chars (GtkOldEditable *old_editable,
458 gint start,
459 gint end)
460 {
461 gchar *str = NULL;
462 const gchar *charset;
463 gboolean need_conversion = !g_get_charset (&charset);
464
465 if (old_editable->visible)
466 {
467 GError *error = NULL;
468 gchar *tmp = gtk_editable_get_chars (GTK_EDITABLE (old_editable), start, end);
469
470 if (need_conversion)
471 {
472 str = g_convert (tmp, -1,
473 "UTF-8", charset,
474 NULL, NULL, &error);
475
476 if (!str)
477 {
478 g_warning ("Cannot convert text from charset to UTF-8 %s: %s", charset, error->message);
479 g_error_free (error);
480 }
481
482 g_free (tmp);
483 }
484 else
485 str = tmp;
486 }
487 else
488 {
489 gint i;
490 gint nchars = end - start;
491
492 if (nchars < 0)
493 nchars = -nchars;
494
495 str = g_new (gchar, nchars + 1);
496 for (i = 0; i<nchars; i++)
497 str[i] = '*';
498 str[i] = '\0';
499 }
500
501 return str;
502 }
503
504 static void
gtk_old_editable_set_selection(GtkOldEditable * old_editable,gint start_pos,gint end_pos)505 gtk_old_editable_set_selection (GtkOldEditable *old_editable,
506 gint start_pos,
507 gint end_pos)
508 {
509 GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
510 klass->set_selection (old_editable, start_pos, end_pos);
511 }
512
513 static void
gtk_old_editable_set_position(GtkEditable * editable,gint position)514 gtk_old_editable_set_position (GtkEditable *editable,
515 gint position)
516 {
517 GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
518
519 klass->set_position (GTK_OLD_EDITABLE (editable), position);
520 }
521
522 static gint
gtk_old_editable_get_position(GtkEditable * editable)523 gtk_old_editable_get_position (GtkEditable *editable)
524 {
525 return GTK_OLD_EDITABLE (editable)->current_pos;
526 }
527
528 static gint
gtk_old_editable_selection_clear(GtkWidget * widget,GdkEventSelection * event)529 gtk_old_editable_selection_clear (GtkWidget *widget,
530 GdkEventSelection *event)
531 {
532 GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
533
534 /* Let the selection handling code know that the selection
535 * has been changed, since we've overriden the default handler */
536 if (!GTK_WIDGET_CLASS (gtk_old_editable_parent_class)->selection_clear_event (widget, event))
537 return FALSE;
538
539 if (old_editable->has_selection)
540 {
541 old_editable->has_selection = FALSE;
542 gtk_old_editable_update_text (old_editable, old_editable->selection_start_pos,
543 old_editable->selection_end_pos);
544 }
545
546 return TRUE;
547 }
548
549 static void
gtk_old_editable_selection_get(GtkWidget * widget,GtkSelectionData * selection_data,guint info,guint time)550 gtk_old_editable_selection_get (GtkWidget *widget,
551 GtkSelectionData *selection_data,
552 guint info,
553 guint time)
554 {
555 GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
556 gint selection_start_pos;
557 gint selection_end_pos;
558
559 gchar *str;
560
561 selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
562 selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
563
564 str = gtk_old_editable_get_public_chars (old_editable,
565 selection_start_pos,
566 selection_end_pos);
567
568 if (str)
569 {
570 gtk_selection_data_set_text (selection_data, str, -1);
571 g_free (str);
572 }
573 }
574
575 static void
gtk_old_editable_paste_received(GtkOldEditable * old_editable,const gchar * text,gboolean is_clipboard)576 gtk_old_editable_paste_received (GtkOldEditable *old_editable,
577 const gchar *text,
578 gboolean is_clipboard)
579 {
580 const gchar *str = NULL;
581 const gchar *charset;
582 gboolean need_conversion = FALSE;
583
584 if (text)
585 {
586 GError *error = NULL;
587
588 need_conversion = !g_get_charset (&charset);
589
590 if (need_conversion)
591 {
592 str = g_convert_with_fallback (text, -1,
593 charset, "UTF-8", NULL,
594 NULL, NULL, &error);
595 if (!str)
596 {
597 g_warning ("Cannot convert text from UTF-8 to %s: %s",
598 charset, error->message);
599 g_error_free (error);
600 return;
601 }
602 }
603 else
604 str = text;
605 }
606
607 if (str)
608 {
609 gboolean reselect;
610 gint old_pos;
611 gint tmp_pos;
612
613 reselect = FALSE;
614
615 if ((old_editable->selection_start_pos != old_editable->selection_end_pos) &&
616 (!old_editable->has_selection || is_clipboard))
617 {
618 reselect = TRUE;
619
620 /* Don't want to call gtk_editable_delete_selection here if we are going
621 * to reclaim the selection to avoid extra server traffic */
622 if (old_editable->has_selection)
623 {
624 gtk_editable_delete_text (GTK_EDITABLE (old_editable),
625 MIN (old_editable->selection_start_pos, old_editable->selection_end_pos),
626 MAX (old_editable->selection_start_pos, old_editable->selection_end_pos));
627 }
628 else
629 gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
630 }
631
632 tmp_pos = old_pos = old_editable->current_pos;
633
634 gtk_editable_insert_text (GTK_EDITABLE (old_editable), str, -1, &tmp_pos);
635
636 if (reselect)
637 gtk_old_editable_set_selection (old_editable, old_pos, old_editable->current_pos);
638
639 if (str && str != text)
640 g_free ((gchar *) str);
641 }
642 }
643
644 static void
gtk_old_editable_selection_received(GtkWidget * widget,GtkSelectionData * selection_data,guint time)645 gtk_old_editable_selection_received (GtkWidget *widget,
646 GtkSelectionData *selection_data,
647 guint time)
648 {
649 GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
650
651 guchar *text = gtk_selection_data_get_text (selection_data);
652
653 if (!text)
654 {
655 /* If we asked for UTF8 and didn't get it, try text; if we asked
656 * for text and didn't get it, try string. If we asked for
657 * anything else and didn't get it, give up.
658 */
659 if (selection_data->target == gdk_atom_intern_static_string ("UTF8_STRING"))
660 {
661 gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
662 gdk_atom_intern_static_string ("TEXT"),
663 time);
664 return;
665 }
666 else if (selection_data->target == gdk_atom_intern_static_string ("TEXT"))
667 {
668 gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
669 GDK_TARGET_STRING,
670 time);
671 return;
672 }
673 }
674
675 if (text)
676 {
677 gtk_old_editable_paste_received (old_editable, (gchar *) text, FALSE);
678 g_free (text);
679 }
680 }
681
682 static void
old_editable_text_received_cb(GtkClipboard * clipboard,const gchar * text,gpointer data)683 old_editable_text_received_cb (GtkClipboard *clipboard,
684 const gchar *text,
685 gpointer data)
686 {
687 GtkOldEditable *old_editable = GTK_OLD_EDITABLE (data);
688
689 gtk_old_editable_paste_received (old_editable, text, TRUE);
690 g_object_unref (G_OBJECT (old_editable));
691 }
692
693 /**
694 * gtk_old_editable_claim_selection:
695 * @old_editable: a #GtkOldEditable
696 * @claim: if %TRUE, claim ownership of the selection, if %FALSE, give
697 * up ownership
698 * @time_: timestamp for this operation
699 *
700 * Claims or gives up ownership of the selection.
701 */
702 void
gtk_old_editable_claim_selection(GtkOldEditable * old_editable,gboolean claim,guint32 time)703 gtk_old_editable_claim_selection (GtkOldEditable *old_editable,
704 gboolean claim,
705 guint32 time)
706 {
707 GtkWidget *widget;
708 GdkDisplay *display;
709
710 g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
711 widget = GTK_WIDGET (old_editable);
712 g_return_if_fail (gtk_widget_get_realized (widget));
713
714 display = gtk_widget_get_display (widget);
715 old_editable->has_selection = FALSE;
716
717 if (claim)
718 {
719 if (gtk_selection_owner_set_for_display (display, widget,
720 GDK_SELECTION_PRIMARY, time))
721 old_editable->has_selection = TRUE;
722 }
723 else
724 {
725 if (gdk_selection_owner_get_for_display (display, GDK_SELECTION_PRIMARY) == widget->window)
726 gtk_selection_owner_set_for_display (display,
727 NULL,
728 GDK_SELECTION_PRIMARY, time);
729 }
730 }
731
732 static void
gtk_old_editable_set_selection_bounds(GtkEditable * editable,gint start,gint end)733 gtk_old_editable_set_selection_bounds (GtkEditable *editable,
734 gint start,
735 gint end)
736 {
737 GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
738
739 if (gtk_widget_get_realized (GTK_WIDGET (editable)))
740 gtk_old_editable_claim_selection (old_editable, start != end, GDK_CURRENT_TIME);
741
742 gtk_old_editable_set_selection (old_editable, start, end);
743 }
744
745 static gboolean
gtk_old_editable_get_selection_bounds(GtkEditable * editable,gint * start,gint * end)746 gtk_old_editable_get_selection_bounds (GtkEditable *editable,
747 gint *start,
748 gint *end)
749 {
750 GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
751
752 *start = old_editable->selection_start_pos;
753 *end = old_editable->selection_end_pos;
754
755 return (old_editable->selection_start_pos != old_editable->selection_end_pos);
756 }
757
758 static void
gtk_old_editable_real_set_editable(GtkOldEditable * old_editable,gboolean is_editable)759 gtk_old_editable_real_set_editable (GtkOldEditable *old_editable,
760 gboolean is_editable)
761 {
762 is_editable = is_editable != FALSE;
763
764 if (old_editable->editable != is_editable)
765 {
766 old_editable->editable = is_editable;
767 gtk_widget_queue_draw (GTK_WIDGET (old_editable));
768 }
769 }
770
771 static void
gtk_old_editable_real_cut_clipboard(GtkOldEditable * old_editable)772 gtk_old_editable_real_cut_clipboard (GtkOldEditable *old_editable)
773 {
774 gtk_old_editable_real_copy_clipboard (old_editable);
775 gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
776 }
777
778 static void
gtk_old_editable_real_copy_clipboard(GtkOldEditable * old_editable)779 gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable)
780 {
781 gint selection_start_pos;
782 gint selection_end_pos;
783
784 selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
785 selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
786
787 if (selection_start_pos != selection_end_pos)
788 {
789 gchar *text = gtk_old_editable_get_public_chars (old_editable,
790 selection_start_pos,
791 selection_end_pos);
792
793 if (text)
794 {
795 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (old_editable),
796 GDK_SELECTION_CLIPBOARD);
797
798 gtk_clipboard_set_text (clipboard, text, -1);
799 g_free (text);
800 }
801 }
802 }
803
804 static void
gtk_old_editable_real_paste_clipboard(GtkOldEditable * old_editable)805 gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable)
806 {
807 GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (old_editable),
808 GDK_SELECTION_CLIPBOARD);
809
810 g_object_ref (G_OBJECT (old_editable));
811 gtk_clipboard_request_text (clipboard, old_editable_text_received_cb, old_editable);
812 }
813
814 /**
815 * gtk_old_editable_changed:
816 * @old_editable: a #GtkOldEditable
817 *
818 * Emits the ::changed signal on @old_editable.
819 */
820 void
gtk_old_editable_changed(GtkOldEditable * old_editable)821 gtk_old_editable_changed (GtkOldEditable *old_editable)
822 {
823 g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
824
825 g_signal_emit_by_name (old_editable, "changed");
826 }
827
828 #define __GTK_OLD_EDITABLE_C__
829 #include "gtkaliasdef.c"
830