Commit fb881018 authored by Matthias Clasen's avatar Matthias Clasen Committed by Matthias Clasen

Support text/plain selection target (#55117, Owen Taylor)

Sat Jul 17 00:48:27 2004  Matthias Clasen  <maclas@gmx.de>

	Support text/plain selection target  (#55117, Owen Taylor)

	* gtk/gtkselection.h:
	* gtk/gtkdnd.h:
	* gtk/gtkselection.c (gtk_target_list_add_text_targets):
	* gtk/gtkdnd.c (gtk_drag_dest_add_text_targets):
	* gtk/gtkdnd.c (gtk_drag_source_add_text_targets): New
	functions to facilitate handling of text targets.

	* gtk/gtkentry.c:
	* gtk/gtktextview.c: Use the new text target handling
	functions instead of hardwiring the list of supported
	text targets everywhere.

	* gtk/gtkselection.c (gtk_selection_data_get_text):
	(gtk_selection_data_set_text):
	Support the targets text/plain, text/plain?charset=utf-8
	and text/plain?charset=<LOCALE-CHARSET> as outlined in
	#55117:
	For text/plain send only ASCII, but accept 8-bit text
	and treat it as ISO-8859-1 as specified by the Xdnd spec.
	Always send CRLF terminators. Accept either and convert
	into the native terminator for the platform.
parent a5638e82
Sat Jul 17 00:48:27 2004 Matthias Clasen <maclas@gmx.de>
Support text/plain selection target (#55117, Owen Taylor)
* gtk/gtkselection.h:
* gtk/gtkdnd.h:
* gtk/gtkselection.c (gtk_target_list_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_dest_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_source_add_text_targets): New
functions to facilitate handling of text targets.
* gtk/gtkentry.c:
* gtk/gtktextview.c: Use the new text target handling
functions instead of hardwiring the list of supported
text targets everywhere.
* gtk/gtkselection.c (gtk_selection_data_get_text):
(gtk_selection_data_set_text):
Support the targets text/plain, text/plain?charset=utf-8
and text/plain?charset=<LOCALE-CHARSET> as outlined in
#55117:
For text/plain send only ASCII, but accept 8-bit text
and treat it as ISO-8859-1 as specified by the Xdnd spec.
Always send CRLF terminators. Accept either and convert
into the native terminator for the platform.
Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
Support themed window icons. (#92346, Calum Benson)
......
Sat Jul 17 00:48:27 2004 Matthias Clasen <maclas@gmx.de>
Support text/plain selection target (#55117, Owen Taylor)
* gtk/gtkselection.h:
* gtk/gtkdnd.h:
* gtk/gtkselection.c (gtk_target_list_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_dest_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_source_add_text_targets): New
functions to facilitate handling of text targets.
* gtk/gtkentry.c:
* gtk/gtktextview.c: Use the new text target handling
functions instead of hardwiring the list of supported
text targets everywhere.
* gtk/gtkselection.c (gtk_selection_data_get_text):
(gtk_selection_data_set_text):
Support the targets text/plain, text/plain?charset=utf-8
and text/plain?charset=<LOCALE-CHARSET> as outlined in
#55117:
For text/plain send only ASCII, but accept 8-bit text
and treat it as ISO-8859-1 as specified by the Xdnd spec.
Always send CRLF terminators. Accept either and convert
into the native terminator for the platform.
Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
Support themed window icons. (#92346, Calum Benson)
......
Sat Jul 17 00:48:27 2004 Matthias Clasen <maclas@gmx.de>
Support text/plain selection target (#55117, Owen Taylor)
* gtk/gtkselection.h:
* gtk/gtkdnd.h:
* gtk/gtkselection.c (gtk_target_list_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_dest_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_source_add_text_targets): New
functions to facilitate handling of text targets.
* gtk/gtkentry.c:
* gtk/gtktextview.c: Use the new text target handling
functions instead of hardwiring the list of supported
text targets everywhere.
* gtk/gtkselection.c (gtk_selection_data_get_text):
(gtk_selection_data_set_text):
Support the targets text/plain, text/plain?charset=utf-8
and text/plain?charset=<LOCALE-CHARSET> as outlined in
#55117:
For text/plain send only ASCII, but accept 8-bit text
and treat it as ISO-8859-1 as specified by the Xdnd spec.
Always send CRLF terminators. Accept either and convert
into the native terminator for the platform.
Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
Support themed window icons. (#92346, Calum Benson)
......
Sat Jul 17 00:48:27 2004 Matthias Clasen <maclas@gmx.de>
Support text/plain selection target (#55117, Owen Taylor)
* gtk/gtkselection.h:
* gtk/gtkdnd.h:
* gtk/gtkselection.c (gtk_target_list_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_dest_add_text_targets):
* gtk/gtkdnd.c (gtk_drag_source_add_text_targets): New
functions to facilitate handling of text targets.
* gtk/gtkentry.c:
* gtk/gtktextview.c: Use the new text target handling
functions instead of hardwiring the list of supported
text targets everywhere.
* gtk/gtkselection.c (gtk_selection_data_get_text):
(gtk_selection_data_set_text):
Support the targets text/plain, text/plain?charset=utf-8
and text/plain?charset=<LOCALE-CHARSET> as outlined in
#55117:
For text/plain send only ASCII, but accept 8-bit text
and treat it as ISO-8859-1 as specified by the Xdnd spec.
Always send CRLF terminators. Accept either and convert
into the native terminator for the platform.
Fri Jul 16 23:20:34 2004 Matthias Clasen <maclas@gmx.de>
Support themed window icons. (#92346, Calum Benson)
......
Sat Jul 17 00:55:54 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtk-sections.txt: Add new text target list handling
functions.
Fri Jul 16 23:54:18 2004 Matthias Clasen <maclas@gmx.de>
* gtk/gtk-sections.txt: Add new GtkWindow and GtkIconTheme
......
......@@ -4890,6 +4890,7 @@ gtk_target_list_ref
gtk_target_list_unref
gtk_target_list_add
gtk_target_list_add_table
gtk_target_list_add_text_targets
gtk_target_list_remove
gtk_target_list_find
gtk_selection_owner_set
......@@ -4958,6 +4959,7 @@ gtk_drag_dest_unset
gtk_drag_dest_find_target
gtk_drag_dest_get_target_list
gtk_drag_dest_set_target_list
gtk_drag_dest_add_text_targets
gtk_drag_finish
gtk_drag_get_data
gtk_drag_get_source_widget
......@@ -4979,6 +4981,7 @@ gtk_drag_source_set_icon_stock
gtk_drag_source_unset
gtk_drag_source_set_target_list
gtk_drag_source_get_target_list
gtk_drag_source_add_text_targets
</SECTION>
......
......@@ -1024,6 +1024,24 @@ gtk_drag_dest_set_target_list (GtkWidget *widget,
site->target_list = target_list;
}
/**
* gtk_drag_dest_add_text_targets:
* @widget: a #GtkWidget that's a drag destination
*
* Add the text targets supported by #GtkSelection to
* the target list of the drag destination.
*
* Since: 2.6
**/
void
gtk_drag_dest_add_text_targets (GtkWidget *widget)
{
GtkTargetList *target_list;
target_list = gtk_drag_dest_get_target_list (widget);
gtk_target_list_add_text_targets (target_list);
gtk_drag_dest_set_target_list (widget, target_list);
}
/*************************************************************
* _gtk_drag_dest_handle_event:
......@@ -2172,6 +2190,25 @@ gtk_drag_source_set_target_list (GtkWidget *widget,
site->target_list = target_list;
}
/**
* gtk_drag_source_add_text_targets:
* @widget: a #GtkWidget that's is a drag source
*
* Add the text targets supported by #GtkSelection to
* the target list of the drag source.
*
* Since: 2.6
**/
void
gtk_drag_source_add_text_targets (GtkWidget *widget)
{
GtkTargetList *target_list;
target_list = gtk_drag_source_get_target_list (widget);
gtk_target_list_add_text_targets (target_list);
gtk_drag_source_set_target_list (widget, target_list);
}
static void
gtk_drag_source_unset_icon (GtkDragSourceSite *site)
{
......
......@@ -85,6 +85,7 @@ GdkAtom gtk_drag_dest_find_target (GtkWidget *widget,
GtkTargetList* gtk_drag_dest_get_target_list (GtkWidget *widget);
void gtk_drag_dest_set_target_list (GtkWidget *widget,
GtkTargetList *target_list);
void gtk_drag_dest_add_text_targets (GtkWidget *widget);
/* Source side */
......@@ -99,6 +100,7 @@ void gtk_drag_source_unset (GtkWidget *widget);
GtkTargetList* gtk_drag_source_get_target_list (GtkWidget *widget);
void gtk_drag_source_set_target_list (GtkWidget *widget,
GtkTargetList *target_list);
void gtk_drag_source_add_text_targets (GtkWidget *widget);
void gtk_drag_source_set_icon (GtkWidget *widget,
GdkColormap *colormap,
......
......@@ -112,13 +112,6 @@ typedef enum {
CURSOR_DND
} CursorType;
static const GtkTargetEntry target_table[] = {
{ "UTF8_STRING", 0, 0 },
{ "COMPOUND_TEXT", 0, 0 },
{ "TEXT", 0, 0 },
{ "STRING", 0, 0 }
};
/* GObject, GtkObject methods
*/
static void gtk_entry_class_init (GtkEntryClass *klass);
......@@ -959,8 +952,9 @@ gtk_entry_init (GtkEntry *entry)
gtk_drag_dest_set (GTK_WIDGET (entry),
GTK_DEST_DEFAULT_HIGHLIGHT,
target_table, G_N_ELEMENTS (target_table),
NULL, 0,
GDK_ACTION_COPY | GDK_ACTION_MOVE);
gtk_drag_dest_add_text_targets (GTK_WIDGET (entry));
/* This object is completely private. No external entity can gain a reference
* to it; so we create it here and destroy it in finalize().
......@@ -1573,7 +1567,8 @@ gtk_entry_motion_notify (GtkWidget *widget,
event->x + entry->scroll_offset, event->y))
{
GdkDragContext *context;
GtkTargetList *target_list = gtk_target_list_new (target_table, G_N_ELEMENTS (target_table));
GtkTargetList *target_list = gtk_target_list_new (NULL, 0);
gtk_target_list_add_text_targets (target_list);
guint actions = entry->editable ? GDK_ACTION_COPY | GDK_ACTION_MOVE : GDK_ACTION_COPY;
context = gtk_drag_begin (widget, target_list, actions,
......@@ -3557,16 +3552,27 @@ primary_clear_cb (GtkClipboard *clipboard,
static void
gtk_entry_update_primary_selection (GtkEntry *entry)
{
static const GtkTargetEntry targets[] = {
static GtkTargetEntry targets[] = {
{ "UTF8_STRING", 0, 0 },
{ "STRING", 0, 0 },
{ "TEXT", 0, 0 },
{ "COMPOUND_TEXT", 0, 0 }
{ "COMPOUND_TEXT", 0, 0 },
{ "text/plain;charset=utf-8", 0, 0 },
{ NULL, 0, 0 },
{ "text/plain", 0, 0 }
};
GtkClipboard *clipboard;
gint start, end;
if (targets[5].target == NULL)
{
const gchar *charset;
g_get_charset (&charset);
targets[5].target = g_strdup_printf ("text/plain;charset=%s", charset);
}
if (!GTK_WIDGET_REALIZED (entry))
return;
......
......@@ -222,9 +222,9 @@ gtk_target_list_unref (GtkTargetList *list)
void
gtk_target_list_add (GtkTargetList *list,
GdkAtom target,
guint flags,
guint info)
GdkAtom target,
guint flags,
guint info)
{
GtkTargetPair *pair;
......@@ -238,6 +238,61 @@ gtk_target_list_add (GtkTargetList *list,
list->list = g_list_append (list->list, pair);
}
static GdkAtom utf8_atom;
static GdkAtom text_atom;
static GdkAtom ctext_atom;
static GdkAtom text_plain_atom;
static GdkAtom text_plain_utf8_atom;
static GdkAtom text_plain_locale_atom;
static void
init_atoms (void)
{
gchar *tmp;
const gchar *charset;
if (!utf8_atom)
{
utf8_atom = gdk_atom_intern ("UTF8_STRING", FALSE);
text_atom = gdk_atom_intern ("TEXT", FALSE);
ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
text_plain_atom = gdk_atom_intern ("text/plain", FALSE);
text_plain_utf8_atom = gdk_atom_intern ("text/plain;charset=utf-8", FALSE);
g_get_charset (&charset);
tmp = g_strdup_printf ("text/plain;charset=%s", charset);
text_plain_locale_atom = gdk_atom_intern (tmp, FALSE);
g_free (tmp);
}
}
/**
* gtk_target_list_add_text_targets:
* @list: a #GtkTargetList
*
* Adds the text targets supported by #GtkSelection to
* the target list. The targets are added with both flags
* and info being zero.
*
* Since: 2.6
**/
void
gtk_target_list_add_text_targets (GtkTargetList *list)
{
g_return_if_fail (list != NULL);
init_atoms ();
/* Keep in sync with gtk_selection_data_targets_include_text()
*/
gtk_target_list_add (list, utf8_atom, 0, 0);
gtk_target_list_add (list, ctext_atom, 0, 0);
gtk_target_list_add (list, text_atom, 0, 0);
gtk_target_list_add (list, GDK_TARGET_STRING, 0, 0);
gtk_target_list_add (list, text_plain_utf8_atom, 0, 0);
gtk_target_list_add (list, text_plain_locale_atom, 0, 0);
gtk_target_list_add (list, text_plain_atom, 0, 0);
}
void
gtk_target_list_add_table (GtkTargetList *list,
const GtkTargetEntry *targets,
......@@ -803,21 +858,6 @@ gtk_selection_data_set (GtkSelectionData *selection_data,
selection_data->length = length;
}
static GdkAtom utf8_atom;
static GdkAtom text_atom;
static GdkAtom ctext_atom;
static void
init_atoms (void)
{
if (!utf8_atom)
{
utf8_atom = gdk_atom_intern ("UTF8_STRING", FALSE);
text_atom = gdk_atom_intern ("TEXT", FALSE);
ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
}
}
static gboolean
selection_set_string (GtkSelectionData *selection_data,
const gchar *str,
......@@ -867,6 +907,149 @@ selection_set_compound_text (GtkSelectionData *selection_data,
return result;
}
/* Normalize \r and \n into \r\n
*/
static gchar *
normalize_to_crlf (const gchar *str,
gint len)
{
GString *result = g_string_sized_new (len);
const gchar *p = str;
while (1)
{
if (*p == '\n')
g_string_append_c (result, '\r');
if (*p == '\r')
{
g_string_append_c (result, *p);
p++;
if (*p != '\n')
g_string_append_c (result, '\n');
}
if (*p == '\0')
break;
g_string_append_c (result, *p);
p++;
}
return g_string_free (result, FALSE);
}
/* Normalize \r and \r\n into \n
*/
static gchar *
normalize_to_lf (gchar *str,
gint len)
{
GString *result = g_string_sized_new (len);
const gchar *p = str;
while (1)
{
if (*p == '\r')
{
p++;
if (*p != '\n')
g_string_append_c (result, '\n');
}
if (*p == '\0')
break;
g_string_append_c (result, *p);
p++;
}
return g_string_free (result, FALSE);
}
static gboolean
selection_set_text_plain (GtkSelectionData *selection_data,
const gchar *str,
gint len)
{
const gchar *charset = NULL;
gchar *result;
GError *error = NULL;
result = normalize_to_crlf (str, len);
if (selection_data->target == text_plain_atom)
charset = "ASCII";
else if (selection_data->target == text_plain_locale_atom)
g_get_charset (&charset);
if (charset)
{
gchar *tmp = result;
result = g_convert_with_fallback (tmp, -1,
charset, "UTF-8",
NULL, NULL, NULL, &error);
g_free (tmp);
}
if (!result)
{
g_warning ("Error converting from UTF-8 to %s: %s",
charset, error->message);
g_error_free (error);
return FALSE;
}
gtk_selection_data_set (selection_data,
selection_data->target,
8, result, strlen (result));
g_free (result);
return TRUE;
}
static gchar *
selection_get_text_plain (GtkSelectionData *selection_data)
{
const gchar *charset = NULL;
gchar *str, *result;
gint len;
GError *error = NULL;
str = g_strdup (selection_data->data);
len = selection_data->length;
if (selection_data->type == text_plain_atom)
charset = "ISO-8859-1";
else if (selection_data->type == text_plain_locale_atom)
g_get_charset (&charset);
if (charset)
{
gchar *tmp = str;
str = g_convert_with_fallback (tmp, len,
charset, "UTF-8",
NULL, NULL, &len, &error);
g_free (tmp);
}
if (!str)
{
g_warning ("Error converting from %s to UTF-8: %s",
charset, error->message);
g_error_free (error);
return NULL;
}
result = normalize_to_lf (str, len);
g_free (str);
return result;
}
/**
* gtk_selection_data_set_text:
* @selection_data: a #GtkSelectionData
......@@ -909,6 +1092,12 @@ gtk_selection_data_set_text (GtkSelectionData *selection_data,
else if (selection_data->target == text_atom)
return selection_set_string (selection_data, str, len);
}
else if (selection_data->target == text_plain_atom ||
selection_data->target == text_plain_utf8_atom ||
selection_data->target == text_plain_locale_atom)
{
return selection_set_text_plain (selection_data, str, len);
}
return FALSE;
}
......@@ -951,6 +1140,13 @@ gtk_selection_data_get_text (GtkSelectionData *selection_data)
g_free (list[i]);
g_free (list);
}
else if (selection_data->length >= 0 &&
(selection_data->type == text_plain_atom ||
selection_data->type == text_plain_utf8_atom ||
selection_data->type == text_plain_locale_atom))
{
result = selection_get_text_plain (selection_data);
}
return result;
}
......@@ -1016,14 +1212,19 @@ gtk_selection_data_targets_include_text (GtkSelectionData *selection_data)
gint i;
gboolean result = FALSE;
init_atoms ();
if (gtk_selection_data_get_targets (selection_data, &targets, &n_targets))
{
for (i=0; i < n_targets; i++)
{
if (targets[i] == gdk_atom_intern ("STRING", FALSE) ||
targets[i] == gdk_atom_intern ("TEXT", FALSE) ||
targets[i] == gdk_atom_intern ("COMPOUND_TEXT", FALSE) ||
targets[i] == gdk_atom_intern ("UTF8_STRING", FALSE))
if (targets[i] == utf8_atom ||
targets[i] == text_atom ||
targets[i] == GDK_TARGET_STRING ||
targets[i] == ctext_atom ||
targets[i] == text_plain_atom ||
targets[i] == text_plain_utf8_atom ||
targets[i] == text_plain_locale_atom)
result = TRUE;
}
......
......@@ -95,6 +95,7 @@ void gtk_target_list_add (GtkTargetList *list,
GdkAtom target,
guint flags,
guint info);
void gtk_target_list_add_text_targets (GtkTargetList *list);
void gtk_target_list_add_table (GtkTargetList *list,
const GtkTargetEntry *targets,
guint ntargets);
......
......@@ -410,22 +410,8 @@ static gint text_window_get_width (GtkTextWindow *win);
static gint text_window_get_height (GtkTextWindow *win);
enum
{
TARGET_STRING,
TARGET_TEXT,
TARGET_COMPOUND_TEXT,
TARGET_UTF8_STRING,
TARGET_TEXT_BUFFER_CONTENTS
};
static const GtkTargetEntry target_table[] = {
{ "GTK_TEXT_BUFFER_CONTENTS", GTK_TARGET_SAME_APP,
TARGET_TEXT_BUFFER_CONTENTS },
{ "UTF8_STRING", 0, TARGET_UTF8_STRING },
{ "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT },
{ "TEXT", 0, TARGET_TEXT },
{ "STRING", 0, TARGET_STRING }
static GtkTargetEntry target_table[] = {
{ "GTK_TEXT_BUFFER_CONTENTS", GTK_TARGET_SAME_APP, 0 },
};
static GtkContainerClass *parent_class = NULL;
......@@ -1066,6 +1052,7 @@ gtk_text_view_init (GtkTextView *text_view)
0,
target_table, G_N_ELEMENTS (target_table),
GDK_ACTION_COPY | GDK_ACTION_MOVE);
gtk_drag_dest_add_text_targets (widget);
text_view->virtual_cursor_x = -1;
text_view->virtual_cursor_y = -1;
......@@ -5872,6 +5859,7 @@ gtk_text_view_start_selection_dnd (GtkTextView *text_view,
target_list = gtk_target_list_new (target_table,
G_N_ELEMENTS (target_table));
gtk_target_list_add_text_targets (target_list);
context = gtk_drag_begin (GTK_WIDGET (text_view), target_list,
GDK_ACTION_COPY | GDK_ACTION_MOVE,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment