📄 gtkeditable.c
字号:
/* GTK - The GIMP Toolkit * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library 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-1999. 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 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. */#include <ctype.h>#include <string.h>#ifdef USE_XIM#include "gdk/gdkx.h"#endif#include "gdk/gdkkeysyms.h"#include "gdk/gdki18n.h"#include "gtkeditable.h"#include "gtkmain.h"#include "gtkselection.h"#include "gtksignal.h"#define MIN_EDITABLE_WIDTH 150#define DRAW_TIMEOUT 20#define INNER_BORDER 2enum { CHANGED, INSERT_TEXT, DELETE_TEXT, /* Binding actions */ ACTIVATE, SET_EDITABLE, MOVE_CURSOR, MOVE_WORD, MOVE_PAGE, MOVE_TO_ROW, MOVE_TO_COLUMN, KILL_CHAR, KILL_WORD, KILL_LINE, CUT_CLIPBOARD, COPY_CLIPBOARD, PASTE_CLIPBOARD, LAST_SIGNAL};enum { ARG_0, ARG_TEXT_POSITION, ARG_EDITABLE};/* values for selection info */enum { TARGET_STRING, TARGET_TEXT, TARGET_COMPOUND_TEXT};static void gtk_editable_class_init (GtkEditableClass *klass);static void gtk_editable_init (GtkEditable *editable);static void gtk_editable_set_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void gtk_editable_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);static void *gtk_editable_get_public_chars (GtkEditable *editable, gint start, gint end);static gint gtk_editable_selection_clear (GtkWidget *widget, GdkEventSelection *event);static void gtk_editable_selection_get (GtkWidget *widget, GtkSelectionData *selection_data, guint info, guint time);static void gtk_editable_selection_received (GtkWidget *widget, GtkSelectionData *selection_data, guint time);static void gtk_editable_set_selection (GtkEditable *editable, gint start, gint end);static guint32 gtk_editable_get_event_time (GtkEditable *editable);static void gtk_editable_real_cut_clipboard (GtkEditable *editable);static void gtk_editable_real_copy_clipboard (GtkEditable *editable);static void gtk_editable_real_paste_clipboard (GtkEditable *editable);static void gtk_editable_real_set_editable (GtkEditable *editable, gboolean is_editable); static GtkWidgetClass *parent_class = NULL;static guint editable_signals[LAST_SIGNAL] = { 0 };static GdkAtom clipboard_atom = GDK_NONE;GtkTypegtk_editable_get_type (void){ static GtkType editable_type = 0; if (!editable_type) { static const GtkTypeInfo editable_info = { "GtkEditable", sizeof (GtkEditable), sizeof (GtkEditableClass), (GtkClassInitFunc) gtk_editable_class_init, (GtkObjectInitFunc) gtk_editable_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, }; editable_type = gtk_type_unique (GTK_TYPE_WIDGET, &editable_info); } return editable_type;}static voidgtk_editable_class_init (GtkEditableClass *class){ GtkObjectClass *object_class; GtkWidgetClass *widget_class; object_class = (GtkObjectClass*) class; widget_class = (GtkWidgetClass*) class; parent_class = gtk_type_class (GTK_TYPE_WIDGET); editable_signals[CHANGED] = gtk_signal_new ("changed", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, changed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); editable_signals[INSERT_TEXT] = gtk_signal_new ("insert_text", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, insert_text), gtk_marshal_NONE__POINTER_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_STRING, GTK_TYPE_INT, GTK_TYPE_POINTER); editable_signals[DELETE_TEXT] = gtk_signal_new ("delete_text", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, delete_text), gtk_marshal_NONE__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); editable_signals[ACTIVATE] = gtk_signal_new ("activate", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, activate), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); widget_class->activate_signal = editable_signals[ACTIVATE]; editable_signals[SET_EDITABLE] = gtk_signal_new ("set-editable", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, set_editable), gtk_marshal_NONE__BOOL, GTK_TYPE_NONE, 1, GTK_TYPE_BOOL); editable_signals[MOVE_CURSOR] = gtk_signal_new ("move_cursor", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, move_cursor), gtk_marshal_NONE__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); editable_signals[MOVE_WORD] = gtk_signal_new ("move_word", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, move_word), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); editable_signals[MOVE_PAGE] = gtk_signal_new ("move_page", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, move_page), gtk_marshal_NONE__INT_INT, GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT); editable_signals[MOVE_TO_ROW] = gtk_signal_new ("move_to_row", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, move_to_row), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); editable_signals[MOVE_TO_COLUMN] = gtk_signal_new ("move_to_column", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, move_to_column), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); editable_signals[KILL_CHAR] = gtk_signal_new ("kill_char", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, kill_char), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); editable_signals[KILL_WORD] = gtk_signal_new ("kill_word", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, kill_word), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); editable_signals[KILL_LINE] = gtk_signal_new ("kill_line", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, kill_line), gtk_marshal_NONE__INT, GTK_TYPE_NONE, 1, GTK_TYPE_INT); editable_signals[CUT_CLIPBOARD] = gtk_signal_new ("cut_clipboard", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, cut_clipboard), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); editable_signals[COPY_CLIPBOARD] = gtk_signal_new ("copy_clipboard", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, copy_clipboard), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); editable_signals[PASTE_CLIPBOARD] = gtk_signal_new ("paste_clipboard", GTK_RUN_LAST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkEditableClass, paste_clipboard), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, editable_signals, LAST_SIGNAL); gtk_object_add_arg_type ("GtkEditable::text_position", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_TEXT_POSITION); gtk_object_add_arg_type ("GtkEditable::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE); object_class->set_arg = gtk_editable_set_arg; object_class->get_arg = gtk_editable_get_arg; widget_class->selection_clear_event = gtk_editable_selection_clear; widget_class->selection_received = gtk_editable_selection_received; widget_class->selection_get = gtk_editable_selection_get; class->insert_text = NULL; class->delete_text = NULL; class->activate = NULL; class->set_editable = gtk_editable_real_set_editable; class->move_cursor = NULL; class->move_word = NULL; class->move_page = NULL; class->move_to_row = NULL; class->move_to_column = NULL; class->kill_char = NULL; class->kill_word = NULL; class->kill_line = NULL; class->cut_clipboard = gtk_editable_real_cut_clipboard; class->copy_clipboard = gtk_editable_real_copy_clipboard; class->paste_clipboard = gtk_editable_real_paste_clipboard; class->update_text = NULL; class->get_chars = NULL; class->set_selection = NULL; class->set_position = NULL;}static voidgtk_editable_set_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkEditable *editable; editable = GTK_EDITABLE (object); switch (arg_id) { case ARG_TEXT_POSITION: gtk_editable_set_position (editable, GTK_VALUE_INT (*arg)); break; case ARG_EDITABLE: gtk_editable_set_editable (editable, GTK_VALUE_BOOL (*arg)); break; default: break; }}static voidgtk_editable_get_arg (GtkObject *object, GtkArg *arg, guint arg_id){ GtkEditable *editable; editable = GTK_EDITABLE (object); switch (arg_id) { case ARG_TEXT_POSITION: GTK_VALUE_INT (*arg) = editable->current_pos; break; case ARG_EDITABLE: GTK_VALUE_BOOL (*arg) = editable->editable; break; default: arg->type = GTK_TYPE_INVALID; break; }}static voidgtk_editable_init (GtkEditable *editable){ static const GtkTargetEntry targets[] = { { "STRING", 0, TARGET_STRING }, { "TEXT", 0, TARGET_TEXT }, { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT } }; static const gint n_targets = sizeof(targets) / sizeof(targets[0]); GTK_WIDGET_SET_FLAGS (editable, GTK_CAN_FOCUS); editable->selection_start_pos = 0; editable->selection_end_pos = 0; editable->has_selection = FALSE; editable->editable = 1; editable->visible = 1; editable->clipboard_text = NULL;#ifdef USE_XIM editable->ic = NULL;#endif if (!clipboard_atom) clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); gtk_selection_add_targets (GTK_WIDGET (editable), GDK_SELECTION_PRIMARY, targets, n_targets); gtk_selection_add_targets (GTK_WIDGET (editable), clipboard_atom, targets, n_targets);}voidgtk_editable_insert_text (GtkEditable *editable, const gchar *new_text, gint new_text_length, gint *position){ GtkEditableClass *klass; gchar buf[64]; gchar *text; g_return_if_fail (editable != NULL); g_return_if_fail (GTK_IS_EDITABLE (editable)); gtk_widget_ref (GTK_WIDGET (editable)); klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass); if (new_text_length <= 64) text = buf; else text = g_new (gchar, new_text_length); strncpy (text, new_text, new_text_length); gtk_signal_emit (GTK_OBJECT (editable), editable_signals[INSERT_TEXT], text, new_text_length, position); gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]); if (new_text_length > 64) g_free (text); gtk_widget_unref (GTK_WIDGET (editable));}voidgtk_editable_delete_text (GtkEditable *editable, gint start_pos, gint end_pos){ GtkEditableClass *klass; g_return_if_fail (editable != NULL); g_return_if_fail (GTK_IS_EDITABLE (editable)); gtk_widget_ref (GTK_WIDGET (editable)); klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass); gtk_signal_emit (GTK_OBJECT (editable), editable_signals[DELETE_TEXT], start_pos, end_pos); gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]); gtk_widget_unref (GTK_WIDGET (editable));}static voidgtk_editable_update_text (GtkEditable *editable, gint start_pos, gint end_pos){ GtkEditableClass *klass; g_return_if_fail (editable != NULL); g_return_if_fail (GTK_IS_EDITABLE (editable)); klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass); klass->update_text (editable, start_pos, end_pos);}gchar * gtk_editable_get_chars (GtkEditable *editable, gint start, gint end){ GtkEditableClass *klass; g_return_val_if_fail (editable != NULL, NULL); g_return_val_if_fail (GTK_IS_EDITABLE (editable), NULL); klass = GTK_EDITABLE_CLASS (GTK_OBJECT (editable)->klass); return klass->get_chars (editable, start, end);}/* * Like gtk_editable_get_chars, but if the editable is not * visible, return asterisks */static void *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -