gtktextview.c 284 KB
Newer Older
Matthias Clasen's avatar
Matthias Clasen committed
1
/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */
Cody Russell's avatar
Cody Russell committed
2
/* GTK - The GIMP Toolkit
3
 * gtktextview.c Copyright (C) 2000 Red Hat, Inc.
4
 *
5 6 7 8
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
9
 *
10 11
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 14 15 16 17 18 19 20 21 22 23 24
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GTK+ Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
25
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
26 27
 */

28
#include "config.h"
29 30
#include <string.h>

31
#define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API
32 33
#include "gtkbindings.h"
#include "gtkdnd.h"
34
#include "gtkimagemenuitem.h"
Owen Taylor's avatar
Owen Taylor committed
35
#include "gtkintl.h"
36
#include "gtkmain.h"
37
#include "gtkmarshalers.h"
Owen Taylor's avatar
Owen Taylor committed
38 39
#include "gtkmenu.h"
#include "gtkmenuitem.h"
40
#include "gtkseparatormenuitem.h"
41
#include "gtksettings.h"
42
#include "gtkstock.h"
43
#include "gtktextbufferrichtext.h"
44 45 46 47
#include "gtktextdisplay.h"
#include "gtktextview.h"
#include "gtkimmulticontext.h"
#include "gdk/gdkkeysyms.h"
48
#include "gtkprivate.h"
49
#include "gtktextutil.h"
Emmanuele Bassi's avatar
Emmanuele Bassi committed
50
#include "gtkwidgetprivate.h"
51
#include "gtkwindow.h"
Tadej Borovšak's avatar
Tadej Borovšak committed
52
#include "gtkscrollable.h"
53

54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
/* How scrolling, validation, exposes, etc. work.
 *
 * The expose_event handler has the invariant that the onscreen lines
 * have been validated.
 *
 * There are two ways that onscreen lines can become invalid. The first
 * is to change which lines are onscreen. This happens when the value
 * of a scroll adjustment changes. So the code path begins in
 * gtk_text_view_value_changed() and goes like this:
 *   - gdk_window_scroll() to reflect the new adjustment value
 *   - validate the lines that were moved onscreen
 *   - gdk_window_process_updates() to handle the exposes immediately
 *
 * The second way is that you get the "invalidated" signal from the layout,
 * indicating that lines have become invalid. This code path begins in
 * invalidated_handler() and goes like this:
 *   - install high-priority idle which does the rest of the steps
 *   - if a scroll is pending from scroll_to_mark(), do the scroll,
 *     jumping to the gtk_text_view_value_changed() code path
 *   - otherwise, validate the onscreen lines
 *   - DO NOT process updates
 *
 * In both cases, validating the onscreen lines can trigger a scroll
 * due to maintaining the first_para on the top of the screen.
 * If validation triggers a scroll, we jump to the top of the code path
 * for value_changed, and bail out of the current code path.
 *
 * Also, in size_allocate, if we invalidate some lines from changing
 * the layout width, we need to go ahead and run the high-priority idle,
 * because GTK sends exposes right after doing the size allocates without
 * returning to the main loop. This is also why the high-priority idle
 * is at a higher priority than resizing.
 *
 */

90
#if 0
91 92
#define DEBUG_VALIDATION_AND_SCROLLING
#endif
93 94 95 96 97 98 99

#ifdef DEBUG_VALIDATION_AND_SCROLLING
#define DV(x) (x)
#else
#define DV(x)
#endif

100 101
#define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->priv->text_window)
#define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->priv->text_window)
102

103 104
#define SPACE_FOR_CURSOR 1

105 106
#define GTK_TEXT_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_TEXT_VIEW, GtkTextViewPrivate))

107 108 109
typedef struct _GtkTextWindow GtkTextWindow;
typedef struct _GtkTextPendingScroll GtkTextPendingScroll;

110 111
struct _GtkTextViewPrivate 
{
112 113 114
  GtkTextLayout *layout;
  GtkTextBuffer *buffer;

115
  guint blink_time;  /* time in msec the cursor has blinked since last user event */
116
  guint im_spot_idle;
117
  gchar *im_module;
118
  GdkDevice *grab_device;
119
  GdkDevice *dnd_device;
120

121
  gulong selection_drag_handler;
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
  guint scroll_timeout;

  GtkTextWindow *text_window;
  GtkTextWindow *left_window;
  GtkTextWindow *right_window;
  GtkTextWindow *top_window;
  GtkTextWindow *bottom_window;

  GtkAdjustment *hadjustment;
  GtkAdjustment *vadjustment;

  gint xoffset;         /* Offsets between widget coordinates and buffer coordinates */
  gint yoffset;
  gint width;           /* Width and height of the buffer */
  gint height;

138 139 140 141 142 143 144
  /* This is used to monitor the overall size request 
   * and decide whether we need to queue resizes when
   * the buffer content changes. 
   *
   * FIXME: This could be done in a simpler way by 
   * consulting the above width/height of the buffer + some
   * padding values, however all of this request code needs
145
   * to be changed to use GtkWidget     Iface and deserves
146 147 148 149
   * more attention.
   */
  GtkRequisition cached_size_request;

150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
  /* The virtual cursor position is normally the same as the
   * actual (strong) cursor position, except in two circumstances:
   *
   * a) When the cursor is moved vertically with the keyboard
   * b) When the text view is scrolled with the keyboard
   *
   * In case a), virtual_cursor_x is preserved, but not virtual_cursor_y
   * In case b), both virtual_cursor_x and virtual_cursor_y are preserved.
   */
  gint virtual_cursor_x;   /* -1 means use actual cursor position */
  gint virtual_cursor_y;   /* -1 means use actual cursor position */

  GtkTextMark *first_para_mark; /* Mark at the beginning of the first onscreen paragraph */
  gint first_para_pixels;       /* Offset of top of screen in the first onscreen paragraph */

  GtkTextMark *dnd_mark;
  guint blink_timeout;

  guint first_validate_idle;        /* Idle to revalidate onscreen portion, runs before resize */
  guint incremental_validate_idle;  /* Idle to revalidate offscreen portions, runs after redraw */

  GtkIMContext *im_context;
  GtkWidget *popup_menu;

  gint drag_start_x;
  gint drag_start_y;

  GSList *children;

  GtkTextPendingScroll *pending_scroll;

  gint pending_place_cursor_button;

