gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]

Sat Feb 28 23:58:54 1998  Owen Taylor  <owt1@cornell.edu>

	* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]

	Created a new base widget type Editable for the entry and
	text widgets, which encapsulates most of the selection and
	clipboard handling stuff, plus some common signals.

	Changed the Entry widget extensively to support this,
	but the interface and appearance should be the same.

	Changed the Text widget moderately to support this.

	It now supports:

	- Selection style cut and paste
	- Clipboard style cut and paste
	- Emacs style key bindings (~same as Entry)
	- Word motion
	- "changed" signal

	There are definitely still some bugs in the new stuff.

	* gtkfilesel.c gtkspinbutton.c testgtk.c: small changes
	to fit the new interface more exactly.
This commit is contained in:
Owen Taylor 1998-03-01 05:11:05 +00:00 committed by Owen Taylor
parent d491547e86
commit 9205edae41
18 changed files with 1973 additions and 913 deletions

View File

@ -1,3 +1,25 @@
Sat Feb 28 23:58:54 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]
Created a new base widget type Editable for the entry and
text widgets, which encapsulates most of the selection and
clipboard handling stuff, plus some common signals.
Changed the Entry widget extensively to support this,
but the interface and appearance should be the same.
Changed the Text widget moderately to support this.
It now supports:
- Selection style cut and paste
- Clipboard style cut and paste
- Emacs style key bindings (~same as Entry)
- Word motion
There are definitely still some bugs in the new stuff.
Sat Feb 28 19:29:09 1998 Tim Janik <timj@gimp.org>
* gtk/gtkclist.c (gtk_clist_new_with_titles): retrive the clist widget

View File

@ -1,3 +1,25 @@
Sat Feb 28 23:58:54 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]
Created a new base widget type Editable for the entry and
text widgets, which encapsulates most of the selection and
clipboard handling stuff, plus some common signals.
Changed the Entry widget extensively to support this,
but the interface and appearance should be the same.
Changed the Text widget moderately to support this.
It now supports:
- Selection style cut and paste
- Clipboard style cut and paste
- Emacs style key bindings (~same as Entry)
- Word motion
There are definitely still some bugs in the new stuff.
Sat Feb 28 19:29:09 1998 Tim Janik <timj@gimp.org>
* gtk/gtkclist.c (gtk_clist_new_with_titles): retrive the clist widget

View File

@ -1,3 +1,25 @@
Sat Feb 28 23:58:54 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]
Created a new base widget type Editable for the entry and
text widgets, which encapsulates most of the selection and
clipboard handling stuff, plus some common signals.
Changed the Entry widget extensively to support this,
but the interface and appearance should be the same.
Changed the Text widget moderately to support this.
It now supports:
- Selection style cut and paste
- Clipboard style cut and paste
- Emacs style key bindings (~same as Entry)
- Word motion
There are definitely still some bugs in the new stuff.
Sat Feb 28 19:29:09 1998 Tim Janik <timj@gimp.org>
* gtk/gtkclist.c (gtk_clist_new_with_titles): retrive the clist widget

View File

@ -1,3 +1,25 @@
Sat Feb 28 23:58:54 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]
Created a new base widget type Editable for the entry and
text widgets, which encapsulates most of the selection and
clipboard handling stuff, plus some common signals.
Changed the Entry widget extensively to support this,
but the interface and appearance should be the same.
Changed the Text widget moderately to support this.
It now supports:
- Selection style cut and paste
- Clipboard style cut and paste
- Emacs style key bindings (~same as Entry)
- Word motion
There are definitely still some bugs in the new stuff.
Sat Feb 28 19:29:09 1998 Tim Janik <timj@gimp.org>
* gtk/gtkclist.c (gtk_clist_new_with_titles): retrive the clist widget

View File

@ -1,3 +1,25 @@
Sat Feb 28 23:58:54 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]
Created a new base widget type Editable for the entry and
text widgets, which encapsulates most of the selection and
clipboard handling stuff, plus some common signals.
Changed the Entry widget extensively to support this,
but the interface and appearance should be the same.
Changed the Text widget moderately to support this.
It now supports:
- Selection style cut and paste
- Clipboard style cut and paste
- Emacs style key bindings (~same as Entry)
- Word motion
There are definitely still some bugs in the new stuff.
Sat Feb 28 19:29:09 1998 Tim Janik <timj@gimp.org>
* gtk/gtkclist.c (gtk_clist_new_with_titles): retrive the clist widget

View File

@ -1,3 +1,25 @@
Sat Feb 28 23:58:54 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]
Created a new base widget type Editable for the entry and
text widgets, which encapsulates most of the selection and
clipboard handling stuff, plus some common signals.
Changed the Entry widget extensively to support this,
but the interface and appearance should be the same.
Changed the Text widget moderately to support this.
It now supports:
- Selection style cut and paste
- Clipboard style cut and paste
- Emacs style key bindings (~same as Entry)
- Word motion
There are definitely still some bugs in the new stuff.
Sat Feb 28 19:29:09 1998 Tim Janik <timj@gimp.org>
* gtk/gtkclist.c (gtk_clist_new_with_titles): retrive the clist widget

View File

@ -1,3 +1,25 @@
Sat Feb 28 23:58:54 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkentry.[ch] gtktext.c gtkeditable.[ch]
Created a new base widget type Editable for the entry and
text widgets, which encapsulates most of the selection and
clipboard handling stuff, plus some common signals.
Changed the Entry widget extensively to support this,
but the interface and appearance should be the same.
Changed the Text widget moderately to support this.
It now supports:
- Selection style cut and paste
- Clipboard style cut and paste
- Emacs style key bindings (~same as Entry)
- Word motion
There are definitely still some bugs in the new stuff.
Sat Feb 28 19:29:09 1998 Tim Janik <timj@gimp.org>
* gtk/gtkclist.c (gtk_clist_new_with_titles): retrive the clist widget

31
TODO
View File

@ -57,6 +57,8 @@ Bugs:
segfault in malloc
-timj
* Change bitfields to guints from enums for C++ ?
Additions:
* it might be good to ues stdio and getch() instead of 1-character reads.
so one can take advantage of buffering. Currently each read() takes a separate
@ -111,3 +113,32 @@ TODO AFTER GTK 1.0
This will be covered by upcoming themability, raster is working on it.
* More work on Documentation
* Check return values on all calls to XIC[Get/Set]Values
* Rewrite the interface to the i18n stuff so GTK widgets don't need to
retrieve X values, and so they don't have to know the value of the
XNxxx character constants.
* The "-geometry" option should be supported
- Having gdk_init() parse the geometry option. (putting it into
GDK means you can use XParseGeometry() without wrapping it)
- Add a call gdk_get_geometry() that retrieves the results
in a form like that returned by XParseGeometry()
- The application then can modify the results (as would gemvt)
then call a routine gtk_window_set_geometry() on whatever
it considers to be its main window.
- Then in some manner GtkWindow takes that into account when
setting its hints. (Probably it uses the size and position
as the current uposition and usize, and modulates that
be the equivalents of the X flags
XValue, YValue, WidthValue, HeightValue, XNegative, or YNegative
( You'd have to extend gdk_window_set_hints to accept the
window gravity option to get it right. )

View File

@ -24,6 +24,7 @@ libgtk_la_SOURCES = \
gtkdata.c \
gtkdialog.c \
gtkdrawingarea.c \
gtkeditable.c \
gtkentry.c \
gtkeventbox.c \
gtkfilesel.c \
@ -117,6 +118,7 @@ gtkinclude_HEADERS = \
gtkdebug.h \
gtkdialog.h \
gtkdrawingarea.h \
gtkeditable.h \
gtkentry.h \
gtkenums.h \
gtkeventbox.h \
@ -213,7 +215,8 @@ EXTRA_DIST = \
tree_plus.xpm \
tree_minus.xpm \
tree_plus.xbm \
tree_minus.xbm
tree_minus.xbm \
circles.xbm
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/glib @x_cflags@

View File

@ -39,6 +39,7 @@
#include <gtk/gtkdata.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkdrawingarea.h>
#include <gtk/gtkeditable.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkeventbox.h>

664
gtk/gtkeditable.c Normal file
View File

@ -0,0 +1,664 @@
/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#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 2
enum {
INSERT_TEXT,
DELETE_TEXT,
UPDATE_TEXT,
GET_CHARS,
SET_SELECTION,
CHANGED,
LAST_SIGNAL
};
typedef void (*GtkEditableSignal1) (GtkObject *object,
gpointer arg1,
gint arg2,
gpointer arg3,
gpointer data);
typedef void (*GtkEditableSignal2) (GtkObject *object,
gint arg1,
gint arg2,
gpointer data);
typedef gpointer (*GtkEditableSignal3) (GtkObject *object,
gint arg1,
gint arg2,
gpointer data);
static void gtk_editable_marshal_signal_1 (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args);
static void gtk_editable_marshal_signal_2 (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args);
static void gtk_editable_marshal_signal_3 (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args);
static void gtk_editable_class_init (GtkEditableClass *klass);
static void gtk_editable_init (GtkEditable *editable);
static void gtk_editable_finalize (GtkObject *object);
static gint gtk_editable_selection_clear (GtkWidget *widget,
GdkEventSelection *event);
static void gtk_editable_selection_handler (GtkWidget *widget,
GtkSelectionData *selection_data,
gpointer data);
static void gtk_editable_selection_received (GtkWidget *widget,
GtkSelectionData *selection_data);
static void gtk_editable_set_selection (GtkEditable *editable,
gint start,
gint end);
static GtkWidgetClass *parent_class = NULL;
static gint editable_signals[LAST_SIGNAL] = { 0 };
static GdkAtom ctext_atom = GDK_NONE;
static GdkAtom text_atom = GDK_NONE;
static GdkAtom clipboard_atom = GDK_NONE;
guint
gtk_editable_get_type ()
{
static guint editable_type = 0;
if (!editable_type)
{
GtkTypeInfo editable_info =
{
"GtkEditable",
sizeof (GtkEditable),
sizeof (GtkEditableClass),
(GtkClassInitFunc) gtk_editable_class_init,
(GtkObjectInitFunc) gtk_editable_init,
(GtkArgSetFunc) NULL,
(GtkArgGetFunc) NULL,
};
editable_type = gtk_type_unique (gtk_widget_get_type (), &editable_info);
}
return editable_type;
}
static void
gtk_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_widget_get_type ());
editable_signals[INSERT_TEXT] =
gtk_signal_new ("insert_text",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkEditableClass, insert_text),
gtk_editable_marshal_signal_1,
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_editable_marshal_signal_2,
GTK_TYPE_NONE, 2,
GTK_TYPE_INT, GTK_TYPE_INT);
editable_signals[UPDATE_TEXT] =
gtk_signal_new ("update_text",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkEditableClass, update_text),
gtk_editable_marshal_signal_2,
GTK_TYPE_NONE, 2,
GTK_TYPE_INT, GTK_TYPE_INT);
editable_signals[GET_CHARS] =
gtk_signal_new ("get_chars",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkEditableClass, get_chars),
gtk_editable_marshal_signal_3,
GTK_TYPE_POINTER, 2,
GTK_TYPE_INT, GTK_TYPE_INT);
editable_signals[SET_SELECTION] =
gtk_signal_new ("set_selection",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkEditableClass, set_selection),
gtk_editable_marshal_signal_2,
GTK_TYPE_NONE, 2,
GTK_TYPE_INT, GTK_TYPE_INT);
editable_signals[CHANGED] =
gtk_signal_new ("changed",
GTK_RUN_LAST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkEditableClass, changed),
gtk_signal_default_marshaller,
GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, editable_signals, LAST_SIGNAL);
object_class->finalize = gtk_editable_finalize;
widget_class->selection_clear_event = gtk_editable_selection_clear;
widget_class->selection_received = gtk_editable_selection_received;
class->insert_text = NULL;
class->delete_text = NULL;
class->update_text = NULL;
class->get_chars = NULL;
class->set_selection = NULL;
class->changed = NULL;
}
static void
gtk_editable_init (GtkEditable *editable)
{
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->clipboard_text = NULL;
#ifdef USE_XIM
editable->ic = NULL;
#endif
if (!clipboard_atom)
clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
gtk_selection_add_handler (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY,
GDK_TARGET_STRING, gtk_editable_selection_handler,
NULL);
gtk_selection_add_handler (GTK_WIDGET(editable), clipboard_atom,
GDK_TARGET_STRING, gtk_editable_selection_handler,
NULL);
if (!text_atom)
text_atom = gdk_atom_intern ("TEXT", FALSE);
gtk_selection_add_handler (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY,
text_atom,
gtk_editable_selection_handler,
NULL);
gtk_selection_add_handler (GTK_WIDGET(editable), clipboard_atom,
text_atom,
gtk_editable_selection_handler,
NULL);
if (!ctext_atom)
ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
gtk_selection_add_handler (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY,
ctext_atom,
gtk_editable_selection_handler,
NULL);
gtk_selection_add_handler (GTK_WIDGET(editable), clipboard_atom,
ctext_atom,
gtk_editable_selection_handler,
NULL);
}
static void
gtk_editable_marshal_signal_1 (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args)
{
GtkEditableSignal1 rfunc;
rfunc = (GtkEditableSignal1) func;
(* rfunc) (object, GTK_VALUE_STRING (args[0]), GTK_VALUE_INT (args[1]),
GTK_VALUE_POINTER (args[2]), func_data);
}
static void
gtk_editable_marshal_signal_2 (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args)
{
GtkEditableSignal2 rfunc;
rfunc = (GtkEditableSignal2) func;
(* rfunc) (object, GTK_VALUE_INT (args[0]), GTK_VALUE_INT (args[1]),
func_data);
}
static void
gtk_editable_marshal_signal_3 (GtkObject *object,
GtkSignalFunc func,
gpointer func_data,
GtkArg *args)
{
GtkEditableSignal3 rfunc;
gpointer *return_val;
rfunc = (GtkEditableSignal3) func;
return_val = GTK_RETLOC_POINTER (args[2]);
*return_val = (* rfunc) (object,
GTK_VALUE_INT (args[0]),
GTK_VALUE_INT (args[1]),
func_data);
}
static void
gtk_editable_finalize (GtkObject *object)
{
GtkEditable *editable;
g_return_if_fail (object != NULL);
g_return_if_fail (GTK_IS_EDITABLE (object));
editable = GTK_EDITABLE (object);
#ifdef USE_XIM
if (editable->ic)
{
gdk_ic_destroy (editable->ic);
editable->ic = NULL;
}
#endif
(* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
}
void
gtk_editable_insert_text (GtkEditable *editable,
const gchar *new_text,
guint new_text_length,
guint *position)
{
gchar buf[64];
gchar *text;
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
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);
}
void
gtk_editable_delete_text (GtkEditable *editable,
guint start_pos,
guint end_pos)
{
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[DELETE_TEXT],
start_pos, end_pos);
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
}
static void
gtk_editable_update_text (GtkEditable *editable,
gint start_pos,
gint end_pos)
{
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[UPDATE_TEXT],
start_pos, end_pos);
}
gchar *
gtk_editable_get_chars (GtkEditable *editable,
guint start,
guint end)
{
gchar *retval = NULL;
g_return_val_if_fail (editable != NULL, NULL);
g_return_val_if_fail (GTK_IS_EDITABLE (editable), NULL);
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[GET_CHARS],
start, end, &retval);
return retval;
}
static void
gtk_editable_set_selection (GtkEditable *editable,
gint start_pos,
gint end_pos)
{
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[SET_SELECTION],
start_pos, end_pos);
}
static gint
gtk_editable_selection_clear (GtkWidget *widget,
GdkEventSelection *event)
{
GtkEditable *editable;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_EDITABLE (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
/* Let the selection handling code know that the selection
* has been changed, since we've overriden the default handler */
gtk_selection_clear (widget, event);
editable = GTK_EDITABLE (widget);
if (event->selection == GDK_SELECTION_PRIMARY)
{
if (editable->has_selection)
{
editable->has_selection = FALSE;
gtk_editable_update_text (editable, editable->selection_start_pos,
editable->selection_end_pos);
}
}
else if (event->selection == clipboard_atom)
{
g_free (editable->clipboard_text);
editable->clipboard_text = NULL;
}
return FALSE;
}
static void
gtk_editable_selection_handler (GtkWidget *widget,
GtkSelectionData *selection_data,
gpointer data)
{
GtkEditable *editable;
gint selection_start_pos;
gint selection_end_pos;
gchar *str;
gint length;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_EDITABLE (widget));
editable = GTK_EDITABLE (widget);
if (selection_data->selection == GDK_SELECTION_PRIMARY)
{
selection_start_pos = MIN (editable->selection_start_pos, editable->selection_end_pos);
selection_end_pos = MAX (editable->selection_start_pos, editable->selection_end_pos);
str = gtk_editable_get_chars(editable, selection_start_pos,
selection_end_pos);
length = selection_end_pos - selection_start_pos;
}
else /* CLIPBOARD */
{
if (!editable->clipboard_text)
return; /* Refuse */
str = editable->clipboard_text;
length = strlen (editable->clipboard_text);
}
if (selection_data->target == GDK_SELECTION_TYPE_STRING)
{
gtk_selection_data_set (selection_data,
GDK_SELECTION_TYPE_STRING,
8*sizeof(gchar), str, length);
}
else if (selection_data->target == text_atom ||
selection_data->target == ctext_atom)
{
guchar *text;
gchar c;
GdkAtom encoding;
gint format;
gint new_length;
c = str[length];
str[length] = '\0';
gdk_string_to_compound_text (str, &encoding, &format, &text, &new_length);
gtk_selection_data_set (selection_data, encoding, format, text, new_length);
gdk_free_compound_text (text);
str[length] = c;
}
if (str != editable->clipboard_text)
g_free (str);
}
static void
gtk_editable_selection_received (GtkWidget *widget,
GtkSelectionData *selection_data)
{
GtkEditable *editable;
gint reselect;
gint old_pos;
gint tmp_pos;
enum {INVALID, STRING, CTEXT} type;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_EDITABLE (widget));
editable = GTK_EDITABLE (widget);
if (selection_data->type == GDK_TARGET_STRING)
type = STRING;
else if (selection_data->type == ctext_atom)
type = CTEXT;
else
type = INVALID;
if (type == INVALID || selection_data->length < 0)
{
/* avoid infinite loop */
if (selection_data->target != GDK_TARGET_STRING)
gtk_selection_convert (widget, selection_data->selection,
GDK_TARGET_STRING, GDK_CURRENT_TIME);
return;
}
reselect = FALSE;
if ((editable->selection_start_pos != editable->selection_end_pos) &&
(!editable->has_selection ||
(selection_data->selection == clipboard_atom)))
{
reselect = TRUE;
/* Don't want to call gtk_editable_delete_selection here if we are going
* to reclaim the selection to avoid extra server traffic */
if (editable->has_selection)
{
gtk_editable_delete_text (editable,
MIN (editable->selection_start_pos, editable->selection_end_pos),
MAX (editable->selection_start_pos, editable->selection_end_pos));
}
else
gtk_editable_delete_selection (editable);
}
tmp_pos = old_pos = editable->current_pos;
switch (type)
{
case STRING:
selection_data->data[selection_data->length] = 0;
gtk_editable_insert_text (editable, selection_data->data,
strlen (selection_data->data), &tmp_pos);
editable->current_pos = tmp_pos;
break;
case CTEXT:
{
gchar **list;
gint count;
gint i;
count = gdk_text_property_to_text_list (selection_data->type,
selection_data->format,
selection_data->data,
selection_data->length,
&list);
for (i=0; i<count; i++)
{
gtk_editable_insert_text (editable, list[i], strlen (list[i]), &tmp_pos);
editable->current_pos = tmp_pos;
}
if (count > 0)
gdk_free_text_list (list);
}
break;
case INVALID: /* quiet compiler */
break;
}
if (reselect)
gtk_editable_set_selection (editable, old_pos, editable->current_pos);
}
void
gtk_editable_delete_selection (GtkEditable *editable)
{
if (editable->selection_start_pos != editable->selection_end_pos)
gtk_editable_delete_text (editable,
MIN (editable->selection_start_pos, editable->selection_end_pos),
MAX (editable->selection_start_pos, editable->selection_end_pos));
editable->selection_start_pos = 0;
editable->selection_end_pos = 0;
if (editable->has_selection)
{
editable->has_selection = FALSE;
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == GTK_WIDGET (editable)->window)
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
}
}
void
gtk_editable_claim_selection (GtkEditable *editable,
gboolean claim,
guint32 time)
{
g_return_if_fail (GTK_WIDGET_REALIZED (editable));
if (claim)
{
if (gtk_selection_owner_set (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY, time))
editable->has_selection = TRUE;
}
else
{
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) ==
GTK_WIDGET(editable)->window)
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, time);
}
}
void
gtk_editable_select_region (GtkEditable *editable,
guint start,
guint end)
{
if (GTK_WIDGET_REALIZED (editable))
gtk_editable_claim_selection (editable, start != end, GDK_CURRENT_TIME);
gtk_editable_set_selection (editable, start, end);
}
void
gtk_editable_cut_clipboard (GtkEditable *editable, GdkEventKey *event)
{
gtk_editable_copy_clipboard (editable, event);
gtk_editable_delete_selection (editable);
}
void
gtk_editable_copy_clipboard (GtkEditable *editable, GdkEventKey *event)
{
gint selection_start_pos;
gint selection_end_pos;
selection_start_pos = MIN (editable->selection_start_pos, editable->selection_end_pos);
selection_end_pos = MAX (editable->selection_start_pos, editable->selection_end_pos);
if (selection_start_pos != selection_end_pos)
{
if (gtk_selection_owner_set (GTK_WIDGET (editable),
clipboard_atom,
event->time))
editable->clipboard_text = gtk_editable_get_chars (editable,
editable->selection_start_pos,
editable->selection_end_pos);
}
}
void
gtk_editable_paste_clipboard (GtkEditable *editable, GdkEventKey *event)
{
gtk_selection_convert (GTK_WIDGET(editable),
clipboard_atom, ctext_atom, event->time);
}
void
gtk_editable_changed (GtkEditable *editable)
{
gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
}

