gtktextview.c 243 KB
Newer Older
1 2
/* GTK - The GIMP Toolkit
 * gtktextview.c Copyright (C) 2000 Red Hat, Inc.
3
 *
4 5 6 7
 * 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.
8
 *
9 10
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 13 14 15 16 17 18 19 20 21 22 23
 * 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
24
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
25 26
 */

27 28
#include <string.h>

29
#define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API
30 31
#include "gtkbindings.h"
#include "gtkdnd.h"
32
#include "gtkimagemenuitem.h"
Owen Taylor's avatar
Owen Taylor committed
33
#include "gtkintl.h"
34
#include "gtkmain.h"
35
#include "gtkmarshalers.h"
Owen Taylor's avatar
Owen Taylor committed
36 37
#include "gtkmenu.h"
#include "gtkmenuitem.h"
38
#include "gtkseparatormenuitem.h"
39
#include "gtksettings.h"
40
#include "gtkstock.h"
41 42 43 44
#include "gtktextdisplay.h"
#include "gtktextview.h"
#include "gtkimmulticontext.h"
#include "gdk/gdkkeysyms.h"
45
#include "gtksizegroup.h"          /* FIXME http://bugzilla.gnome.org/show_bug.cgi?id=72258 */
46
#include "gtktextutil.h"
47
#include "gtkwindow.h"
48

49 50 51 52 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
/* 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.
 *
 */

84
#if 0
85 86
#define DEBUG_VALIDATION_AND_SCROLLING
#endif
87 88 89 90 91 92 93

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

94 95 96
#define SCREEN_WIDTH(widget) text_window_get_width (GTK_TEXT_VIEW (widget)->text_window)
#define SCREEN_HEIGHT(widget) text_window_get_height (GTK_TEXT_VIEW (widget)->text_window)

97 98
#define SPACE_FOR_CURSOR 1

99 100 101 102 103 104 105 106 107
struct _GtkTextPendingScroll
{
  GtkTextMark   *mark;
  gdouble        within_margin;
  gboolean       use_align;
  gdouble        xalign;
  gdouble        yalign;
};
  
108 109
enum
{
Owen Taylor's avatar
Owen Taylor committed
110 111
  SET_SCROLL_ADJUSTMENTS,
  POPULATE_POPUP,
112
  MOVE_CURSOR,
113
  PAGE_HORIZONTALLY,
114
  SET_ANCHOR,
115
  INSERT_AT_CURSOR,
116
  DELETE_FROM_CURSOR,
117 118 119
  CUT_CLIPBOARD,
  COPY_CLIPBOARD,
  PASTE_CLIPBOARD,
120
  TOGGLE_OVERWRITE,
121
  MOVE_FOCUS,
122
  MOVE_VIEWPORT,
123
  SELECT_ALL,
124 125 126
  LAST_SIGNAL
};

127 128
enum
{
129 130 131 132 133 134 135 136 137 138 139 140
  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,
141
  PROP_BUFFER,
142
  PROP_OVERWRITE,
143
  PROP_TAB_MOVES_FOCUS,
144
  LAST_PROP
145 146 147 148 149 150
};

static void gtk_text_view_init                 (GtkTextView      *text_view);
static void gtk_text_view_class_init           (GtkTextViewClass *klass);
static void gtk_text_view_destroy              (GtkObject        *object);
static void gtk_text_view_finalize             (GObject          *object);
151 152 153 154 155 156 157 158
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);
159
static void gtk_text_view_size_request         (GtkWidget        *widget,
160
                                                GtkRequisition   *requisition);
161
static void gtk_text_view_size_allocate        (GtkWidget        *widget,
162
                                                GtkAllocation    *allocation);
163 164 165
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,
166
                                                GtkStyle         *previous_style);
167
static void gtk_text_view_direction_changed    (GtkWidget        *widget,
168
                                                GtkTextDirection  previous_direction);
169 170
static void gtk_text_view_grab_notify          (GtkWidget        *widget,
					        gboolean         was_grabbed);
171 172 173
static void gtk_text_view_state_changed        (GtkWidget        *widget,
					        GtkStateType      previous_state);

174
static gint gtk_text_view_event                (GtkWidget        *widget,
175
                                                GdkEvent         *event);
176
static gint gtk_text_view_key_press_event      (GtkWidget        *widget,
177
                                                GdkEventKey      *event);
178
static gint gtk_text_view_key_release_event    (GtkWidget        *widget,
179
                                                GdkEventKey      *event);
180
static gint gtk_text_view_button_press_event   (GtkWidget        *widget,
181
                                                GdkEventButton   *event);
182
static gint gtk_text_view_button_release_event (GtkWidget        *widget,
183
                                                GdkEventButton   *event);
184
static gint gtk_text_view_focus_in_event       (GtkWidget        *widget,
185
                                                GdkEventFocus    *event);
186
static gint gtk_text_view_focus_out_event      (GtkWidget        *widget,
187
                                                GdkEventFocus    *event);
188
static gint gtk_text_view_motion_event         (GtkWidget        *widget,
189
                                                GdkEventMotion   *event);
190
static gint gtk_text_view_expose_event         (GtkWidget        *widget,
191
                                                GdkEventExpose   *expose);