  /* Default style settings */
  gint pixels_above_lines;
  gint pixels_below_lines;
  gint pixels_inside_wrap;
  GtkWrapMode wrap_mode;
  GtkJustification justify;
  gint left_margin;
  gint right_margin;
  gint indent;
  PangoTabArray *tabs;
  guint editable : 1;

  guint overwrite_mode : 1;
  guint cursor_visible : 1;

  /* if we have reset the IM since the last character entered */  
  guint need_im_reset : 1;

  guint accepts_tab : 1;

  guint width_changed : 1;

  /* debug flag - means that we've validated onscreen since the
   * last "invalidate" signal from the layout
   */
  guint onscreen_validated : 1;

  guint mouse_cursor_obscured : 1;

212
  guint scroll_after_paste : 1;
213 214 215 216 217

  /* GtkScrollablePolicy needs to be checked when
   * driving the scrollable adjustment values */
  guint hscroll_policy : 1;
  guint vscroll_policy : 1;
218 219
};

220 221 222 223 224 225 226 227
struct _GtkTextPendingScroll
{
  GtkTextMark   *mark;
  gdouble        within_margin;
  gboolean       use_align;
  gdouble        xalign;
  gdouble        yalign;
};
228

229 230
enum
{
Owen Taylor's avatar
Owen Taylor committed
231
  POPULATE_POPUP,
232
  MOVE_CURSOR,
233
  PAGE_HORIZONTALLY,
234
  SET_ANCHOR,
235
  INSERT_AT_CURSOR,
236
  DELETE_FROM_CURSOR,
237
  BACKSPACE,
238 239 240
  CUT_CLIPBOARD,
  COPY_CLIPBOARD,
  PASTE_CLIPBOARD,
241
  TOGGLE_OVERWRITE,
242
  MOVE_VIEWPORT,
243
  SELECT_ALL,
244
  TOGGLE_CURSOR_VISIBLE,
245
  PREEDIT_CHANGED,
246 247 248
  LAST_SIGNAL
};

249 250
enum
{
251 252 253 254 255 256 257 258 259 260 261 262
  PROP_0,
  PROP_PIXELS_ABOVE_LINES,
  PROP_PIXELS_BELOW_LINES,
  PROP_PIXELS_INSIDE_WRAP,
  PROP_EDITABLE,
  PROP_WRAP_MODE,
  PROP_JUSTIFICATION,
  PROP_LEFT_MARGIN,
  PROP_RIGHT_MARGIN,
  PROP_INDENT,
  PROP_TABS,
  PROP_CURSOR_VISIBLE,
263
  PROP_BUFFER,
264
  PROP_OVERWRITE,
265
  PROP_ACCEPTS_TAB,
Tadej Borovšak's avatar
Tadej Borovšak committed
266 267
  PROP_IM_MODULE,
  PROP_HADJUSTMENT,
268 269 270
  PROP_VADJUSTMENT,
  PROP_HSCROLL_POLICY,
  PROP_VSCROLL_POLICY
271 272 273
};

static void gtk_text_view_finalize             (GObject          *object);
274 275 276 277 278 279 280 281
static void gtk_text_view_set_property         (GObject         *object,
						guint            prop_id,
						const GValue    *value,
						GParamSpec      *pspec);
static void gtk_text_view_get_property         (GObject         *object,
						guint            prop_id,
						GValue          *value,
						GParamSpec      *pspec);
282
static void gtk_text_view_destroy              (GtkWidget        *widget);
283
static void gtk_text_view_size_request         (GtkWidget        *widget,
284
                                                GtkRequisition   *requisition);
285 286 287 288 289 290
static void gtk_text_view_get_preferred_width  (GtkWidget        *widget,
						gint             *minimum,
						gint             *natural);
static void gtk_text_view_get_preferred_height (GtkWidget        *widget,
						gint             *minimum,
						gint             *natural);
291
static void gtk_text_view_size_allocate        (GtkWidget        *widget,
292
                                                GtkAllocation    *allocation);
293 294 295
static void gtk_text_view_realize              (GtkWidget        *widget);
static void gtk_text_view_unrealize            (GtkWidget        *widget);
static void gtk_text_view_style_set            (GtkWidget        *widget,
296
                                                GtkStyle         *previous_style);
297
static void gtk_text_view_direction_changed    (GtkWidget        *widget,
298
                                                GtkTextDirection  previous_direction);
299 300
static void gtk_text_view_grab_notify          (GtkWidget        *widget,
					        gboolean         was_grabbed);
301 302 303
static void gtk_text_view_state_changed        (GtkWidget        *widget,
					        GtkStateType      previous_state);

304
static gint gtk_text_view_event                (GtkWidget        *widget,
305
                                                GdkEvent         *event);
306
static gint gtk_text_view_key_press_event      (GtkWidget        *widget,
307
                                                GdkEventKey      *event);
308
static gint gtk_text_view_key_release_event    (GtkWidget        *widget,
309
                                                GdkEventKey      *event);
310
static gint gtk_text_view_button_press_event   (GtkWidget        *widget,
311
                                                GdkEventButton   *event);
312
static gint gtk_text_view_button_release_event (GtkWidget        *widget,
313
                                                GdkEventButton   *event);
314
static gint gtk_text_view_focus_in_event       (GtkWidget        *widget,
315
                                                GdkEventFocus    *event);
316
static gint gtk_text_view_focus_out_event      (GtkWidget        *widget,
317
                                                GdkEventFocus    *event);
318
static gint gtk_text_view_motion_event         (GtkWidget        *widget,
319
                                                GdkEventMotion   *event);
Benjamin Otte's avatar
Benjamin Otte committed
320 321 322 323
static gint gtk_text_view_draw                 (GtkWidget        *widget,
                                                cairo_t          *cr);
static void gtk_text_view_draw_focus           (GtkWidget        *widget,
                                                cairo_t          *cr);
324 325
static gboolean gtk_text_view_focus            (GtkWidget        *widget,
                                                GtkDirectionType  direction);
326 327
static void gtk_text_view_select_all           (GtkWidget        *widget,
                                                gboolean          select);
328

329 330 331

/* Source side drag signals */
static void gtk_text_view_drag_begin       (GtkWidget        *widget,
332
                                            GdkDragContext   *context);
333
static void gtk_text_view_drag_end         (GtkWidget        *widget,
334
                                            GdkDragContext   *context);
335
static void gtk_text_view_drag_data_get    (GtkWidget        *widget,
336 337 338 339
                                            GdkDragContext   *context,
                                            GtkSelectionData *selection_data,
                                            guint             info,
                                            guint             time);
340
static void gtk_text_view_drag_data_delete (GtkWidget        *widget,
341
                                            GdkDragContext   *context);
342 343 344

/* Target side drag signals */
static void     gtk_text_view_drag_leave         (GtkWidget        *widget,
345 346
                                                  GdkDragContext   *context,
                                                  guint             time);
347
static gboolean gtk_text_view_drag_motion        (GtkWidget        *widget,
348 349 350 351
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
352
static gboolean gtk_text_view_drag_drop          (GtkWidget        *widget,
353 354 355 356
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
357
static void     gtk_text_view_drag_data_received (GtkWidget        *widget,
358 359 360 361 362 363
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  GtkSelectionData *selection_data,
                                                  guint             info,
                                                  guint             time);
364

365
static gboolean gtk_text_view_popup_menu         (GtkWidget     *widget);
366

367 368 369 370
static void gtk_text_view_move_cursor       (GtkTextView           *text_view,
                                             GtkMovementStep        step,
                                             gint                   count,
                                             gboolean               extend_selection);
371
static gboolean gtk_text_view_move_viewport (GtkTextView           *text_view,
372 373
                                             GtkScrollStep          step,
                                             gint                   count);
374
static void gtk_text_view_set_anchor       (GtkTextView           *text_view);
375
static gboolean gtk_text_view_scroll_pages (GtkTextView           *text_view,
376 377
                                            gint                   count,
                                            gboolean               extend_selection);
378
static gboolean gtk_text_view_scroll_hpages(GtkTextView           *text_view,
379 380
                                            gint                   count,
                                            gboolean               extend_selection);
381
static void gtk_text_view_insert_at_cursor (GtkTextView           *text_view,
382
                                            const gchar           *str);
383 384 385
static void gtk_text_view_delete_from_cursor (GtkTextView           *text_view,
                                              GtkDeleteType          type,
                                              gint                   count);
386
static void gtk_text_view_backspace        (GtkTextView           *text_view);
387 388 389 390
static void gtk_text_view_cut_clipboard    (GtkTextView           *text_view);
static void gtk_text_view_copy_clipboard   (GtkTextView           *text_view);
static void gtk_text_view_paste_clipboard  (GtkTextView           *text_view);
static void gtk_text_view_toggle_overwrite (GtkTextView           *text_view);
391
static void gtk_text_view_toggle_cursor_visible (GtkTextView      *text_view);
392

393
static void gtk_text_view_unselect         (GtkTextView           *text_view);
394 395 396

static void     gtk_text_view_validate_onscreen     (GtkTextView        *text_view);
static void     gtk_text_view_get_first_para_iter   (GtkTextView        *text_view,
397
                                                     GtkTextIter        *iter);
398
static void     gtk_text_view_update_layout_width       (GtkTextView        *text_view);
399 400 401
static void     gtk_text_view_set_attributes_from_style (GtkTextView        *text_view,
                                                         GtkTextAttributes *values,
                                                         GtkStyle           *style);
402 403 404 405 406 407
static void     gtk_text_view_ensure_layout          (GtkTextView        *text_view);
static void     gtk_text_view_destroy_layout         (GtkTextView        *text_view);
static void     gtk_text_view_check_keymap_direction (GtkTextView        *text_view);
static void     gtk_text_view_start_selection_drag   (GtkTextView        *text_view,
                                                      const GtkTextIter  *iter,
                                                      GdkEventButton     *event);
408
static gboolean gtk_text_view_end_selection_drag     (GtkTextView        *text_view);
409 410 411 412 413 414
static void     gtk_text_view_start_selection_dnd    (GtkTextView        *text_view,
                                                      const GtkTextIter  *iter,
                                                      GdkEventMotion     *event);
static void     gtk_text_view_check_cursor_blink     (GtkTextView        *text_view);
static void     gtk_text_view_pend_cursor_blink      (GtkTextView        *text_view);
static void     gtk_text_view_stop_cursor_blink      (GtkTextView        *text_view);
415
static void     gtk_text_view_reset_blink_time       (GtkTextView        *text_view);
416

417 418 419 420 421
static void     gtk_text_view_value_changed                (GtkAdjustment *adj,
							    GtkTextView   *view);
static void     gtk_text_view_commit_handler               (GtkIMContext  *context,
							    const gchar   *str,
							    GtkTextView   *text_view);
422 423
static void     gtk_text_view_commit_text                  (GtkTextView   *text_view,
                                                            const gchar   *text);
424 425 426 427 428 429 430 431
static void     gtk_text_view_preedit_changed_handler      (GtkIMContext  *context,
							    GtkTextView   *text_view);
static gboolean gtk_text_view_retrieve_surrounding_handler (GtkIMContext  *context,
							    GtkTextView   *text_view);
static gboolean gtk_text_view_delete_surrounding_handler   (GtkIMContext  *context,
							    gint           offset,
							    gint           n_chars,
							    GtkTextView   *text_view);
432 433

static void gtk_text_view_mark_set_handler       (GtkTextBuffer     *buffer,
434
                                                  const GtkTextIter *location,
Havoc Pennington's avatar
Havoc Pennington committed
435
                                                  GtkTextMark       *mark,
436
                                                  gpointer           data);
437 438 439
static void gtk_text_view_target_list_notify     (GtkTextBuffer     *buffer,
                                                  const GParamSpec  *pspec,
                                                  gpointer           data);
440 441 442
static void gtk_text_view_paste_done_handler     (GtkTextBuffer     *buffer,
                                                  GtkClipboard      *clipboard,
                                                  gpointer           data);
443 444
static void gtk_text_view_get_cursor_location    (GtkTextView       *text_view,
						  GdkRectangle      *pos);
445
static void gtk_text_view_get_virtual_cursor_pos (GtkTextView       *text_view,
446
                                                  GtkTextIter       *cursor,
447 448
                                                  gint              *x,
                                                  gint              *y);
449
static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
450 451
                                                  gint               x,
                                                  gint               y);
452

Owen Taylor's avatar
Owen Taylor committed
453
static void gtk_text_view_do_popup               (GtkTextView       *text_view,
Owen Taylor's avatar
Owen Taylor committed
454
						  GdkEventButton    *event);
455

456
static void cancel_pending_scroll                (GtkTextView   *text_view);
457 458 459 460 461 462 463
static void gtk_text_view_queue_scroll           (GtkTextView   *text_view,
                                                  GtkTextMark   *mark,
                                                  gdouble        within_margin,
                                                  gboolean       use_align,
                                                  gdouble        xalign,
                                                  gdouble        yalign);

464 465 466 467
static gboolean gtk_text_view_flush_scroll         (GtkTextView *text_view);
static void     gtk_text_view_update_adjustments   (GtkTextView *text_view);
static void     gtk_text_view_invalidate           (GtkTextView *text_view);
static void     gtk_text_view_flush_first_validate (GtkTextView *text_view);
468

Tadej Borovšak's avatar
Tadej Borovšak committed
469 470 471 472 473 474 475
static void     gtk_text_view_set_hadjustment        (GtkTextView   *text_view,
                                                      GtkAdjustment *adjustment);
static void     gtk_text_view_set_vadjustment        (GtkTextView   *text_view,
                                                      GtkAdjustment *adjustment);
static void     gtk_text_view_set_hadjustment_values (GtkTextView   *text_view);
static void     gtk_text_view_set_vadjustment_values (GtkTextView   *text_view);

476 477
static void gtk_text_view_update_im_spot_location (GtkTextView *text_view);

478 479 480 481 482 483 484
/* Container methods */
static void gtk_text_view_add    (GtkContainer *container,
                                  GtkWidget    *child);
static void gtk_text_view_remove (GtkContainer *container,
                                  GtkWidget    *child);
static void gtk_text_view_forall (GtkContainer *container,
                                  gboolean      include_internals,
485
                                  GtkCallback   callback,
486 487 488 489 490 491 492 493 494 495 496 497
                                  gpointer      callback_data);

/* FIXME probably need the focus methods. */

typedef struct _GtkTextViewChild GtkTextViewChild;

struct _GtkTextViewChild
{
  GtkWidget *widget;

  GtkTextChildAnchor *anchor;

498 499 500
  gint from_top_of_line;
  gint from_left_of_buffer;
  
501 502 503 504 505 506
  /* These are ignored if anchor != NULL */
  GtkTextWindowType type;
  gint x;
  gint y;
};

507 508 509 510 511 512 513 514 515 516
static GtkTextViewChild* text_view_child_new_anchored      (GtkWidget          *child,
							    GtkTextChildAnchor *anchor,
							    GtkTextLayout      *layout);
static GtkTextViewChild* text_view_child_new_window        (GtkWidget          *child,
							    GtkTextWindowType   type,
							    gint                x,
							    gint                y);
static void              text_view_child_free              (GtkTextViewChild   *child);
static void              text_view_child_set_parent_window (GtkTextView        *text_view,
							    GtkTextViewChild   *child);
517

518 519 520 521 522 523 524 525 526 527
struct _GtkTextWindow
{
  GtkTextWindowType type;
  GtkWidget *widget;
  GdkWindow *window;
  GdkWindow *bin_window;
  GtkRequisition requisition;
  GdkRectangle allocation;
};

528 529 530 531 532 533
static GtkTextWindow *text_window_new             (GtkTextWindowType  type,
                                                   GtkWidget         *widget,
                                                   gint               width_request,
                                                   gint               height_request);
static void           text_window_free            (GtkTextWindow     *win);
static void           text_window_realize         (GtkTextWindow     *win,
534
                                                   GtkWidget         *widget);
535 536 537 538 539 540 541 542
static void           text_window_unrealize       (GtkTextWindow     *win);
static void           text_window_size_allocate   (GtkTextWindow     *win,
                                                   GdkRectangle      *rect);
static void           text_window_scroll          (GtkTextWindow     *win,
                                                   gint               dx,
                                                   gint               dy);
static void           text_window_invalidate_rect (GtkTextWindow     *win,
                                                   GdkRectangle      *rect);
543
static void           text_window_invalidate_cursors (GtkTextWindow  *win);
544 545 546

static gint           text_window_get_width       (GtkTextWindow     *win);
static gint           text_window_get_height      (GtkTextWindow     *win);
547 548


549 550
static guint signals[LAST_SIGNAL] = { 0 };

Tadej Borovšak's avatar
Tadej Borovšak committed
551 552
G_DEFINE_TYPE_WITH_CODE (GtkTextView, gtk_text_view, GTK_TYPE_CONTAINER,
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
553 554

static void
555
add_move_binding (GtkBindingSet  *binding_set,
556 557 558 559
                  guint           keyval,
                  guint           modmask,
                  GtkMovementStep step,
                  gint            count)
560
{
561
  g_assert ((modmask & GDK_SHIFT_MASK) == 0);
562

563
  gtk_binding_entry_add_signal (binding_set, keyval, modmask,
564
                                "move-cursor", 3,
Manish Singh's avatar
Manish Singh committed
565 566 567
                                G_TYPE_ENUM, step,
                                G_TYPE_INT, count,
                                G_TYPE_BOOLEAN, FALSE);
568 569 570

  /* Selection-extending version */
  gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_SHIFT_MASK,
571
                                "move-cursor", 3,
Manish Singh's avatar
Manish Singh committed
572 573 574
                                G_TYPE_ENUM, step,
                                G_TYPE_INT, count,
                                G_TYPE_BOOLEAN, TRUE);
575 576 577 578 579 580 581
}

static void
gtk_text_view_class_init (GtkTextViewClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
582
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
583
  GtkBindingSet *binding_set;
584

585 586
  /* Default handlers and virtual methods
   */
587 588
  gobject_class->set_property = gtk_text_view_set_property;
  gobject_class->get_property = gtk_text_view_get_property;
589 590
  gobject_class->finalize = gtk_text_view_finalize;

591
  widget_class->destroy = gtk_text_view_destroy;
592 593 594 595
  widget_class->realize = gtk_text_view_realize;
  widget_class->unrealize = gtk_text_view_unrealize;
  widget_class->style_set = gtk_text_view_style_set;
  widget_class->direction_changed = gtk_text_view_direction_changed;
596
  widget_class->grab_notify = gtk_text_view_grab_notify;
597
  widget_class->state_changed = gtk_text_view_state_changed;
598 599
  widget_class->get_preferred_width = gtk_text_view_get_preferred_width;
  widget_class->get_preferred_height = gtk_text_view_get_preferred_height;
600 601 602 603 604 605 606 607 608
  widget_class->size_allocate = gtk_text_view_size_allocate;
  widget_class->event = gtk_text_view_event;
  widget_class->key_press_event = gtk_text_view_key_press_event;
  widget_class->key_release_event = gtk_text_view_key_release_event;
  widget_class->button_press_event = gtk_text_view_button_press_event;
  widget_class->button_release_event = gtk_text_view_button_release_event;
  widget_class->focus_in_event = gtk_text_view_focus_in_event;
  widget_class->focus_out_event = gtk_text_view_focus_out_event;
  widget_class->motion_notify_event = gtk_text_view_motion_event;
Benjamin Otte's avatar
Benjamin Otte committed
609
  widget_class->draw = gtk_text_view_draw;
610
  widget_class->focus = gtk_text_view_focus;
611 612 613 614 615 616 617 618 619 620
  widget_class->drag_begin = gtk_text_view_drag_begin;
  widget_class->drag_end = gtk_text_view_drag_end;
  widget_class->drag_data_get = gtk_text_view_drag_data_get;
  widget_class->drag_data_delete = gtk_text_view_drag_data_delete;

  widget_class->drag_leave = gtk_text_view_drag_leave;
  widget_class->drag_motion = gtk_text_view_drag_motion;
  widget_class->drag_drop = gtk_text_view_drag_drop;
  widget_class->drag_data_received = gtk_text_view_drag_data_received;

Owen Taylor's avatar
Owen Taylor committed
621 622
  widget_class->popup_menu = gtk_text_view_popup_menu;
  
623 624 625 626 627 628 629 630
  container_class->add = gtk_text_view_add;
  container_class->remove = gtk_text_view_remove;
  container_class->forall = gtk_text_view_forall;

  klass->move_cursor = gtk_text_view_move_cursor;
  klass->set_anchor = gtk_text_view_set_anchor;
  klass->insert_at_cursor = gtk_text_view_insert_at_cursor;
  klass->delete_from_cursor = gtk_text_view_delete_from_cursor;
631
  klass->backspace = gtk_text_view_backspace;
632 633 634 635 636
  klass->cut_clipboard = gtk_text_view_cut_clipboard;
  klass->copy_clipboard = gtk_text_view_copy_clipboard;
  klass->paste_clipboard = gtk_text_view_paste_clipboard;
  klass->toggle_overwrite = gtk_text_view_toggle_overwrite;

637
  /*
638
   * Properties
639
   */
640 641 642
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_ABOVE_LINES,
Matthias Clasen's avatar
x  
Matthias Clasen committed
643
                                   g_param_spec_int ("pixels-above-lines",
644 645
						     P_("Pixels Above Lines"),
						     P_("Pixels of blank space above paragraphs"),
646 647 648
						     0,
						     G_MAXINT,
						     0,
649
						     GTK_PARAM_READWRITE));
650 651 652
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_BELOW_LINES,
Matthias Clasen's avatar
x  
Matthias Clasen committed
653
                                   g_param_spec_int ("pixels-below-lines",
654 655
						     P_("Pixels Below Lines"),
						     P_("Pixels of blank space below paragraphs"),
656 657 658
						     0,
						     G_MAXINT,
						     0,
659
						     GTK_PARAM_READWRITE));
660 661 662
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_INSIDE_WRAP,
Matthias Clasen's avatar
x  
Matthias Clasen committed
663
                                   g_param_spec_int ("pixels-inside-wrap",
664 665
						     P_("Pixels Inside Wrap"),
						     P_("Pixels of blank space between wrapped lines in a paragraph"),
666 667 668
						     0,
						     G_MAXINT,
						     0,
669
						     GTK_PARAM_READWRITE));
670 671 672 673

  g_object_class_install_property (gobject_class,
                                   PROP_EDITABLE,
                                   g_param_spec_boolean ("editable",
674 675
							 P_("Editable"),
							 P_("Whether the text can be modified by the user"),
676
							 TRUE,
677
							 GTK_PARAM_READWRITE));
678 679 680

  g_object_class_install_property (gobject_class,
                                   PROP_WRAP_MODE,
Matthias Clasen's avatar
x  
Matthias Clasen committed
681
                                   g_param_spec_enum ("wrap-mode",
682 683
						      P_("Wrap Mode"),
						      P_("Whether to wrap lines never, at word boundaries, or at character boundaries"),
684 685
						      GTK_TYPE_WRAP_MODE,
						      GTK_WRAP_NONE,
686
						      GTK_PARAM_READWRITE));
687 688 689 690
 
  g_object_class_install_property (gobject_class,
                                   PROP_JUSTIFICATION,
                                   g_param_spec_enum ("justification",
691 692
						      P_("Justification"),
						      P_("Left, right, or center justification"),
693 694
						      GTK_TYPE_JUSTIFICATION,
						      GTK_JUSTIFY_LEFT,
695
						      GTK_PARAM_READWRITE));
