diff options
author | Havoc Pennington <hp@src.gnome.org> | 2000-07-03 17:01:33 +0000 |
---|---|---|
committer | Havoc Pennington <hp@src.gnome.org> | 2000-07-03 17:01:33 +0000 |
commit | d22a509cf73f1d68c72e862d5d3b3a743b8acb15 (patch) | |
tree | 482b8814c64608c288228fb0bf8820f1ce7494ab | |
parent | dfc74e1264132b6f96cd36998a1c99966a81cb27 (diff) | |
download | gdk-pixbuf-d22a509cf73f1d68c72e862d5d3b3a743b8acb15.tar.gz |
Add g_convert() and use it to properly handle compound text selections;
add gtk_text_view_get_iter_location()
-rw-r--r-- | gtk/gtktextbuffer.c | 22 | ||||
-rw-r--r-- | gtk/gtktexttypes.c | 89 | ||||
-rw-r--r-- | gtk/gtktexttypes.h | 6 | ||||
-rw-r--r-- | gtk/gtktextview.c | 68 | ||||
-rw-r--r-- | gtk/gtktextview.h | 3 |
5 files changed, 156 insertions, 32 deletions
diff --git a/gtk/gtktextbuffer.c b/gtk/gtktextbuffer.c index 0726863b5..9b5ad3a95 100644 --- a/gtk/gtktextbuffer.c +++ b/gtk/gtktextbuffer.c @@ -1364,11 +1364,20 @@ selection_received (GtkWidget *widget, &list); for (i=0; i<count; i++) { - /* FIXME this is broken, it assumes the CTEXT is latin1 - when it probably isn't. */ - gchar *utf; - - utf = gtk_text_latin1_to_utf(list[i], strlen(list[i])); + /* list contains stuff in our default encoding */ + gboolean free_utf = FALSE; + gchar *utf = NULL; + gchar *charset = NULL; + + if (g_get_charset (&charset)) + { + utf = g_convert (list[i], -1, + "UTF8", charset, + NULL); + free_utf = TRUE; + } + else + utf = list[i]; if (buffer->paste_interactive) gtk_text_buffer_insert_interactive (buffer, &insert_point, @@ -1377,7 +1386,8 @@ selection_received (GtkWidget *widget, gtk_text_buffer_insert (buffer, &insert_point, utf, -1); - g_free(utf); + if (free_utf) + g_free(utf); } if (count > 0) diff --git a/gtk/gtktexttypes.c b/gtk/gtktexttypes.c index c9ba97df6..0a05e0dac 100644 --- a/gtk/gtktexttypes.c +++ b/gtk/gtktexttypes.c @@ -140,3 +140,92 @@ gtk_text_latin1_to_utf (const gchar *latin1, gint len) +#include <iconv.h> +#include <errno.h> +#include <string.h> + +gchar* +g_convert (const gchar *str, + gint len, + const gchar *to_codeset, + const gchar *from_codeset, + gint *bytes_converted) +{ + gchar *dest; + gchar *outp; + const gchar *p; + size_t inbytes_remaining; + size_t outbytes_remaining; + size_t err; + iconv_t cd; + size_t outbuf_size; + + g_return_val_if_fail (str != NULL, NULL); + g_return_val_if_fail (to_codeset != NULL, NULL); + g_return_val_if_fail (from_codeset != NULL, NULL); + + cd = iconv_open (to_codeset, from_codeset); + + if (cd == (iconv_t) -1) + { + /* Something went wrong. */ + if (errno == EINVAL) + g_warning ("Conversion from character set `%s' to `%s' is not supported", + from_codeset, to_codeset); + else + g_warning ("Failed to convert character set `%s' to `%s': %s", + from_codeset, to_codeset, strerror (errno)); + + if (bytes_converted) + *bytes_converted = 0; + + return NULL; + } + + if (len < 0) + len = strlen (str); + + p = str; + inbytes_remaining = len; + outbuf_size = len + 1; /* + 1 for nul in case len == 1 */ + outbytes_remaining = outbuf_size - 1; /* -1 for nul */ + outp = dest = g_malloc (outbuf_size); + + again: + + err = iconv (cd, &p, &inbytes_remaining, &outp, &outbytes_remaining); + + if (err == (size_t) -1) + { + if (errno == E2BIG) + { + size_t used = outp - dest; + outbuf_size *= 2; + dest = g_realloc (dest, outbuf_size); + + outp = dest + used; + outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */ + + goto again; + } + else + g_warning ("iconv() failed: %s", strerror (errno)); + } + + *outp = '\0'; + + if (iconv_close (cd) != 0) + g_warning ("Failed to close iconv() conversion descriptor: %s", + strerror (errno)); + + if (bytes_converted) + *bytes_converted = p - str; + + if (p == str) + { + g_free (dest); + return NULL; + } + else + return dest; +} diff --git a/gtk/gtktexttypes.h b/gtk/gtktexttypes.h index 65c3cf065..007ea25b1 100644 --- a/gtk/gtktexttypes.h +++ b/gtk/gtktexttypes.h @@ -126,6 +126,12 @@ gchar* gtk_text_latin1_to_utf (const gchar *latin1, gint len); +gchar* g_convert (const gchar *str, + gint len, + const gchar *to_codeset, + const gchar *from_codeset, + gint *bytes_converted); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c index 300567370..802b9ffc8 100644 --- a/gtk/gtktextview.c +++ b/gtk/gtktextview.c @@ -706,6 +706,16 @@ gtk_text_view_get_iter_at_pixel (GtkTextView *text_view, y + text_view->yoffset); } +void +gtk_text_view_get_iter_location (GtkTextView *text_view, + const GtkTextIter *iter, + GdkRectangle *location) +{ + g_return_if_fail (GTK_IS_TEXT_VIEW (text_view)); + g_return_if_fail (gtk_text_iter_get_buffer (iter) == text_view->buffer); + + gtk_text_layout_get_iter_location (text_view->layout, iter, location); +} static void set_adjustment_clamped (GtkAdjustment *adj, gfloat val) @@ -1475,9 +1485,6 @@ gtk_text_view_event (GtkWidget *widget, GdkEvent *event) if (text_view->layout == NULL || text_view->buffer == NULL) return FALSE; - - /* FIXME eventually we really want to synthesize enter/leave - events here as the canvas does for canvas items */ if (get_event_coordinates (event, &x, &y)) { @@ -1494,28 +1501,28 @@ gtk_text_view_event (GtkWidget *widget, GdkEvent *event) &iter, x, y); - { - GSList *tags; - GSList *tmp; + { + GSList *tags; + GSList *tmp; - tags = gtk_text_buffer_get_tags (text_view->buffer, &iter); + tags = gtk_text_buffer_get_tags (text_view->buffer, &iter); - tmp = tags; - while (tmp != NULL) - { - GtkTextTag *tag = tmp->data; + tmp = tags; + while (tmp != NULL) + { + GtkTextTag *tag = tmp->data; - if (gtk_text_tag_event (tag, GTK_OBJECT (widget), event, &iter)) - { - retval = TRUE; - break; - } + if (gtk_text_tag_event (tag, GTK_OBJECT (widget), event, &iter)) + { + retval = TRUE; + break; + } - tmp = g_slist_next (tmp); - } + tmp = g_slist_next (tmp); + } - g_slist_free (tags); - } + g_slist_free (tags); + } return retval; } @@ -2810,17 +2817,26 @@ gtk_text_view_drag_data_received (GtkWidget *widget, &list); for (i=0; i<count; i++) { - /* FIXME this is broken, it assumes the CTEXT is latin1 - when it probably isn't. */ - gchar *utf; - - utf = gtk_text_latin1_to_utf (list[i], strlen (list[i])); + /* list contains stuff in our default encoding */ + gboolean free_utf = FALSE; + gchar *utf = NULL; + gchar *charset = NULL; + if (g_get_charset (&charset)) + { + utf = g_convert (list[i], -1, + "UTF8", charset, NULL); + free_utf = TRUE; + } + else + utf = list[i]; + gtk_text_buffer_insert_interactive (text_view->buffer, &drop_point, utf, -1, text_view->editable); - g_free (utf); + if (free_utf) + g_free(utf); } if (count > 0) diff --git a/gtk/gtktextview.h b/gtk/gtktextview.h index 7871f611c..296a1626b 100644 --- a/gtk/gtktextview.h +++ b/gtk/gtktextview.h @@ -156,6 +156,9 @@ void gtk_text_view_set_cursor_visible (GtkTextView *text_view, gboolean setting); gboolean gtk_text_view_get_cursor_visible (GtkTextView *text_view); +void gtk_text_view_get_iter_location (GtkTextView *text_view, + const GtkTextIter *iter, + GdkRectangle *location); #ifdef __cplusplus } |