192
static void gtk_text_view_draw_focus           (GtkWidget        *widget);
193 194
static gboolean gtk_text_view_focus            (GtkWidget        *widget,
                                                GtkDirectionType  direction);
195 196
static void gtk_text_view_select_all           (GtkWidget        *widget,
                                                gboolean          select);
197

198 199 200

/* Source side drag signals */
static void gtk_text_view_drag_begin       (GtkWidget        *widget,
201
                                            GdkDragContext   *context);
202
static void gtk_text_view_drag_end         (GtkWidget        *widget,
203
                                            GdkDragContext   *context);
204
static void gtk_text_view_drag_data_get    (GtkWidget        *widget,
205 206 207 208
                                            GdkDragContext   *context,
                                            GtkSelectionData *selection_data,
                                            guint             info,
                                            guint             time);
209
static void gtk_text_view_drag_data_delete (GtkWidget        *widget,
210
                                            GdkDragContext   *context);
211 212 213

/* Target side drag signals */
static void     gtk_text_view_drag_leave         (GtkWidget        *widget,
214 215
                                                  GdkDragContext   *context,
                                                  guint             time);
216
static gboolean gtk_text_view_drag_motion        (GtkWidget        *widget,
217 218 219 220
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
221
static gboolean gtk_text_view_drag_drop          (GtkWidget        *widget,
222 223 224 225
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
226
static void     gtk_text_view_drag_data_received (GtkWidget        *widget,
227 228 229 230 231 232
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  GtkSelectionData *selection_data,
                                                  guint             info,
                                                  guint             time);
233 234

static void gtk_text_view_set_scroll_adjustments (GtkTextView   *text_view,
235 236
                                                  GtkAdjustment *hadj,
                                                  GtkAdjustment *vadj);
237
static gboolean gtk_text_view_popup_menu         (GtkWidget     *widget);
238

239 240 241 242 243 244 245
static void gtk_text_view_move_cursor       (GtkTextView           *text_view,
                                             GtkMovementStep        step,
                                             gint                   count,
                                             gboolean               extend_selection);
static void gtk_text_view_page_horizontally (GtkTextView          *text_view,
                                             gint                  count,
                                             gboolean              extend_selection);
246 247 248
static void gtk_text_view_move_viewport     (GtkTextView           *text_view,
                                             GtkScrollStep          step,
                                             gint                   count);
249 250
static void gtk_text_view_set_anchor       (GtkTextView           *text_view);
static void gtk_text_view_scroll_pages     (GtkTextView           *text_view,
251 252
                                            gint                   count,
                                            gboolean               extend_selection);
253
static void gtk_text_view_scroll_hpages    (GtkTextView           *text_view,
254 255
                                            gint                   count,
                                            gboolean               extend_selection);
256
static void gtk_text_view_insert_at_cursor (GtkTextView           *text_view,
257
                                            const gchar           *str);
258 259 260
static void gtk_text_view_delete_from_cursor (GtkTextView           *text_view,
                                              GtkDeleteType          type,
                                              gint                   count);
261 262 263 264
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);
265 266
static void gtk_text_view_move_focus       (GtkTextView           *text_view,
                                            GtkDirectionType       direction_type);
267
static void gtk_text_view_unselect         (GtkTextView           *text_view);
268 269 270

static void     gtk_text_view_validate_onscreen     (GtkTextView        *text_view);
static void     gtk_text_view_get_first_para_iter   (GtkTextView        *text_view,
271
                                                     GtkTextIter        *iter);
272
static void     gtk_text_view_update_layout_width       (GtkTextView        *text_view);
273 274 275
static void     gtk_text_view_set_attributes_from_style (GtkTextView        *text_view,
                                                         GtkTextAttributes *values,
                                                         GtkStyle           *style);
276 277 278 279 280 281 282 283 284 285 286 287 288 289 290
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_reset_im_context       (GtkTextView        *text_view);
static void     gtk_text_view_start_selection_drag   (GtkTextView        *text_view,
                                                      const GtkTextIter  *iter,
                                                      GdkEventButton     *event);
static gboolean gtk_text_view_end_selection_drag     (GtkTextView        *text_view,
                                                      GdkEventButton     *event);
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);
291

292 293 294 295 296
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);
297 298
static void     gtk_text_view_commit_text                  (GtkTextView   *text_view,
                                                            const gchar   *text);
299 300 301 302 303 304 305 306
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);
307 308

static void gtk_text_view_mark_set_handler       (GtkTextBuffer     *buffer,
309
                                                  const GtkTextIter *location,
Havoc Pennington's avatar
Havoc Pennington committed
310
                                                  GtkTextMark       *mark,
311
                                                  gpointer           data);
312 313
static void gtk_text_view_get_cursor_location    (GtkTextView       *text_view,
						  GdkRectangle      *pos);
314
static void gtk_text_view_get_virtual_cursor_pos (GtkTextView       *text_view,
315 316
                                                  gint              *x,
                                                  gint              *y);
317
static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
318 319
                                                  gint               x,
                                                  gint               y);
320

321 322 323
static GtkAdjustment* get_hadjustment            (GtkTextView       *text_view);
static GtkAdjustment* get_vadjustment            (GtkTextView       *text_view);