696 697 698
 
  g_object_class_install_property (gobject_class,
                                   PROP_LEFT_MARGIN,
Matthias Clasen's avatar
x  
Matthias Clasen committed
699
                                   g_param_spec_int ("left-margin",
700 701
						     P_("Left Margin"),
						     P_("Width of the left margin in pixels"),
702 703 704
						     0,
						     G_MAXINT,
						     0,
705
						     GTK_PARAM_READWRITE));
706 707 708

  g_object_class_install_property (gobject_class,
                                   PROP_RIGHT_MARGIN,
Matthias Clasen's avatar
x  
Matthias Clasen committed
709
                                   g_param_spec_int ("right-margin",
710 711
						     P_("Right Margin"),
						     P_("Width of the right margin in pixels"),
712 713 714
						     0,
						     G_MAXINT,
						     0,
715
						     GTK_PARAM_READWRITE));
716 717 718 719

  g_object_class_install_property (gobject_class,
                                   PROP_INDENT,
                                   g_param_spec_int ("indent",
720 721
						     P_("Indent"),
						     P_("Amount to indent the paragraph, in pixels"),
722
						     G_MININT,
723 724
						     G_MAXINT,
						     0,
725
						     GTK_PARAM_READWRITE));
726 727 728 729

  g_object_class_install_property (gobject_class,
                                   PROP_TABS,
                                   g_param_spec_boxed ("tabs",
730 731
                                                       P_("Tabs"),
                                                       P_("Custom tabs for this text"),
732
                                                       PANGO_TYPE_TAB_ARRAY,
733
						       GTK_PARAM_READWRITE));
