summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHavoc Pennington <hp@src.gnome.org>2000-07-03 17:01:33 +0000
committerHavoc Pennington <hp@src.gnome.org>2000-07-03 17:01:33 +0000
commitd22a509cf73f1d68c72e862d5d3b3a743b8acb15 (patch)
tree482b8814c64608c288228fb0bf8820f1ce7494ab
parentdfc74e1264132b6f96cd36998a1c99966a81cb27 (diff)
downloadgdk-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.c22
-rw-r--r--gtk/gtktexttypes.c89
-rw-r--r--gtk/gtktexttypes.h6
-rw-r--r--gtk/gtktextview.c68
-rw-r--r--gtk/gtktextview.h3
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
}