Owen Taylor's avatar
Owen Taylor committed
324
static void gtk_text_view_do_popup               (GtkTextView       *text_view,
Owen Taylor's avatar
Owen Taylor committed
325
						  GdkEventButton    *event);
326

327 328 329 330 331 332 333
static void gtk_text_view_queue_scroll           (GtkTextView   *text_view,
                                                  GtkTextMark   *mark,
                                                  gdouble        within_margin,
                                                  gboolean       use_align,
                                                  gdouble        xalign,
                                                  gdouble        yalign);

334 335 336 337
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);
338

339 340
static void gtk_text_view_update_im_spot_location (GtkTextView *text_view);

341 342 343 344 345 346 347
/* 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,
348
                                 GtkCallback   callback,
349 350 351 352 353 354 355 356 357 358 359 360
                                  gpointer      callback_data);

/* FIXME probably need the focus methods. */

typedef struct _GtkTextViewChild GtkTextViewChild;

struct _GtkTextViewChild
{
  GtkWidget *widget;

  GtkTextChildAnchor *anchor;

361 362 363
  gint from_top_of_line;
  gint from_left_of_buffer;
  
364 365 366 367 368 369
  /* These are ignored if anchor != NULL */
  GtkTextWindowType type;
  gint x;
  gint y;
};

370 371 372 373 374 375 376 377 378 379
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);
380

381 382 383 384 385 386 387 388 389 390
struct _GtkTextWindow
{
  GtkTextWindowType type;
  GtkWidget *widget;
  GdkWindow *window;
  GdkWindow *bin_window;
  GtkRequisition requisition;
  GdkRectangle allocation;
};

391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
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,
                                                   GdkWindow         *parent);
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);

static gint           text_window_get_width       (GtkTextWindow     *win);
static gint           text_window_get_height      (GtkTextWindow     *win);
409 410


411 412
enum
{
413 414 415
  TARGET_STRING,
  TARGET_TEXT,
  TARGET_COMPOUND_TEXT,
416 417
  TARGET_UTF8_STRING,
  TARGET_TEXT_BUFFER_CONTENTS
418 419
};

420
static const GtkTargetEntry target_table[] = {
421 422
  { "GTK_TEXT_BUFFER_CONTENTS", GTK_TARGET_SAME_APP,
    TARGET_TEXT_BUFFER_CONTENTS },
423 424 425 426 427 428 429 430 431
  { "UTF8_STRING", 0, TARGET_UTF8_STRING },
  { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
  { "TEXT", 0, TARGET_TEXT },
  { "STRING",     0, TARGET_STRING }
};

static GtkContainerClass *parent_class = NULL;
static guint signals[LAST_SIGNAL] = { 0 };

Manish Singh's avatar
Manish Singh committed
432
GType
433 434
gtk_text_view_get_type (void)
{
Manish Singh's avatar
Manish Singh committed
435
  static GType our_type = 0;
436 437 438

  if (our_type == 0)
    {
Manish Singh's avatar
Manish Singh committed
439
      static const GTypeInfo our_info =
440
      {
Manish Singh's avatar
Manish Singh committed
441 442 443 444 445 446 447 448 449
	sizeof (GtkTextViewClass),
	NULL,		/* base_init */
	NULL,		/* base_finalize */
	(GClassInitFunc) gtk_text_view_class_init,
	NULL,		/* class_finalize */
	NULL,		/* class_data */
	sizeof (GtkTextView),
	0,		/* n_preallocs */
	(GInstanceInitFunc) gtk_text_view_init,
450 451
      };

Manish Singh's avatar
Manish Singh committed
452 453
      our_type = g_type_register_static (GTK_TYPE_CONTAINER, "GtkTextView",
					 &our_info, 0);
454
    }
455 456 457 458 459

  return our_type;
}

static void
460
add_move_binding (GtkBindingSet  *binding_set,
461 462 463 464
                  guint           keyval,
                  guint           modmask,
                  GtkMovementStep step,
                  gint            count)
465 466
{
  g_return_if_fail ((modmask & GDK_SHIFT_MASK) == 0);
467

468
  gtk_binding_entry_add_signal (binding_set, keyval, modmask,
469
                                "move_cursor", 3,
Manish Singh's avatar
Manish Singh committed
470 471 472
                                G_TYPE_ENUM, step,
                                G_TYPE_INT, count,
                                G_TYPE_BOOLEAN, FALSE);
473 474 475

  /* Selection-extending version */
  gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_SHIFT_MASK,
476
                                "move_cursor", 3,
Manish Singh's avatar
Manish Singh committed
477 478 479
                                G_TYPE_ENUM, step,
                                G_TYPE_INT, count,
                                G_TYPE_BOOLEAN, TRUE);
480 481 482 483 484 485 486 487
}

static void
gtk_text_view_class_init (GtkTextViewClass *klass)
{
  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
  GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
488
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
489
  GtkBindingSet *binding_set;
490

Manish Singh's avatar
Manish Singh committed
491
  parent_class = g_type_class_peek_parent (klass);
492

493 494
  /* Default handlers and virtual methods
   */
495 496
  gobject_class->set_property = gtk_text_view_set_property;
  gobject_class->get_property = gtk_text_view_get_property;
497 498 499 500 501 502 503 504

  object_class->destroy = gtk_text_view_destroy;
  gobject_class->finalize = gtk_text_view_finalize;

  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;
505
  widget_class->grab_notify = gtk_text_view_grab_notify;
506
  widget_class->state_changed = gtk_text_view_state_changed;
507 508 509 510 511 512 513 514 515 516 517
  widget_class->size_request = gtk_text_view_size_request;
  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;
  widget_class->expose_event = gtk_text_view_expose_event;
518
  widget_class->focus = gtk_text_view_focus;
519
  
520 521 522 523 524 525 526 527 528 529
  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
530 531
  widget_class->popup_menu = gtk_text_view_popup_menu;
  
532 533 534 535 536
  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;
537
  klass->page_horizontally = gtk_text_view_page_horizontally;
538 539 540 541 542 543 544
  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;
  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;
545
  klass->move_focus = gtk_text_view_move_focus;
546 547
  klass->set_scroll_adjustments = gtk_text_view_set_scroll_adjustments;

548
  /*
549
   * Properties
550
   */
551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_ABOVE_LINES,
                                   g_param_spec_int ("pixels_above_lines",
						     _("Pixels Above Lines"),
						     _("Pixels of blank space above paragraphs"),
						     0,
						     G_MAXINT,
						     0,
						     G_PARAM_READWRITE));
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_BELOW_LINES,
                                   g_param_spec_int ("pixels_below_lines",
						     _("Pixels Below Lines"),
						     _("Pixels of blank space below paragraphs"),
						     0,
						     G_MAXINT,
						     0,
						     G_PARAM_READWRITE));
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_INSIDE_WRAP,
                                   g_param_spec_int ("pixels_inside_wrap",
						     _("Pixels Inside Wrap"),
						     _("Pixels of blank space between wrapped lines in a paragraph"),
						     0,
						     G_MAXINT,
						     0,
						     G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_EDITABLE,
                                   g_param_spec_boolean ("editable",
							 _("Editable"),
							 _("Whether the text can be modified by the user"),
							 TRUE,
							 G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_WRAP_MODE,
                                   g_param_spec_enum ("wrap_mode",
						      _("Wrap Mode"),
						      _("Whether to wrap lines never, at word boundaries, or at character boundaries"),
						      GTK_TYPE_WRAP_MODE,
						      GTK_WRAP_NONE,
						      G_PARAM_READWRITE));
 
  g_object_class_install_property (gobject_class,
                                   PROP_JUSTIFICATION,
                                   g_param_spec_enum ("justification",
						      _("Justification"),
						      _("Left, right, or center justification"),
						      GTK_TYPE_JUSTIFICATION,
						      GTK_JUSTIFY_LEFT,
						      G_PARAM_READWRITE));
 
  g_object_class_install_property (gobject_class,
                                   PROP_LEFT_MARGIN,
                                   g_param_spec_int ("left_margin",
						     _("Left Margin"),
						     _("Width of the left margin in pixels"),
						     0,
						     G_MAXINT,
						     0,
						     G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_RIGHT_MARGIN,
                                   g_param_spec_int ("right_margin",
						     _("Right Margin"),
						     _("Width of the right margin in pixels"),
						     0,
						     G_MAXINT,
						     0,
						     G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_INDENT,
                                   g_param_spec_int ("indent",
						     _("Indent"),
						     _("Amount to indent the paragraph, in pixels"),
						     0,
						     G_MAXINT,
						     0,
						     G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_TABS,
                                   g_param_spec_boxed ("tabs",
                                                       _("Tabs"),
                                                       _("Custom tabs for this text"),
643
                                                       PANGO_TYPE_TAB_ARRAY,
644 645 646 647 648 649 650 651 652
						       G_PARAM_READWRITE));

  g_object_class_install_property (gobject_class,
                                   PROP_CURSOR_VISIBLE,
                                   g_param_spec_boolean ("cursor_visible",
							 _("Cursor Visible"),
							 _("If the insertion cursor is shown"),
							 TRUE,
							 G_PARAM_READWRITE));
653

654 655 656 657 658 659 660 661
  g_object_class_install_property (gobject_class,
                                   PROP_BUFFER,
                                   g_param_spec_object ("buffer",
							_("Buffer"),
							_("The buffer which is displayed"),
							GTK_TYPE_TEXT_BUFFER,
							G_PARAM_READWRITE));

662 663 664 665 666 667 668 669
  g_object_class_install_property (gobject_class,
                                   PROP_OVERWRITE,
                                   g_param_spec_boolean ("overwrite",
							 _("Overwrite mode"),
							 _("Whether entered text overwrites existing contents"),
							 FALSE,
							 G_PARAM_READWRITE));

670 671 672 673 674 675 676 677
  g_object_class_install_property (gobject_class,
                                   PROP_TAB_MOVES_FOCUS,
                                   g_param_spec_boolean ("tab_moves_focus",
							 _("Tab moves focus"),
							 _("Whether tab moves focus"),
							 FALSE,
							 G_PARAM_READWRITE));

678 679 680 681
  /*
   * Signals
   */

682
  signals[MOVE_CURSOR] =
Manish Singh's avatar
Manish Singh committed
683 684 685 686 687 688 689 690 691 692
    g_signal_new ("move_cursor",
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, move_cursor),
		  NULL, NULL,
		  _gtk_marshal_VOID__ENUM_INT_BOOLEAN,
		  G_TYPE_NONE, 3,
		  GTK_TYPE_MOVEMENT_STEP,
		  G_TYPE_INT,
		  G_TYPE_BOOLEAN);
693

694
  signals[PAGE_HORIZONTALLY] =
Manish Singh's avatar
Manish Singh committed
695 696 697 698 699 700 701 702 703
    g_signal_new ("page_horizontally",
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, page_horizontally),
		  NULL, NULL,
		  _gtk_marshal_VOID__INT_BOOLEAN,
		  G_TYPE_NONE, 2,
		  G_TYPE_INT,
		  G_TYPE_BOOLEAN);
704
  
705 706 707 708 709 710 711 712 713 714 715
  signals[MOVE_VIEWPORT] =
    _gtk_binding_signal_new ("move_viewport",
			     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);

716
  signals[SET_ANCHOR] =
Manish Singh's avatar
Manish Singh committed
717 718 719 720 721 722 723
    g_signal_new ("set_anchor",
		  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);
724 725

  signals[INSERT_AT_CURSOR] =
Manish Singh's avatar
Manish Singh committed
726 727 728 729 730 731 732 733
    g_signal_new ("insert_at_cursor",
		  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);
734

735
  signals[DELETE_FROM_CURSOR] =
Manish Singh's avatar
Manish Singh committed
736 737 738 739 740 741 742 743 744
    g_signal_new ("delete_from_cursor",
		  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);
745

746
  signals[CUT_CLIPBOARD] =
Manish Singh's avatar
Manish Singh committed
747 748 749 750 751 752 753
    g_signal_new ("cut_clipboard",
		  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);
754

755
  signals[COPY_CLIPBOARD] =
Manish Singh's avatar
Manish Singh committed
756 757 758 759 760 761 762
    g_signal_new ("copy_clipboard",
		  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);
763

764
  signals[PASTE_CLIPBOARD] =
Manish Singh's avatar
Manish Singh committed
765 766 767 768 769 770 771
    g_signal_new ("paste_clipboard",
		  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);
772 773

  signals[TOGGLE_OVERWRITE] =
Manish Singh's avatar
Manish Singh committed
774 775 776 777 778 779 780
    g_signal_new ("toggle_overwrite",
		  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);
781

782
  signals[MOVE_FOCUS] =
Manish Singh's avatar
Manish Singh committed
783 784 785 786 787 788 789 790
    g_signal_new ("move_focus",
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, move_focus),
		  NULL, NULL,
		  _gtk_marshal_VOID__ENUM,
		  G_TYPE_NONE, 1,
		  GTK_TYPE_DIRECTION_TYPE);
791
  
792
  signals[SET_SCROLL_ADJUSTMENTS] =
Manish Singh's avatar
Manish Singh committed
793 794 795 796 797 798 799 800 801
    g_signal_new ("set_scroll_adjustments",
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
		  G_STRUCT_OFFSET (GtkTextViewClass, set_scroll_adjustments),
		  NULL, NULL,
		  _gtk_marshal_VOID__OBJECT_OBJECT,
		  G_TYPE_NONE, 2,
		  GTK_TYPE_ADJUSTMENT,
		  GTK_TYPE_ADJUSTMENT);
802
  widget_class->set_scroll_adjustments_signal = signals[SET_SCROLL_ADJUSTMENTS];
803

Owen Taylor's avatar
Owen Taylor committed
804
  signals[POPULATE_POPUP] =
Manish Singh's avatar
Manish Singh committed
805 806 807 808 809 810 811 812
    g_signal_new ("populate_popup",
		  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
813
  
814 815 816 817 818 819 820 821 822 823 824
  signals[SELECT_ALL] =
    _gtk_binding_signal_new ("select_all",
			     G_OBJECT_CLASS_TYPE (object_class),
			     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, TRUE);

  
825 826 827 828 829
  /*
   * Key bindings
   */

  binding_set = gtk_binding_set_by_class (klass);
830
  
831
  /* Moving the insertion point */
832
  add_move_binding (binding_set, GDK_Right, 0,
833
                    GTK_MOVEMENT_VISUAL_POSITIONS, 1);
834

835 836 837
  add_move_binding (binding_set, GDK_KP_Right, 0,
                    GTK_MOVEMENT_VISUAL_POSITIONS, 1);
  
838
  add_move_binding (binding_set, GDK_Left, 0,
839
                    GTK_MOVEMENT_VISUAL_POSITIONS, -1);
840

841 842 843
  add_move_binding (binding_set, GDK_KP_Left, 0,
                    GTK_MOVEMENT_VISUAL_POSITIONS, -1);
  
844
  add_move_binding (binding_set, GDK_Right, GDK_CONTROL_MASK,
845
                    GTK_MOVEMENT_WORDS, 1);
846

847 848 849
  add_move_binding (binding_set, GDK_KP_Right, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_WORDS, 1);
  
850
  add_move_binding (binding_set, GDK_Left, GDK_CONTROL_MASK,
851 852
                    GTK_MOVEMENT_WORDS, -1);

853 854 855
  add_move_binding (binding_set, GDK_KP_Left, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_WORDS, 1);
  
856
  add_move_binding (binding_set, GDK_Up, 0,
857 858
                    GTK_MOVEMENT_DISPLAY_LINES, -1);

859 860 861
  add_move_binding (binding_set, GDK_KP_Up, 0,
                    GTK_MOVEMENT_DISPLAY_LINES, -1);
  
862
  add_move_binding (binding_set, GDK_Down, 0,
863
                    GTK_MOVEMENT_DISPLAY_LINES, 1);
864

865 866 867
  add_move_binding (binding_set, GDK_KP_Down, 0,
                    GTK_MOVEMENT_DISPLAY_LINES, 1);
  
868 869 870 871 872 873 874 875 876 877 878 879
  add_move_binding (binding_set, GDK_Up, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_PARAGRAPHS, -1);

  add_move_binding (binding_set, GDK_KP_Up, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_PARAGRAPHS, -1);
  
  add_move_binding (binding_set, GDK_Down, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_PARAGRAPHS, 1);

  add_move_binding (binding_set, GDK_KP_Down, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_PARAGRAPHS, 1);
  
880
  add_move_binding (binding_set, GDK_Home, 0,
881
                    GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
882

883 884 885
  add_move_binding (binding_set, GDK_KP_Home, 0,
                    GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
  
886
  add_move_binding (binding_set, GDK_End, 0,
887 888
                    GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);

889 890 891
  add_move_binding (binding_set, GDK_KP_End, 0,
                    GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);
  
892
  add_move_binding (binding_set, GDK_Home, GDK_CONTROL_MASK,
893
                    GTK_MOVEMENT_BUFFER_ENDS, -1);
894

895 896 897
  add_move_binding (binding_set, GDK_KP_Home, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_BUFFER_ENDS, -1);
  
898
  add_move_binding (binding_set, GDK_End, GDK_CONTROL_MASK,
899
                    GTK_MOVEMENT_BUFFER_ENDS, 1);
900

901 902 903
  add_move_binding (binding_set, GDK_KP_End, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_BUFFER_ENDS, 1);
  
904
  add_move_binding (binding_set, GDK_Page_Up, 0,
905
                    GTK_MOVEMENT_PAGES, -1);
906

907 908 909
  add_move_binding (binding_set, GDK_KP_Page_Up, 0,
                    GTK_MOVEMENT_PAGES, -1);
  
910
  add_move_binding (binding_set, GDK_Page_Down, 0,
911 912
                    GTK_MOVEMENT_PAGES, 1);

913 914
  add_move_binding (binding_set, GDK_KP_Page_Down, 0,
                    GTK_MOVEMENT_PAGES, 1);
915

916 917 918 919 920 921 922 923 924 925 926 927
  add_move_binding (binding_set, GDK_Page_Up, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_HORIZONTAL_PAGES, -1);

  add_move_binding (binding_set, GDK_KP_Page_Up, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_HORIZONTAL_PAGES, -1);
  
  add_move_binding (binding_set, GDK_Page_Down, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_HORIZONTAL_PAGES, 1);

  add_move_binding (binding_set, GDK_KP_Page_Down, GDK_CONTROL_MASK,
                    GTK_MOVEMENT_HORIZONTAL_PAGES, 1);

928
  /* Select all */
929
  gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK,
930 931
				"select_all", 1,
  				G_TYPE_BOOLEAN, TRUE);
932

933
  gtk_binding_entry_add_signal (binding_set, GDK_slash, GDK_CONTROL_MASK,
934 935 936 937
				"select_all", 1,
  				G_TYPE_BOOLEAN, TRUE);
  
  /* Unselect all */
938
  gtk_binding_entry_add_signal (binding_set, GDK_backslash, GDK_CONTROL_MASK,
939 940
				 "select_all", 1,
				 G_TYPE_BOOLEAN, FALSE);
941

942 943
  /* Deleting text */
  gtk_binding_entry_add_signal (binding_set, GDK_Delete, 0,
Manish Singh's avatar
Manish Singh committed
944 945 946
				"delete_from_cursor", 2,
				G_TYPE_ENUM, GTK_DELETE_CHARS,
				G_TYPE_INT, 1);
947

948
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, 0,
Manish Singh's avatar
Manish Singh committed
949 950 951
				"delete_from_cursor", 2,
				G_TYPE_ENUM, GTK_DELETE_CHARS,
				G_TYPE_INT, 1);
952
  
953
  gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0,
Manish Singh's avatar
Manish Singh committed
954 955 956
				"delete_from_cursor", 2,
				G_TYPE_ENUM, GTK_DELETE_CHARS,
				G_TYPE_INT, -1);
957

958 959
  /* Make this do the same as Backspace, to help with mis-typing */
  gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_SHIFT_MASK,
Manish Singh's avatar
Manish Singh committed
960 961 962
				"delete_from_cursor", 2,
				G_TYPE_ENUM, GTK_DELETE_CHARS,
				G_TYPE_INT, -1);
963

964
  gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
965 966 967
				"delete_from_cursor", 2,
				G_TYPE_ENUM, GTK_DELETE_WORD_ENDS,
				G_TYPE_INT, 1);
968

969
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
970 971 972
				"delete_from_cursor", 2,
				G_TYPE_ENUM, GTK_DELETE_WORD_ENDS,
				G_TYPE_INT, 1);
973
  
974
  gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
975 976 977
				"delete_from_cursor", 2,
				G_TYPE_ENUM, GTK_DELETE_WORD_ENDS,
				G_TYPE_INT, -1);
978 979 980 981

  /* Cut/copy/paste */

  gtk_binding_entry_add_signal (binding_set, GDK_x, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
982
				"cut_clipboard", 0);
983
  gtk_binding_entry_add_signal (binding_set, GDK_c, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
984
				"copy_clipboard", 0);
985
  gtk_binding_entry_add_signal (binding_set, GDK_v, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
986
				"paste_clipboard", 0);
987

988 989 990 991 992 993 994
  gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_SHIFT_MASK,
				"cut_clipboard", 0);
  gtk_binding_entry_add_signal (binding_set, GDK_Insert, GDK_CONTROL_MASK,
				"copy_clipboard", 0);
  gtk_binding_entry_add_signal (binding_set, GDK_Insert, GDK_SHIFT_MASK,
				"paste_clipboard", 0);