734 735 736

  g_object_class_install_property (gobject_class,
                                   PROP_CURSOR_VISIBLE,
Matthias Clasen's avatar
x  
Matthias Clasen committed
737
                                   g_param_spec_boolean ("cursor-visible",
738 739
							 P_("Cursor Visible"),
							 P_("If the insertion cursor is shown"),
740
							 TRUE,
741
							 GTK_PARAM_READWRITE));
742

743 744 745
  g_object_class_install_property (gobject_class,
                                   PROP_BUFFER,
                                   g_param_spec_object ("buffer",
746 747
							P_("Buffer"),
							P_("The buffer which is displayed"),
748
							GTK_TYPE_TEXT_BUFFER,
749
							GTK_PARAM_READWRITE));
750

751 752 753
  g_object_class_install_property (gobject_class,
                                   PROP_OVERWRITE,
                                   g_param_spec_boolean ("overwrite",
754 755
							 P_("Overwrite mode"),
							 P_("Whether entered text overwrites existing contents"),
756
							 FALSE,
757
							 GTK_PARAM_READWRITE));
758

759
  g_object_class_install_property (gobject_class,
760
                                   PROP_ACCEPTS_TAB,
Matthias Clasen's avatar
x  
Matthias Clasen committed
761
                                   g_param_spec_boolean ("accepts-tab",
762 763
							 P_("Accepts tab"),
							 P_("Whether Tab will result in a tab character being entered"),
764
							 TRUE,
765
							 GTK_PARAM_READWRITE));
766

767 768 769
   /**
    * GtkTextView:im-module:
    *
770 771
    * Which IM (input method) module should be used for this entry. 
    * See #GtkIMContext.
772 773
    *
    * Setting this to a non-%NULL value overrides the
774 775
    * system-wide IM module setting. See the GtkSettings 
    * #GtkSettings:gtk-im-module property.
776 777 778 779 780 781 782 783 784 785 786
    *
    * Since: 2.16
    */
   g_object_class_install_property (gobject_class,
                                    PROP_IM_MODULE,
                                    g_param_spec_string ("im-module",
                                                         P_("IM module"),
                                                         P_("Which IM module should be used"),
                                                         NULL,
                                                         GTK_PARAM_READWRITE));

Tadej Borovšak's avatar
Tadej Borovšak committed
787
   /* GtkScrollable interface */
788 789 790 791
   g_object_class_override_property (gobject_class, PROP_HADJUSTMENT,    "hadjustment");
   g_object_class_override_property (gobject_class, PROP_VADJUSTMENT,    "vadjustment");
   g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
   g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
Tadej Borovšak's avatar
Tadej Borovšak committed
792

793 794 795 796 797
  /*
   * Style properties
   */
  gtk_widget_class_install_style_property (widget_class,
					   g_param_spec_boxed ("error-underline-color",
798
							       P_("Error underline color"),
Owen Taylor's avatar
Owen Taylor committed
799
							       P_("Color with which to draw error-indication underlines"),
800
							       GDK_TYPE_COLOR,
801
							       GTK_PARAM_READABLE));
802
  
803 804 805 806
  /*
   * Signals
   */

807 808
  /**
   * GtkTextView::move-cursor: 
Matthias Clasen's avatar
Matthias Clasen committed
809
   * @text_view: the object which received the signal
810 811 812 813
   * @step: the granularity of the move, as a #GtkMovementStep
   * @count: the number of @step units to move
   * @extend_selection: %TRUE if the move should extend the selection
   *  
Matthias Clasen's avatar
Matthias Clasen committed
814 815 816 817 818
   * The ::move-cursor signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted when the user initiates a cursor movement. 
   * If the cursor is not visible in @text_view, this signal causes
   * the viewport to be moved instead.
819 820
   *
   * Applications should not connect to it, but may emit it with 
821
   * g_signal_emit_by_name() if they need to control the cursor
822
   * programmatically.
Matthias Clasen's avatar
Matthias Clasen committed
823 824 825 826 827 828 829 830 831 832 833 834
   *
   * The default bindings for this signal come in two variants,
   * the variant with the Shift modifier extends the selection,
   * the variant without the Shift modifer does not.
   * There are too many key combinations to list them all here.
   * <itemizedlist>
   * <listitem>Arrow keys move by individual characters/lines</listitem>
   * <listitem>Ctrl-arrow key combinations move by words/paragraphs</listitem>
   * <listitem>Home/End keys move to the ends of the buffer</listitem>
   * <listitem>PageUp/PageDown keys move vertically by pages</listitem>
   * <listitem>Ctrl-PageUp/PageDown keys move horizontally by pages</listitem>
   * </itemizedlist>
835 836
   */
  signals[MOVE_CURSOR] = 
837
    g_signal_new (I_("move-cursor"),
838 839
		  G_OBJECT_CLASS_TYPE (gobject_class), 
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, 
Manish Singh's avatar
Manish Singh committed
840
		  G_STRUCT_OFFSET (GtkTextViewClass, move_cursor),
841 842
		  NULL, NULL, 
		  _gtk_marshal_VOID__ENUM_INT_BOOLEAN, 
Manish Singh's avatar
Manish Singh committed
843
		  G_TYPE_NONE, 3,
844 845
		  GTK_TYPE_MOVEMENT_STEP, 
		  G_TYPE_INT, 
Manish Singh's avatar
Manish Singh committed
846
		  G_TYPE_BOOLEAN);
847

Matthias Clasen's avatar
Matthias Clasen committed
848 849 850 851 852 853 854 855 856 857 858 859 860 861
  /**
   * GtkTextView::move-viewport:
   * @text_view: the object which received the signal
   * @step: the granularity of the move, as a #GtkMovementStep
   * @count: the number of @step units to move
   *
   * The ::move-viewport signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which can be bound to key combinations to allow the user
   * to move the viewport, i.e. change what part of the text view
   * is visible in a containing scrolled window.
   *
   * There are no default bindings for this signal.
   */
862
  signals[MOVE_VIEWPORT] =
863
    g_signal_new_class_handler (I_("move-viewport"),
864 865 866 867 868 869 870 871
                                G_OBJECT_CLASS_TYPE (gobject_class),
                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                G_CALLBACK (gtk_text_view_move_viewport),
                                NULL, NULL,
                                _gtk_marshal_VOID__ENUM_INT,
                                G_TYPE_NONE, 2,
                                GTK_TYPE_SCROLL_STEP,
                                G_TYPE_INT);
872