112
gtk/gtkeditable.h Normal file
View File

@ -0,0 +1,112 @@
/* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __GTK_EDITABLE_H__
#define __GTK_EDITABLE_H__
#include <gdk/gdk.h>
#include <gtk/gtkwidget.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GTK_EDITABLE(obj) GTK_CHECK_CAST (obj, gtk_editable_get_type (), GtkEditable)
#define GTK_EDITABLE_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_editable_get_type (), GtkEditableClass)
#define GTK_IS_EDITABLE(obj) GTK_CHECK_TYPE (obj, gtk_editable_get_type ())
typedef struct _GtkEditable GtkEditable;
typedef struct _GtkEditableClass GtkEditableClass;
typedef void (*GtkTextFunction) (GtkEditable *editable, GdkEventKey *event);
struct _GtkEditable
{
GtkWidget widget;
guint current_pos;
guint selection_start_pos;
guint selection_end_pos;
guint has_selection : 1;
guint editable : 1;
GdkIC ic;
gchar *clipboard_text;
};
struct _GtkEditableClass
{
GtkWidgetClass parent_class;
void (* insert_text) (GtkEditable *editable,
const gchar *text,
guint length,
guint *position);
void (* delete_text) (GtkEditable *editable,
guint start_pos,
guint end_pos);
void (* update_text) (GtkEditable *editable,
guint start_pos,
guint end_pos);
gchar* (* get_chars) (GtkEditable *editable,
guint start_pos,
guint end_pos);
void (* set_selection)(GtkEditable *editable,
guint start_pos,
guint end_pos);
void (* changed) (GtkEditable *editable);
};
guint gtk_editable_get_type (void);
void gtk_editable_select_region (GtkEditable *editable,
guint start,
guint end);
void gtk_editable_insert_text (GtkEditable *editable,
const gchar *new_text,
guint new_text_length,
guint *position);
void gtk_editable_delete_text (GtkEditable *editable,
guint start_pos,
guint end_pos);
gchar * gtk_editable_get_chars (GtkEditable *editable,
guint start,
guint end);
void gtk_editable_cut_clipboard (GtkEditable *editable,
GdkEventKey *event);
void gtk_editable_copy_clipboard (GtkEditable *editable,
GdkEventKey *event);
void gtk_editable_paste_clipboard (GtkEditable *editable,
GdkEventKey *event);
void gtk_editable_claim_selection (GtkEditable *editable,
gboolean claim,
guint32 time);
void gtk_editable_delete_selection (GtkEditable *editable);
void gtk_editable_changed (GtkEditable *editable);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_EDITABLE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -20,7 +20,7 @@
#include <gdk/gdk.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkeditable.h>
#ifdef __cplusplus
@ -38,7 +38,7 @@ typedef struct _GtkEntryClass GtkEntryClass;
struct _GtkEntry
{
GtkWidget widget;
GtkEditable editable;
GdkWindow *text_area;
GdkPixmap *backing_pixmap;
@ -48,32 +48,15 @@ struct _GtkEntry
guint16 text_size;
guint16 text_length;
guint16 text_max_length;
gint16 current_pos;
gint16 selection_start_pos;
gint16 selection_end_pos;
gint16 scroll_offset;
guint have_selection : 1;
guint visible : 1;
guint editable : 1;
guint32 timer;
GdkIC ic;
gchar *clipboard_text;
};
struct _GtkEntryClass
{
GtkWidgetClass parent_class;
GtkEditableClass parent_class;
void (* insert_text) (GtkEntry *entry,
const gchar *text,
gint length,
gint *position);
void (* delete_text) (GtkEntry *entry,
gint start_pos,
gint end_pos);
void (* changed) (GtkEntry *entry);
void (* set_text) (GtkEntry *entry);
void (* activate) (GtkEntry *entry);
};
@ -90,8 +73,8 @@ void gtk_entry_set_position (GtkEntry *entry,
gint position);
gchar* gtk_entry_get_text (GtkEntry *entry);
void gtk_entry_select_region (GtkEntry *entry,
gint start,
gint end);
guint start,
guint end);
void gtk_entry_set_visibility (GtkEntry *entry,
gboolean visible);
void gtk_entry_set_editable (GtkEntry *entry,

View File

@ -936,8 +936,8 @@ gtk_file_selection_rename_file (GtkWidget *widget, gpointer data)
gtk_widget_show (fs->fileop_entry);
gtk_entry_set_text (GTK_ENTRY (fs->fileop_entry), fs->fileop_file);
gtk_entry_select_region (GTK_ENTRY (fs->fileop_entry),
0, strlen (fs->fileop_file));
gtk_editable_select_region (GTK_EDITABLE (fs->fileop_entry),
0, strlen (fs->fileop_file));
/* buttons */
button = gtk_button_new_with_label ("Rename");