995 996
  /* Overwrite */
  gtk_binding_entry_add_signal (binding_set, GDK_Insert, 0,
Manish Singh's avatar
Manish Singh committed
997
				"toggle_overwrite", 0);
998
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Insert, 0,
Manish Singh's avatar
Manish Singh committed
999
				"toggle_overwrite", 0);
1000 1001 1002

  /* Control-tab focus motion */
  gtk_binding_entry_add_signal (binding_set, GDK_Tab, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
1003 1004
				"move_focus", 1,
				GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_FORWARD);
1005
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
1006 1007
				"move_focus", 1,
				GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_FORWARD);
1008 1009
  
  gtk_binding_entry_add_signal (binding_set, GDK_Tab, GDK_SHIFT_MASK | GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
1010 1011
				"move_focus", 1,
				GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD);
1012
  gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, GDK_SHIFT_MASK | GDK_CONTROL_MASK,
Manish Singh's avatar
Manish Singh committed
1013 1014
				"move_focus", 1,
				GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD);
1015 1016
}

1017
static void
1018 1019 1020
gtk_text_view_init (GtkTextView *text_view)
{
  GtkWidget *widget;
1021

1022 1023 1024 1025
  widget = GTK_WIDGET (text_view);

  GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);

1026
  /* Set up default style */