Matthias Clasen's avatar
Matthias Clasen committed
873 874 875 876 877 878 879 880 881 882 883 884
  /**
   * GtkTextView::set-anchor:
   * @text_view: the object which received the signal
   *
   * The ::set-anchor signal is a
   * <link linkend="keybinding-signals">keybinding signal</link>
   * which gets emitted when the user initiates setting the "anchor" 
   * mark. The "anchor" mark gets placed at the same position as the
   * "insert" mark.
   *
   * This signal has no default bindings.
   */   
885
  signals[SET_ANCHOR] =
886
    g_signal_new (I_("set-anchor"),
Manish Singh's avatar
Manish Singh committed
887 888 889 890 891 892
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, set_anchor),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
893

Matthias Clasen's avatar
Matthias Clasen committed
894 895 896 897 898 899 900 901 902 903 904 905
  /**
   * GtkTextView::insert-at-cursor:
   * @text_view: the object which received the signal
   * @string: the string to insert
   *
   * The ::insert-at-cursor signal is a
   * <link linkend="keybinding-signals">keybinding signal</link>
   * which gets emitted when the user initiates the insertion of a 
   * fixed string at the cursor.
   *
   * This signal has no default bindings.
   */
906
  signals[INSERT_AT_CURSOR] =
907
    g_signal_new (I_("insert-at-cursor"),
Manish Singh's avatar
Manish Singh committed
908 909 910 911 912 913 914
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, insert_at_cursor),
		  NULL, NULL,
		  _gtk_marshal_VOID__STRING,
		  G_TYPE_NONE, 1,
		  G_TYPE_STRING);
915

Matthias Clasen's avatar
Matthias Clasen committed
916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934
  /**
   * GtkTextView::delete-from-cursor:
   * @text_view: the object which received the signal
   * @type: the granularity of the deletion, as a #GtkDeleteType
   * @count: the number of @type units to delete
   *
   * The ::delete-from-cursor signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted when the user initiates a text deletion.
   *
   * If the @type is %GTK_DELETE_CHARS, GTK+ deletes the selection
   * if there is one, otherwise it deletes the requested number
   * of characters.
   *
   * The default bindings for this signal are
   * Delete for deleting a character, Ctrl-Delete for 
   * deleting a word and Ctrl-Backspace for deleting a word 
   * backwords.
   */
935
  signals[DELETE_FROM_CURSOR] =
936
    g_signal_new (I_("delete-from-cursor"),
Manish Singh's avatar
Manish Singh committed
937 938 939 940 941 942 943 944
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, delete_from_cursor),
		  NULL, NULL,
		  _gtk_marshal_VOID__ENUM_INT,
		  G_TYPE_NONE, 2,
		  GTK_TYPE_DELETE_TYPE,
		  G_TYPE_INT);
945

Matthias Clasen's avatar
Matthias Clasen committed
946 947 948 949 950 951 952 953 954 955 956
  /**
   * GtkTextView::backspace:
   * @text_view: the object which received the signal
   *
   * The ::backspace signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted when the user asks for it.
   * 
   * The default bindings for this signal are
   * Backspace and Shift-Backspace.
   */
957
  signals[BACKSPACE] =
Matthias Clasen's avatar
Matthias Clasen committed
958
    g_signal_new (I_("backspace"),
959 960 961 962 963 964 965
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, backspace),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);

Matthias Clasen's avatar
Matthias Clasen committed
966 967 968 969 970 971 972 973 974 975 976
  /**
   * GtkTextView::cut-clipboard:
   * @text_view: the object which received the signal
   *
   * The ::cut-clipboard signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted to cut the selection to the clipboard.
   * 
   * The default bindings for this signal are
   * Ctrl-x and Shift-Delete.
   */
977
  signals[CUT_CLIPBOARD] =
978
    g_signal_new (I_("cut-clipboard"),
Manish Singh's avatar
Manish Singh committed
979 980 981 982 983 984
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, cut_clipboard),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
985

Matthias Clasen's avatar
Matthias Clasen committed
986 987 988 989 990 991 992 993 994 995 996
  /**
   * GtkTextView::copy-clipboard:
   * @text_view: the object which received the signal
   *
   * The ::copy-clipboard signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted to copy the selection to the clipboard.
   * 
   * The default bindings for this signal are
   * Ctrl-c and Ctrl-Insert.
   */
997
  signals[COPY_CLIPBOARD] =
998
    g_signal_new (I_("copy-clipboard"),
Manish Singh's avatar
Manish Singh committed
999 1000 1001 1002 1003 1004
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, copy_clipboard),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
1005

Matthias Clasen's avatar
Matthias Clasen committed
1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017
  /**
   * GtkTextView::paste-clipboard:
   * @text_view: the object which received the signal
   *
   * The ::paste-clipboard signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted to paste the contents of the clipboard 
   * into the text view.
   * 
   * The default bindings for this signal are
   * Ctrl-v and Shift-Insert.
   */
1018
  signals[PASTE_CLIPBOARD] =
1019
    g_signal_new (I_("paste-clipboard"),
Manish Singh's avatar
Manish Singh committed
1020 1021 1022 1023 1024 1025
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, paste_clipboard),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
1026

Matthias Clasen's avatar
Matthias Clasen committed
1027 1028 1029 1030 1031 1032
  /**
   * GtkTextView::toggle-overwrite:
   * @text_view: the object which received the signal
   *
   * The ::toggle-overwrite signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
Matthias Clasen's avatar
Matthias Clasen committed
1033
   * which gets emitted to toggle the overwrite mode of the text view.
Matthias Clasen's avatar
Matthias Clasen committed
1034 1035 1036
   * 
   * The default bindings for this signal is Insert.
   */ 
1037
  signals[TOGGLE_OVERWRITE] =
1038
    g_signal_new (I_("toggle-overwrite"),
Manish Singh's avatar
Manish Singh committed
1039 1040 1041 1042 1043 1044
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, toggle_overwrite),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
1045

Matthias Clasen's avatar
Matthias Clasen committed
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
  /**
   * GtkTextView::populate-popup:
   * @entry: The text view on which the signal is emitted
   * @menu: the menu that is being populated
   *
   * The ::populate-popup signal gets emitted before showing the 
   * context menu of the text view.
   *
   * If you need to add items to the context menu, connect
   * to this signal and append your menuitems to the @menu.
   */
Owen Taylor's avatar
Owen Taylor committed
1057
  signals[POPULATE_POPUP] =
