zlh and g_signal_new()

来源:互联网 发布:linux 查看系统信息 编辑:程序博客网 时间:2024/06/06 18:51
#include <config.h>
#include <string.h>

#define GTK_TEXT_USE_INTERNAL_UNSUPPORTED_API
#include "gtkimmulticontext.h"
#include "gdk/gdkkeysyms.h"
#include "gtkprivate.h"
#include "gtksizegroup.h"          /* FIXME http://bugzilla.gnome.org/show_bug.cgi?id=72258 */
#include "gtktextutil.h"
#include "gtkwindow.h"
#include "gtkalias.h"

#if 0
#define DEBUG_VALIDATION_AND_SCROLLING
#endif

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

#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)

#define SPACE_FOR_CURSOR 1

struct _GtkTextPendingScroll
{
  GtkTextMark   *mark;
  gdouble        within_margin;
  gboolean       use_align;
  gdouble        xalign;
  gdouble        yalign;
};
 
enum
{
  SET_SCROLL_ADJUSTMENTS,
  POPULATE_POPUP,
  MOVE_CURSOR,
  PAGE_HORIZONTALLY,
  SET_ANCHOR,
  INSERT_AT_CURSOR,
  DELETE_FROM_CURSOR,
    LAST_SIGNAL
};

enum
{
  PROP_0,
  PROP_PIXELS_ABOVE_LINES,
  PROP_PIXELS_BELOW_LINES,
  PROP_PIXELS_INSIDE_WRAP,
  PROP_EDITABLE,
  PROP_WRAP_MODE,
    LAST_PROP
};

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);
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);
static void gtk_text_view_size_request         (GtkWidget        *widget,
                                                GtkRequisition   *requisition);
static void gtk_text_view_size_allocate        (GtkWidget        *widget,
                                                GtkAllocation    *allocation);
static void gtk_text_view_realize              (GtkWidget        *widget);
static void gtk_text_view_unrealize            (GtkWidget        *widget);
/* Target side drag signals */
static void     gtk_text_view_drag_leave         (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  guint             time);
static gboolean gtk_text_view_drag_motion        (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
static gboolean gtk_text_view_drag_drop          (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  guint             time);
static void     gtk_text_view_drag_data_received (GtkWidget        *widget,
                                                  GdkDragContext   *context,
                                                  gint              x,
                                                  gint              y,
                                                  GtkSelectionData *selection_data,
                                                  guint             info,
                                                  guint             time);

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

static void gtk_text_view_move_cursor       (GtkTextView           *text_view,
                                             GtkMovementStep        step,
                                             gint                   count,
                                             gboolean               extend_selection);
static void gtk_text_view_mark_set_handler       (GtkTextBuffer     *buffer,
                                                  const GtkTextIter *location,
                                                  GtkTextMark       *mark,
                                                  gpointer           data);
static void gtk_text_view_get_cursor_location    (GtkTextView       *text_view,
        GdkRectangle      *pos);
static void gtk_text_view_get_virtual_cursor_pos (GtkTextView       *text_view,
                                                  gint              *x,
                                                  gint              *y);
static void gtk_text_view_set_virtual_cursor_pos (GtkTextView       *text_view,
                                                  gint               x,
                                                  gint               y);

static GtkAdjustment* get_hadjustment            (GtkTextView       *text_view);
static GtkAdjustment* get_vadjustment            (GtkTextView       *text_view);

static void gtk_text_view_do_popup               (GtkTextView       *text_view,
        GdkEventButton    *event);

static void gtk_text_view_queue_scroll           (GtkTextView   *text_view,
                                                  GtkTextMark   *mark,
                                                  gdouble        within_margin,
                                                  gboolean       use_align,
                                                  gdouble        xalign,
                                                  gdouble        yalign);

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);

static void gtk_text_view_update_im_spot_location (GtkTextView *text_view);

/* 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,
                                  GtkCallback   callback,
                                  gpointer      callback_data);

/* FIXME probably need the focus methods. */

typedef struct _GtkTextViewChild GtkTextViewChild;

struct _GtkTextViewChild
{
  GtkWidget *widget;

  GtkTextChildAnchor *anchor;

  gint from_top_of_line;
  gint from_left_of_buffer;
 
  /* These are ignored if anchor != NULL */
  GtkTextWindowType type;
  gint x;
  gint y;
};

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);