1027
  text_view->wrap_mode = GTK_WRAP_NONE;
1028 1029 1030 1031 1032 1033 1034 1035 1036
  text_view->pixels_above_lines = 0;
  text_view->pixels_below_lines = 0;
  text_view->pixels_inside_wrap = 0;
  text_view->justify = GTK_JUSTIFY_LEFT;
  text_view->left_margin = 0;
  text_view->right_margin = 0;
  text_view->indent = 0;
  text_view->tabs = NULL;
  text_view->editable = TRUE;
1037

1038
  gtk_drag_dest_set (widget,
1039
		     0,
1040 1041
                     target_table, G_N_ELEMENTS (target_table),
                     GDK_ACTION_COPY | GDK_ACTION_MOVE);
1042 1043 1044 1045 1046

  text_view->virtual_cursor_x = -1;
  text_view->virtual_cursor_y = -1;

  /* This object is completely private. No external entity can gain a reference
1047
   * to it; so we create it here and destroy it in finalize ().
1048 1049
   */
  text_view->im_context = gtk_im_multicontext_new ();
1050

Manish Singh's avatar
Manish Singh committed
1051
  g_signal_connect (text_view->im_context, "commit",
1052
                    G_CALLBACK (gtk_text_view_commit_handler), text_view);
Manish Singh's avatar
Manish Singh committed
1053
  g_signal_connect (text_view->im_context, "preedit_changed",
1054
 		    G_CALLBACK (gtk_text_view_preedit_changed_handler), text_view);
Manish Singh's avatar
Manish Singh committed
1055
  g_signal_connect (text_view->im_context, "retrieve_surrounding",
1056
 		    G_CALLBACK (gtk_text_view_retrieve_surrounding_handler), text_view);
Manish Singh's avatar
Manish Singh committed
1057
  g_signal_connect (text_view->im_context, "delete_surrounding",
1058
 		    G_CALLBACK (gtk_text_view_delete_surrounding_handler), text_view);
1059

1060
  text_view->cursor_visible = TRUE;
1061 1062 1063

  text_view->text_window = text_window_new (GTK_TEXT_WINDOW_TEXT,
                                            widget, 200, 200);
Havoc Pennington's avatar
Havoc Pennington committed
1064 1065 1066

  text_view->drag_start_x = -1;
  text_view->drag_start_y = -1;
Havoc Pennington's avatar
Havoc Pennington committed
1067 1068

  text_view->pending_place_cursor_button = 0;
1069 1070 1071

  /* We handle all our own redrawing */
  gtk_widget_set_redraw_on_allocate (widget, FALSE);
1072 1073
}