View File

@ -73,7 +73,7 @@ static void gtk_spin_button_value_changed (GtkWidget *widget,
static gint gtk_spin_button_key_press (GtkWidget *widget,
GdkEventKey *event);
static void gtk_spin_button_update (GtkSpinButton *spin_button);
static void gtk_spin_button_changed (GtkEntry *entry);
static void gtk_spin_button_changed (GtkEditable *editable);
static void gtk_spin_button_activate (GtkEntry *entry);
@ -109,11 +109,13 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkEditableClass *editable_class;
GtkEntryClass *entry_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
entry_class = (GtkEntryClass*) class;
editable_class = (GtkEditableClass*) class;
parent_class = gtk_type_class (gtk_entry_get_type ());
@ -135,7 +137,7 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
widget_class->leave_notify_event = gtk_spin_button_leave_notify;
widget_class->focus_out_event = gtk_spin_button_focus_out;
entry_class->changed = gtk_spin_button_changed;
editable_class->changed = gtk_spin_button_changed;
entry_class->activate = gtk_spin_button_activate;
}
@ -900,22 +902,22 @@ gtk_spin_button_update (GtkSpinButton *spin_button)
}
static void
gtk_spin_button_changed (GtkEntry *entry)
gtk_spin_button_changed (GtkEditable *editable)
{
g_return_if_fail (entry != NULL);
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_SPIN_BUTTON (editable));
GTK_ENTRY_CLASS (parent_class)->changed (entry);
if (GTK_WIDGET_VISIBLE (GTK_WIDGET (entry)))
GTK_EDITABLE_CLASS (parent_class)->changed (editable);
if (GTK_WIDGET_VISIBLE (GTK_WIDGET (editable)))
{
GtkSpinButton *spin;
gfloat val;
gchar *error = NULL;
spin = GTK_SPIN_BUTTON (entry);
spin = GTK_SPIN_BUTTON (editable);
spin->snapped = 0;
val = strtod (entry->text, &error);
val = strtod (GTK_ENTRY (editable)->text, &error);
if (val < spin->adjustment->lower)
val = spin->adjustment->lower;
else if (val > spin->adjustment->upper)
@ -928,9 +930,9 @@ static void
gtk_spin_button_activate (GtkEntry *entry)
{
g_return_if_fail (entry != NULL);
g_return_if_fail (GTK_IS_ENTRY (entry));
g_return_if_fail (GTK_IS_SPIN_BUTTON (entry));
if (entry->editable)
if (GTK_EDITABLE(entry)->editable)
gtk_spin_button_update (GTK_SPIN_BUTTON (entry));
}

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,7 @@
#include <gdk/gdk.h>
#include <gtk/gtkadjustment.h>
#include <gtk/gtkwidget.h>
#include <gtk/gtkeditable.h>
#ifdef __cplusplus
@ -38,8 +38,6 @@ typedef struct _GtkPropertyMark GtkPropertyMark;
typedef struct _GtkText GtkText;
typedef struct _GtkTextClass GtkTextClass;
typedef void (*GtkTextFunction) (GtkText *text);
struct _GtkPropertyMark
{
/* Position in list. */
@ -54,7 +52,7 @@ struct _GtkPropertyMark
struct _GtkText
{
GtkWidget widget;
GtkEditable editable;
GdkWindow *text_area;
@ -66,8 +64,6 @@ struct _GtkText
GdkPixmap* line_wrap_bitmap;
GdkPixmap* line_arrow_bitmap;
GdkIC ic;
/* GAPPED TEXT SEGMENT */
/* The text, a single segment of text a'la emacs, with a gap
@ -96,24 +92,17 @@ struct _GtkText
/* First visible horizontal pixel. */
guint first_onscreen_hor_pixel;
/* First visible vertical pixel. */
guint first_onscreen_ver_pixel;
guint first_onscreen_ver_pixel;
/* FLAGS */
/* True iff the cursor has been placed yet. */
guint has_cursor : 1;
/* True iff this buffer is editable. (Allowing a cursor to be placed). */
guint is_editable : 1;
/* True iff this buffer is wrapping lines, otherwise it is using a
* horizontal scrollbar. */
guint line_wrap : 1;
/* Frozen, don't do updates. @@@ fixme */
guint freeze : 1;
/* Whether a selection. */
guint has_selection : 1;
/* Whether the selection is in the clipboard. */
guint own_selection : 1;
/* Whether it has been realized yet. */
/* TEXT PROPERTIES */
@ -155,20 +144,11 @@ struct _GtkText
GList *tab_stops;
gint default_tab_width;
/* Key bindings */
GtkTextFunction control_keys[26];
GtkTextFunction alt_keys[26];
/* Selection nonsense. */
guint selection_start;
guint selection_stop;
};
struct _GtkTextClass
{
GtkWidgetClass parent_class;
GtkEditableClass parent_class;
};
@ -197,9 +177,9 @@ gint gtk_text_backward_delete (GtkText *text,
gint gtk_text_forward_delete (GtkText *text,
guint nchars);
gchar * gtk_text_get_chars (GtkText *text,
guint index,
guint nchars);
void gtk_text_select_region (GtkText *entry,
guint start,
guint end);
#define GTK_TEXT_INDEX(t, index) \
((index) < (t)->gap_position ? (t)->text[index] : \