1058
    g_signal_new (I_("populate-popup"),
Manish Singh's avatar
Manish Singh committed
1059 1060 1061 1062 1063 1064 1065
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (GtkTextViewClass, populate_popup),
		  NULL, NULL,
		  _gtk_marshal_VOID__OBJECT,
		  G_TYPE_NONE, 1,
		  GTK_TYPE_MENU);
Owen Taylor's avatar
Owen Taylor committed
1066
  
Matthias Clasen's avatar
Matthias Clasen committed
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079
  /**
   * GtkTextView::select-all:
   * @text_view: the object which received the signal
   * @select: %TRUE to select, %FALSE to unselect
   *
   * The ::select-all signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted to select or unselect the complete
   * contents of the text view.
   *
   * The default bindings for this signal are Ctrl-a and Ctrl-/ 
   * for selecting and Shift-Ctrl-a and Ctrl-\ for unselecting.
   */
1080
  signals[SELECT_ALL] =
1081
    g_signal_new_class_handler (I_("select-all"),
1082
                                G_OBJECT_CLASS_TYPE (gobject_class),
1083 1084 1085 1086 1087
                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                G_CALLBACK (gtk_text_view_select_all),
                                NULL, NULL,
                                _gtk_marshal_VOID__BOOLEAN,
                                G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
1088

Matthias Clasen's avatar
Matthias Clasen committed
1089 1090 1091 1092 1093 1094 1095 1096 1097 1098
  /**
   * GtkTextView::toggle-cursor-visible:
   * @text_view: the object which received the signal
   *
   * The ::toggle-cursor-visible signal is a 
   * <link linkend="keybinding-signals">keybinding signal</link> 
   * which gets emitted to toggle the visibility of the cursor.
   *
   * The default binding for this signal is F7.
   */ 
1099
  signals[TOGGLE_CURSOR_VISIBLE] =
1100
    g_signal_new_class_handler (I_("toggle-cursor-visible"),
1101
                                G_OBJECT_CLASS_TYPE (gobject_class),
1102 1103 1104 1105 1106
                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                G_CALLBACK (gtk_text_view_toggle_cursor_visible),
                                NULL, NULL,
                                _gtk_marshal_VOID__VOID,
                                G_TYPE_NONE, 0);
1107

1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
  /**
   * GtkTextView::preedit-changed:
   * @text_view: the object which received the signal
   * @preedit: the current preedit string
   *
   * If an input method is used, the typed text will not immediately
   * be committed to the buffer. So if you are interested in the text,
   * connect to this signal.
   *
   * This signal is only emitted if the text at the given position
   * is actually editable.
   *
   * Since: 2.20
   */
  signals[PREEDIT_CHANGED] =
    g_signal_new_class_handler (I_("preedit-changed"),
1124
                                G_OBJECT_CLASS_TYPE (gobject_class),
1125 1126 1127 1128 1129 1130 1131
                                G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
                                NULL,
                                NULL, NULL,
                                _gtk_marshal_VOID__STRING,
                                G_TYPE_NONE, 1,
                                G_TYPE_STRING);

1132 1133 1134 1135 1136
  /*
   * Key bindings
   */

  binding_set = gtk_binding_set_by_class (klass);
1137
  
1138
  /* Moving the insertion point */
1139
  add_move_binding (binding_set, GDK_KEY_Right, 0,
1140
                    GTK_MOVEMENT_VISUAL_POSITIONS, 1);
1141

1142
  add_move_binding (binding_set, GDK_KEY_KP_Right, 0,
1143 1144
                    GTK_MOVEMENT_VISUAL_POSITIONS, 1);
  
1145
  add_move_binding (binding_set, GDK_KEY_Left, 0,
1146
                    GTK_MOVEMENT_VISUAL_POSITIONS, -1);
1147

1148
  add_move_binding (binding_set, GDK_KEY_KP_Left, 0,
1149 1150
                    GTK_MOVEMENT_VISUAL_POSITIONS, -1);
  
1151
  add_move_binding (binding_set, GDK_KEY_Right, GDK_CONTROL_MASK,
1152
                    GTK_MOVEMENT_WORDS, 1);
1153

1154
  add_move_binding (binding_set, GDK_KEY_KP_Right, GDK_CONTROL_MASK,
1155 1156
                    GTK_MOVEMENT_WORDS, 1);
  
1157
  add_move_binding (binding_set, GDK_KEY_Left, GDK_CONTROL_MASK,
1158 1159
                    GTK_MOVEMENT_WORDS, -1);

1160
  add_move_binding (binding_set, GDK_KEY_KP_Left, GDK_CONTROL_MASK,
1161
                    GTK_MOVEMENT_WORDS, -1);
1162
  
1163
  add_move_binding (binding_set, GDK_KEY_Up, 0,
1164 1165
                    GTK_MOVEMENT_DISPLAY_LINES, -1);

1166
  add_move_binding (binding_set, GDK_KEY_KP_Up, 0,
1167 1168
                    GTK_MOVEMENT_DISPLAY_LINES, -1);
  
1169
  add_move_binding (binding_set, GDK_KEY_Down, 0,
1170
                    GTK_MOVEMENT_DISPLAY_LINES, 1);
1171

1172
  add_move_binding (binding_set, GDK_KEY_KP_Down, 0,
1173 1174
                    GTK_MOVEMENT_DISPLAY_LINES, 1);
  
1175
  add_move_binding (binding_set, GDK_KEY_Up, GDK_CONTROL_MASK,
1176 1177
                    GTK_MOVEMENT_PARAGRAPHS, -1);

1178
  add_move_binding (binding_set, GDK_KEY_KP_Up, GDK_CONTROL_MASK,
1179 1180
                    GTK_MOVEMENT_PARAGRAPHS, -1);
  
1181
  add_move_binding (binding_set, GDK_KEY_Down, GDK_CONTROL_MASK,
1182 1183
                    GTK_MOVEMENT_PARAGRAPHS, 1);

1184
  add_move_binding (binding_set, GDK_KEY_KP_Down, GDK_CONTROL_MASK,
1185 1186
                    GTK_MOVEMENT_PARAGRAPHS, 1);
  
1187
  add_move_binding (binding_set, GDK_KEY_Home, 0,
1188
                    GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
1189

1190
  add_move_binding (binding_set, GDK_KEY_KP_Home, 0,
1191 1192
                    GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
  
Colin Walters's avatar