1074 1075
/**
 * gtk_text_view_new:
1076
 *
1077 1078 1079 1080 1081 1082 1083
 * Creates a new #GtkTextView. If you don't call gtk_text_view_set_buffer()
 * before using the text view, an empty default buffer will be created
 * for you. Get the buffer with gtk_text_view_get_buffer(). If you want
 * to specify your own buffer, consider gtk_text_view_new_with_buffer().
 *
 * Return value: a new #GtkTextView
 **/
1084 1085 1086
GtkWidget*
gtk_text_view_new (void)
{
Manish Singh's avatar
Manish Singh committed
1087
  return g_object_new (GTK_TYPE_TEXT_VIEW, NULL);
1088 1089
}

1090 1091 1092
/**
 * gtk_text_view_new_with_buffer:
 * @buffer: a #GtkTextBuffer
1093
 *
1094 1095 1096 1097 1098 1099
 * Creates a new #GtkTextView widget displaying the buffer
 * @buffer. One buffer can be shared among many widgets.
 * @buffer may be NULL to create a default buffer, in which case
 * this function is equivalent to gtk_text_view_new(). The
 * text view adds its own reference count to the buffer; it does not
 * take over an existing reference.
1100
 *
1101 1102
 * Return value: a new #GtkTextView.
 **/
1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
GtkWidget*
gtk_text_view_new_with_buffer (GtkTextBuffer *buffer)
{
  GtkTextView *text_view;

  text_view = (GtkTextView*)gtk_text_view_new ();

  gtk_text_view_set_buffer (text_view, buffer);

  return GTK_WIDGET (text_view);
}

1115 1116 1117 1118 1119 1120 1121 1122 1123 1124
/**
 * gtk_text_view_set_buffer:
 * @text_view: a #GtkTextView
 * @buffer: a #GtkTextBuffer
 *
 * Sets @buffer as the buffer being displayed by @text_view. The previous
 * buffer displayed by the text view is unreferenced, and a reference is
 * added to @buffer. If you owned a reference to @buffer before passing it
 * to this function, you must remove that reference yourself; #GtkTextView
 * will not "adopt" it.
1125
 *
1126
 **/
1127
void
1128
gtk_text_view_set_buffer (GtkTextView   *text_view,
1129
                          GtkTextBuffer *buffer)
1130 1131 1132
{
  g_return_if_fail (GTK_IS_TEXT_VIEW (text_view));
  g_return_if_fail (buffer == NULL || GTK_IS_TEXT_BUFFER (buffer));
1133

1134 1135 1136 1137 1138
  if (text_view->buffer == buffer)
    return;

  if (text_view->buffer != NULL)
    {
1139 1140 1141
      /* Destroy all anchored children */
      GSList *tmp_list;
      GSList *copy;
1142

1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153
      copy = g_slist_copy (text_view->children);
      tmp_list = copy;
      while (tmp_list != NULL)
        {
          GtkTextViewChild *vc = tmp_list->data;

          if (vc->anchor)
            {
              gtk_widget_destroy (vc->widget);
              /* vc may now be invalid! */
            }
1154

1155 1156 1157 1158
          tmp_list = g_slist_next (tmp_list);
        }

      g_slist_free (copy);
1159

Manish Singh's avatar
Manish Singh committed
1160 1161 1162 1163
      g_signal_handlers_disconnect_by_func (text_view->buffer,
					    gtk_text_view_mark_set_handler,
					    text_view);
      g_object_unref (text_view->buffer);
1164
      text_view->dnd_mark = NULL;
1165 1166

      if (GTK_WIDGET_REALIZED (text_view))
1167 1168 1169 1170 1171
	{
	  GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view),
							      GDK_SELECTION_PRIMARY);
	  gtk_text_buffer_remove_selection_clipboard (text_view->buffer, clipboard);
	}
1172 1173 1174
    }

  text_view->buffer = buffer;
1175

1176 1177 1178
  if (buffer != NULL)
    {
      GtkTextIter start;
1179

Manish Singh's avatar
Manish Singh committed
1180
      g_object_ref (buffer);
1181 1182 1183 1184

      if (text_view->layout)
        gtk_text_layout_set_buffer (text_view->layout, buffer);

1185
      gtk_text_buffer_get_iter_at_offset (text_view->buffer, &start, 0);
1186

1187
      text_view->dnd_mark = gtk_text_buffer_create_mark (text_view->buffer,
1188 1189
                                                         "gtk_drag_target",
                                                         &start, FALSE);
1190 1191

      text_view->first_para_mark = gtk_text_buffer_create_mark (text_view->buffer,
1192
                                                                NULL,
1193 1194
                                                                &start, TRUE);

1195
      text_view->first_para_pixels = 0;
1196

Manish Singh's avatar
Manish Singh committed
1197
      g_signal_connect (text_view->buffer, "mark_set",
1198
			G_CALLBACK (gtk_text_view_mark_set_handler), text_view);
1199 1200

      if (GTK_WIDGET_REALIZED (text_view))
1201 1202 1203 1204 1205
	{
	  GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view),
							      GDK_SELECTION_PRIMARY);
	  gtk_text_buffer_add_selection_clipboard (text_view->buffer, clipboard);
	}
1206
    }
1207 1208

  g_object_notify (G_OBJECT (text_view), "buffer");
1209
  
1210
  if (GTK_WIDGET_VISIBLE (text_view))
</