struct _GtkTextWindow
{
  GtkTextWindowType type;
  GtkWidget *widget;
  GdkWindow *window;
  GdkWindow *bin_window;
  GtkRequisition requisition;
  GdkRectangle allocation;
};

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 gint           text_window_get_height      (GtkTextWindow     *win);


static const GtkTargetEntry target_table[] = {
  { "GTK_TEXT_BUFFER_CONTENTS", GTK_TARGET_SAME_APP, 0 },
};

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

GType
gtk_text_view_get_type (void)
{
  static GType our_type = 0;

  if (our_type == 0)
    {
      static const GTypeInfo our_info =
      {
 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,
      };

      our_type = g_type_register_static (GTK_TYPE_CONTAINER, I_("GtkTextView"),
      &our_info, 0);
    }

  return our_type;
}

static void
add_move_binding (GtkBindingSet  *binding_set,
                  guint           keyval,
                  guint           modmask,
                  GtkMovementStep step,
                  gint            count)
{
  g_return_if_fail ((modmask & GDK_SHIFT_MASK) == 0);

  gtk_binding_entry_add_signal (binding_set, keyval, modmask,
                                "move_cursor", 3,
                                G_TYPE_ENUM, step,
                                G_TYPE_INT, count,
                                G_TYPE_BOOLEAN, FALSE);

  /* Selection-extending version */
  gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_SHIFT_MASK,
                                "move_cursor", 3,
                                G_TYPE_ENUM, step,
                                G_TYPE_INT, count,
                                G_TYPE_BOOLEAN, TRUE);
}

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);
  GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
  GtkBindingSet *binding_set;

  parent_class = g_type_class_peek_parent (klass);

  /* Default handlers and virtual methods
   */
  gobject_class->set_property = gtk_text_view_set_property;
  gobject_class->get_property = gtk_text_view_get_property;

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

  klass->move_focus = gtk_text_view_move_focus;
  klass->set_scroll_adjustments = gtk_text_view_set_scroll_adjustments;

  /*
   * Properties
   */
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_ABOVE_LINES,
                                   g_param_spec_int ("pixels-above-lines",
           P_("Pixels Above Lines"),
           P_("Pixels of blank space above paragraphs"),
           0,
           G_MAXINT,
           0,
           GTK_PARAM_READWRITE));
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_BELOW_LINES,
                                   g_param_spec_int ("pixels-below-lines",
           P_("Pixels Below Lines"),
           P_("Pixels of blank space below paragraphs"),
           0,
           G_MAXINT,
           0,
           GTK_PARAM_READWRITE));
 
  g_object_class_install_property (gobject_class,
                                   PROP_PIXELS_INSIDE_WRAP,
                                   g_param_spec_int ("pixels-inside-wrap",
           P_("Pixels Inside Wrap"),
           P_("Pixels of blank space between wrapped lines in a paragraph"),
           0,
           G_MAXINT,
           0,
           GTK_PARAM_READWRITE));

  /*
   * Style properties
   */
  gtk_widget_class_install_style_property (widget_class,
        g_param_spec_boxed ("error-underline-color",
              P_("Error underline color"),
              P_("Color with which to draw error-indication underlines"),
              GDK_TYPE_COLOR,
              GTK_PARAM_READABLE));
 
  /*
   * Signals
   */

  /**
   * GtkTextView::move-cursor:
   * @widget: the object which received the signal
   * @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
   * 
   * The ::move-cursor signal is a keybinding signal which gets emitted
   * when the user initiates a cursor movement.
   *
   * Applications should not connect to it, but may emit it with
   * g_signal_emit_by_name() if they need to control scrolling
   * programmatically.
   *
   */
  signals[MOVE_CURSOR] =
    g_signal_new (I_("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);

  signals[PAGE_HORIZONTALLY] =
    g_signal_new (I_("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);
 
  signals[MOVE_VIEWPORT] =
    _gtk_binding_signal_new (I_("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);

  signals[SET_ANCHOR] =
    g_signal_new (I_("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);

  signals[INSERT_AT_CURSOR] =
    g_signal_new (I_("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);

  signals[DELETE_FROM_CURSOR] =
    g_signal_new (I_("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);

  signals[BACKSPACE] =
    g_signal_new (I_("backspace"),
    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);

  signals[CUT_CLIPBOARD] =
    g_signal_new (I_("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);

  signals[COPY_CLIPBOARD] =
    g_signal_new (I_("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);

原创粉丝点击