forked from AuroraMiddleware/gtk
Instead of always mirroring the selection to a single PRIMARY selection,
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com> * gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard): Instead of always mirroring the selection to a single PRIMARY selection, allow it to be mirrored to any number of clipboards. * gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove, just use gtk_text_buffer_paste_clipboard with the appropriate clipboard. * gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a GtkClipboard argument, and for paste_clipboard, the @override_location argument from @paste_primary. * gtk/gtktextview.c: Adapt to above change.
This commit is contained in:
parent
d5f469987b
commit
b97a0a452f
15
ChangeLog
15
ChangeLog
@ -1,3 +1,18 @@
|
||||
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard):
|
||||
Instead of always mirroring the selection to a single PRIMARY
|
||||
selection, allow it to be mirrored to any number of clipboards.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove,
|
||||
just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
|
||||
GtkClipboard argument, and for paste_clipboard, the
|
||||
@override_location argument from @paste_primary.
|
||||
|
||||
* gtk/gtktextview.c: Adapt to above change.
|
||||
|
||||
2001-08-30 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* gtk/gtktextview.c (invalidated_handler): put validate idle at
|
||||
|
@ -1,3 +1,18 @@
|
||||
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard):
|
||||
Instead of always mirroring the selection to a single PRIMARY
|
||||
selection, allow it to be mirrored to any number of clipboards.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove,
|
||||
just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
|
||||
GtkClipboard argument, and for paste_clipboard, the
|
||||
@override_location argument from @paste_primary.
|
||||
|
||||
* gtk/gtktextview.c: Adapt to above change.
|
||||
|
||||
2001-08-30 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* gtk/gtktextview.c (invalidated_handler): put validate idle at
|
||||
|
@ -1,3 +1,18 @@
|
||||
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard):
|
||||
Instead of always mirroring the selection to a single PRIMARY
|
||||
selection, allow it to be mirrored to any number of clipboards.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove,
|
||||
just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
|
||||
GtkClipboard argument, and for paste_clipboard, the
|
||||
@override_location argument from @paste_primary.
|
||||
|
||||
* gtk/gtktextview.c: Adapt to above change.
|
||||
|
||||
2001-08-30 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* gtk/gtktextview.c (invalidated_handler): put validate idle at
|
||||
|
@ -1,3 +1,18 @@
|
||||
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard):
|
||||
Instead of always mirroring the selection to a single PRIMARY
|
||||
selection, allow it to be mirrored to any number of clipboards.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove,
|
||||
just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
|
||||
GtkClipboard argument, and for paste_clipboard, the
|
||||
@override_location argument from @paste_primary.
|
||||
|
||||
* gtk/gtktextview.c: Adapt to above change.
|
||||
|
||||
2001-08-30 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* gtk/gtktextview.c (invalidated_handler): put validate idle at
|
||||
|
@ -1,3 +1,18 @@
|
||||
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard):
|
||||
Instead of always mirroring the selection to a single PRIMARY
|
||||
selection, allow it to be mirrored to any number of clipboards.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove,
|
||||
just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
|
||||
GtkClipboard argument, and for paste_clipboard, the
|
||||
@override_location argument from @paste_primary.
|
||||
|
||||
* gtk/gtktextview.c: Adapt to above change.
|
||||
|
||||
2001-08-30 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* gtk/gtktextview.c (invalidated_handler): put validate idle at
|
||||
|
@ -1,3 +1,18 @@
|
||||
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard):
|
||||
Instead of always mirroring the selection to a single PRIMARY
|
||||
selection, allow it to be mirrored to any number of clipboards.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove,
|
||||
just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
|
||||
GtkClipboard argument, and for paste_clipboard, the
|
||||
@override_location argument from @paste_primary.
|
||||
|
||||
* gtk/gtktextview.c: Adapt to above change.
|
||||
|
||||
2001-08-30 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* gtk/gtktextview.c (invalidated_handler): put validate idle at
|
||||
|
@ -1,3 +1,18 @@
|
||||
Wed Aug 29 20:40:58 2001 Owen Taylor <otaylor@redhat.com>
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_add/remove_selection_clipboard):
|
||||
Instead of always mirroring the selection to a single PRIMARY
|
||||
selection, allow it to be mirrored to any number of clipboards.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_paste_primary): Remove,
|
||||
just use gtk_text_buffer_paste_clipboard with the appropriate clipboard.
|
||||
|
||||
* gtk/gtktextbuffer.[ch] (gtk_text_buffer_cut/copy/paste_clipboard): Add a
|
||||
GtkClipboard argument, and for paste_clipboard, the
|
||||
@override_location argument from @paste_primary.
|
||||
|
||||
* gtk/gtktextview.c: Adapt to above change.
|
||||
|
||||
2001-08-30 Havoc Pennington <hp@redhat.com>
|
||||
|
||||
* gtk/gtktextview.c (invalidated_handler): put validate idle at
|
||||
|
@ -81,7 +81,6 @@ static void gtk_text_buffer_class_init (GtkTextBufferClass *klass);
|
||||
static void gtk_text_buffer_finalize (GObject *object);
|
||||
|
||||
|
||||
static void gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer);
|
||||
static void gtk_text_buffer_real_insert_text (GtkTextBuffer *buffer,
|
||||
GtkTextIter *iter,
|
||||
const gchar *text,
|
||||
@ -108,6 +107,10 @@ static void gtk_text_buffer_real_changed (GtkTextBuffer *buffe
|
||||
static GtkTextBTree* get_btree (GtkTextBuffer *buffer);
|
||||
static void free_log_attr_cache (GtkTextLogAttrCache *cache);
|
||||
|
||||
static void remove_all_clipboard_contents_buffers (GtkTextBuffer *buffer);
|
||||
static void remove_all_selection_clipboards (GtkTextBuffer *buffer);
|
||||
static void update_selection_clipboards (GtkTextBuffer *buffer);
|
||||
|
||||
static GtkObjectClass *parent_class = NULL;
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
@ -299,7 +302,7 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
|
||||
void
|
||||
gtk_text_buffer_init (GtkTextBuffer *buffer)
|
||||
{
|
||||
buffer->clipboard_contents = NULL;
|
||||
buffer->clipboard_contents_buffers = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -334,12 +337,9 @@ gtk_text_buffer_finalize (GObject *object)
|
||||
|
||||
buffer = GTK_TEXT_BUFFER (object);
|
||||
|
||||
if (buffer->clipboard_contents)
|
||||
{
|
||||
g_object_unref (G_OBJECT (buffer->clipboard_contents));
|
||||
buffer->clipboard_contents = NULL;
|
||||
}
|
||||
|
||||
remove_all_clipboard_contents_buffers (buffer);
|
||||
remove_all_selection_clipboards (buffer);
|
||||
|
||||
if (buffer->tag_table)
|
||||
{
|
||||
g_object_unref (G_OBJECT (buffer->tag_table));
|
||||
@ -1116,7 +1116,7 @@ gtk_text_buffer_real_delete_range (GtkTextBuffer *buffer,
|
||||
_gtk_text_btree_delete (start, end);
|
||||
|
||||
/* may have deleted the selection... */
|
||||
gtk_text_buffer_update_primary_selection (buffer);
|
||||
update_selection_clipboards (buffer);
|
||||
|
||||
g_signal_emit (G_OBJECT (buffer), signals[CHANGED], 0);
|
||||
}
|
||||
@ -1586,7 +1586,7 @@ gtk_text_buffer_set_mark (GtkTextBuffer *buffer,
|
||||
if (_gtk_text_btree_mark_is_insert (get_btree (buffer), mark) ||
|
||||
_gtk_text_btree_mark_is_selection_bound (get_btree (buffer), mark))
|
||||
{
|
||||
gtk_text_buffer_update_primary_selection (buffer);
|
||||
update_selection_clipboards (buffer);
|
||||
}
|
||||
|
||||
_gtk_text_btree_get_iter_at_mark (get_btree (buffer),
|
||||
@ -2588,6 +2588,87 @@ clipboard_get_selection_cb (GtkClipboard *clipboard,
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkClipboard *clipboard;
|
||||
GtkTextBuffer *buffer;
|
||||
} ContentsBuffer;
|
||||
|
||||
static void
|
||||
remove_all_clipboard_contents_buffers (GtkTextBuffer *buffer)
|
||||
{
|
||||
GSList *tmp_list = buffer->clipboard_contents_buffers;
|
||||
while (tmp_list)
|
||||
{
|
||||
ContentsBuffer *contents_buffer = tmp_list->data;
|
||||
|
||||
g_object_unref (contents_buffer->buffer);
|
||||
g_free (contents_buffer);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
g_slist_free (buffer->clipboard_contents_buffers);
|
||||
buffer->clipboard_contents_buffers = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_clipboard_contents_buffer (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard)
|
||||
{
|
||||
GSList *tmp_list = buffer->clipboard_contents_buffers;
|
||||
while (tmp_list)
|
||||
{
|
||||
ContentsBuffer *contents_buffer = tmp_list->data;
|
||||
|
||||
if (contents_buffer->clipboard == clipboard)
|
||||
{
|
||||
buffer->clipboard_contents_buffers = g_slist_remove (buffer->clipboard_contents_buffers, contents_buffer);
|
||||
|
||||
g_object_unref (contents_buffer->buffer);
|
||||
g_free (contents_buffer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
|
||||
static GtkTextBuffer *
|
||||
get_clipboard_contents_buffer (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard,
|
||||
gboolean create)
|
||||
{
|
||||
ContentsBuffer *contents_buffer;
|
||||
GSList *tmp_list;
|
||||
|
||||
tmp_list = buffer->clipboard_contents_buffers;
|
||||
while (tmp_list)
|
||||
{
|
||||
contents_buffer = tmp_list->data;
|
||||
if (contents_buffer->clipboard == clipboard)
|
||||
return contents_buffer->buffer;
|
||||
}
|
||||
|
||||
if (create)
|
||||
{
|
||||
contents_buffer = g_new (ContentsBuffer, 1);
|
||||
contents_buffer->clipboard = clipboard;
|
||||
contents_buffer->buffer = gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
|
||||
|
||||
g_object_set_data (G_OBJECT (contents_buffer->buffer), "gtk-text-buffer-clipboard",
|
||||
GUINT_TO_POINTER (1));
|
||||
|
||||
buffer->clipboard_contents_buffers = g_slist_prepend (buffer->clipboard_contents_buffers, contents_buffer);
|
||||
|
||||
|
||||
return contents_buffer->buffer;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Provide cut/copied data */
|
||||
static void
|
||||
clipboard_get_contents_cb (GtkClipboard *clipboard,
|
||||
@ -2596,7 +2677,9 @@ clipboard_get_contents_cb (GtkClipboard *clipboard,
|
||||
gpointer data)
|
||||
{
|
||||
GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
|
||||
GtkTextBuffer *contents = buffer->clipboard_contents;
|
||||
GtkTextBuffer *contents = get_clipboard_contents_buffer (buffer, clipboard, FALSE);
|
||||
|
||||
g_assert (contents); /* This should never be called unless we own the clipboard */
|
||||
|
||||
if (selection_data->target ==
|
||||
gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE))
|
||||
@ -2612,25 +2695,16 @@ clipboard_get_contents_cb (GtkClipboard *clipboard,
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Just provide text from the clipboard buffer */
|
||||
if (buffer->clipboard_contents)
|
||||
{
|
||||
gchar *str;
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_bounds (contents, &start, &end);
|
||||
/* strip off the trailing newline, it isn't part of the text that was cut */
|
||||
gtk_text_iter_backward_char (&end);
|
||||
|
||||
str = gtk_text_iter_get_visible_text (&start, &end);
|
||||
gtk_selection_data_set_text (selection_data, str);
|
||||
g_free (str);
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_selection_data_set_text (selection_data, "");
|
||||
return;
|
||||
}
|
||||
gchar *str;
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_bounds (contents, &start, &end);
|
||||
/* strip off the trailing newline, it isn't part of the text that was cut */
|
||||
gtk_text_iter_backward_char (&end);
|
||||
|
||||
str = gtk_text_iter_get_visible_text (&start, &end);
|
||||
gtk_selection_data_set_text (selection_data, str);
|
||||
g_free (str);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2640,11 +2714,7 @@ clipboard_clear_contents_cb (GtkClipboard *clipboard,
|
||||
{
|
||||
GtkTextBuffer *buffer = GTK_TEXT_BUFFER (data);
|
||||
|
||||
if (buffer->clipboard_contents)
|
||||
{
|
||||
g_object_unref (G_OBJECT (buffer->clipboard_contents));
|
||||
buffer->clipboard_contents = NULL;
|
||||
}
|
||||
remove_clipboard_contents_buffer (buffer, clipboard);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2849,39 +2919,21 @@ clipboard_clipboard_buffer_received (GtkClipboard *clipboard,
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
gtk_text_buffer_get_bounds (src_buffer, &start, &end);
|
||||
/* There's an extra newline on clipboard_contents */
|
||||
gtk_text_iter_backward_char (&end);
|
||||
if (g_object_get_data (G_OBJECT (src_buffer), "gtk-text-buffer-clipboard"))
|
||||
{
|
||||
gtk_text_buffer_get_bounds (src_buffer, &start, &end);
|
||||
/* There's an extra newline on clipboard_contents */
|
||||
gtk_text_iter_backward_char (&end);
|
||||
|
||||
paste_from_buffer (request_data, src_buffer,
|
||||
&start, &end);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Request the text selection instead */
|
||||
gtk_clipboard_request_text (clipboard,
|
||||
clipboard_text_received,
|
||||
data);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clipboard_selection_buffer_received (GtkClipboard *clipboard,
|
||||
GtkSelectionData *selection_data,
|
||||
gpointer data)
|
||||
{
|
||||
ClipboardRequest *request_data = data;
|
||||
GtkTextBuffer *src_buffer;
|
||||
|
||||
src_buffer = selection_data_get_buffer (selection_data, request_data);
|
||||
|
||||
if (src_buffer)
|
||||
{
|
||||
GtkTextIter start, end;
|
||||
|
||||
if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
|
||||
paste_from_buffer (request_data, src_buffer,
|
||||
&start, &end);
|
||||
paste_from_buffer (request_data, src_buffer,
|
||||
&start, &end);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
|
||||
paste_from_buffer (request_data, src_buffer,
|
||||
&start, &end);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2900,49 +2952,179 @@ static const GtkTargetEntry targets[] = {
|
||||
{ "GTK_TEXT_BUFFER_CONTENTS", 0, TARGET_TEXT_BUFFER_CONTENTS }
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_text_buffer_update_primary_selection (GtkTextBuffer *buffer)
|
||||
typedef struct
|
||||
{
|
||||
GtkTextIter start;
|
||||
GtkTextIter end;
|
||||
GtkClipboard *clipboard;
|
||||
guint ref_count;
|
||||
} SelectionClipboard;
|
||||
|
||||
GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
|
||||
|
||||
/* Determine whether we have a selection and adjust X selection
|
||||
* accordingly.
|
||||
*/
|
||||
|
||||
if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
|
||||
static void
|
||||
update_selection_clipboards (GtkTextBuffer *buffer)
|
||||
{
|
||||
GSList *tmp_list = buffer->selection_clipboards;
|
||||
while (tmp_list)
|
||||
{
|
||||
if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
|
||||
gtk_clipboard_clear (clipboard);
|
||||
GtkTextIter start;
|
||||
GtkTextIter end;
|
||||
|
||||
SelectionClipboard *selection_clipboard = tmp_list->data;
|
||||
GtkClipboard *clipboard = selection_clipboard->clipboard;
|
||||
|
||||
/* Determine whether we have a selection and adjust X selection
|
||||
* accordingly.
|
||||
*/
|
||||
if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
|
||||
{
|
||||
if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (buffer))
|
||||
gtk_clipboard_clear (clipboard);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Even if we already have the selection, we need to update our
|
||||
* timestamp.
|
||||
*/
|
||||
if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
|
||||
clipboard_get_selection_cb,
|
||||
clipboard_clear_selection_cb,
|
||||
G_OBJECT (buffer)))
|
||||
clipboard_clear_selection_cb (clipboard, buffer);
|
||||
}
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
}
|
||||
|
||||
static SelectionClipboard *
|
||||
find_selection_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard)
|
||||
{
|
||||
GSList *tmp_list = buffer->selection_clipboards;
|
||||
while (tmp_list)
|
||||
{
|
||||
SelectionClipboard *selection_clipboard = tmp_list->data;
|
||||
if (selection_clipboard->clipboard == clipboard)
|
||||
return selection_clipboard;
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_add_selection_clipboard:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @clipboard: a #GtkClipboard
|
||||
*
|
||||
* Adds @clipboard to the list of clipboards in which the selection contents
|
||||
* of @buffer are available. In most cases, @clipboard will be the #GtkClipboard
|
||||
* of type %GDK_SELECTION_PRIMARY for a view of @buffer.
|
||||
**/
|
||||
void
|
||||
gtk_text_buffer_add_selection_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard)
|
||||
{
|
||||
SelectionClipboard *selection_clipboard;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
g_return_if_fail (clipboard != NULL);
|
||||
|
||||
selection_clipboard = find_selection_clipboard (buffer, clipboard);
|
||||
if (selection_clipboard)
|
||||
{
|
||||
selection_clipboard->ref_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Even if we already have the selection, we need to update our
|
||||
* timestamp.
|
||||
*/
|
||||
if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
|
||||
clipboard_get_selection_cb,
|
||||
clipboard_clear_selection_cb,
|
||||
G_OBJECT (buffer)))
|
||||
clipboard_clear_selection_cb (clipboard, buffer);
|
||||
selection_clipboard = g_new (SelectionClipboard, 1);
|
||||
|
||||
selection_clipboard->clipboard = clipboard;
|
||||
selection_clipboard->ref_count = 1;
|
||||
|
||||
buffer->selection_clipboards = g_slist_prepend (buffer->selection_clipboards, selection_clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_remove_selection_clipboard:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @clipboard: a #GtkClipboard added to @buffer by gtk_text_buffer_add_selection_clipboard().
|
||||
*
|
||||
* Removes a #GtkClipboard added with gtk_text_buffer_add_selection_clipboard()
|
||||
**/
|
||||
void
|
||||
gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard)
|
||||
{
|
||||
SelectionClipboard *selection_clipboard;
|
||||
|
||||
g_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
|
||||
g_return_if_fail (clipboard != NULL);
|
||||
|
||||
selection_clipboard = find_selection_clipboard (buffer, clipboard);
|
||||
g_return_if_fail (selection_clipboard != NULL);
|
||||
|
||||
selection_clipboard->ref_count--;
|
||||
if (selection_clipboard->ref_count == 0)
|
||||
{
|
||||
if (gtk_clipboard_get_owner (selection_clipboard->clipboard) == G_OBJECT (buffer))
|
||||
gtk_clipboard_clear (selection_clipboard->clipboard);
|
||||
|
||||
g_free (selection_clipboard);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
paste (GtkTextBuffer *buffer,
|
||||
gboolean is_clipboard,
|
||||
gboolean interactive,
|
||||
gboolean default_editable)
|
||||
remove_all_selection_clipboards (GtkTextBuffer *buffer)
|
||||
{
|
||||
GSList *tmp_list = buffer->selection_clipboards;
|
||||
while (tmp_list)
|
||||
{
|
||||
SelectionClipboard *selection_clipboard = tmp_list->data;
|
||||
|
||||
if (gtk_clipboard_get_owner (selection_clipboard->clipboard) == G_OBJECT (buffer))
|
||||
gtk_clipboard_clear (selection_clipboard->clipboard);
|
||||
|
||||
g_free (selection_clipboard);
|
||||
|
||||
tmp_list = tmp_list->next;
|
||||
}
|
||||
|
||||
g_slist_free (buffer->selection_clipboards);
|
||||
buffer->selection_clipboards = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_paste_clipboard:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @clipboard: the #GtkClipboard to paste from
|
||||
* @override_location: location to insert pasted text, or %NULL for at the cursor
|
||||
* @default_editable: whether the buffer is editable by default
|
||||
*
|
||||
* Pastes the contents of a clipboard at the insertion point, or at @override_location.
|
||||
* (Note: pasting is asynchronous, that is, we'll ask for the paste data and
|
||||
* return, and at some point later after the main loop runs, the paste
|
||||
* data will be inserted.)
|
||||
*
|
||||
**/
|
||||
void
|
||||
gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard,
|
||||
GtkTextIter *override_location,
|
||||
gboolean default_editable)
|
||||
{
|
||||
ClipboardRequest *data = g_new (ClipboardRequest, 1);
|
||||
GtkTextIter paste_point;
|
||||
GtkTextIter start, end;
|
||||
|
||||
|
||||
if (override_location != NULL)
|
||||
gtk_text_buffer_create_mark (buffer,
|
||||
"gtk_paste_point_override",
|
||||
override_location, FALSE);
|
||||
|
||||
data->buffer = buffer;
|
||||
g_object_ref (G_OBJECT (buffer));
|
||||
data->interactive = interactive;
|
||||
data->interactive = TRUE;
|
||||
data->default_editable = default_editable;
|
||||
|
||||
/* When pasting with the cursor inside the selection area, you
|
||||
@ -2959,58 +3141,9 @@ paste (GtkTextBuffer *buffer,
|
||||
gtk_text_iter_equal (&paste_point, &end)))
|
||||
data->replace_selection = TRUE;
|
||||
|
||||
if (is_clipboard)
|
||||
gtk_clipboard_request_contents (gtk_clipboard_get (GDK_NONE),
|
||||
|
||||
gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
|
||||
clipboard_clipboard_buffer_received, data);
|
||||
else
|
||||
gtk_clipboard_request_contents (gtk_clipboard_get (GDK_SELECTION_PRIMARY),
|
||||
|
||||
gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
|
||||
clipboard_selection_buffer_received, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_paste_primary:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @override_location: location to insert pasted text, or %NULL for at the cursor
|
||||
* @default_editable: whether the buffer is editable by default
|
||||
*
|
||||
* Pastes the primary selection at the insertion point, or at @override_location.
|
||||
* (Note: pasting is asynchronous, that is, we'll ask for the paste data
|
||||
* and return, and at some point later after the main loop runs, the paste
|
||||
* data will be inserted.)
|
||||
**/
|
||||
void
|
||||
gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
|
||||
const GtkTextIter *override_location,
|
||||
gboolean default_editable)
|
||||
{
|
||||
if (override_location != NULL)
|
||||
gtk_text_buffer_create_mark (buffer,
|
||||
"gtk_paste_point_override",
|
||||
override_location, FALSE);
|
||||
|
||||
paste (buffer, FALSE, TRUE, default_editable);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_paste_clipboard:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @default_editable: whether the buffer is editable by default
|
||||
*
|
||||
* Pastes the clipboard contents at the insertion point. (Note:
|
||||
* pasting is asynchronous, that is, we'll ask for the paste data and
|
||||
* return, and at some point later after the main loop runs, the paste
|
||||
* data will be inserted.)
|
||||
*
|
||||
**/
|
||||
void
|
||||
gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
|
||||
gboolean default_editable)
|
||||
{
|
||||
paste (buffer, TRUE, TRUE, default_editable);
|
||||
gtk_clipboard_request_contents (clipboard,
|
||||
gdk_atom_intern ("GTK_TEXT_BUFFER_CONTENTS", FALSE),
|
||||
clipboard_clipboard_buffer_received, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3055,9 +3188,10 @@ gtk_text_buffer_delete_selection (GtkTextBuffer *buffer,
|
||||
|
||||
static void
|
||||
cut_or_copy (GtkTextBuffer *buffer,
|
||||
gboolean delete_region_after,
|
||||
gboolean interactive,
|
||||
gboolean default_editable)
|
||||
GtkClipboard *clipboard,
|
||||
gboolean delete_region_after,
|
||||
gboolean interactive,
|
||||
gboolean default_editable)
|
||||
{
|
||||
/* We prefer to cut the selected region between selection_bound and
|
||||
* insertion point. If that region is empty, then we cut the region
|
||||
@ -3068,12 +3202,8 @@ cut_or_copy (GtkTextBuffer *buffer,
|
||||
*/
|
||||
GtkTextIter start;
|
||||
GtkTextIter end;
|
||||
|
||||
if (buffer->clipboard_contents)
|
||||
{
|
||||
g_object_unref (G_OBJECT (buffer->clipboard_contents));
|
||||
buffer->clipboard_contents = NULL;
|
||||
}
|
||||
|
||||
remove_clipboard_contents_buffer (buffer, clipboard);
|
||||
|
||||
if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end))
|
||||
{
|
||||
@ -3091,19 +3221,14 @@ cut_or_copy (GtkTextBuffer *buffer,
|
||||
|
||||
if (!gtk_text_iter_equal (&start, &end))
|
||||
{
|
||||
GtkClipboard *clipboard = gtk_clipboard_get (GDK_NONE);
|
||||
GtkTextIter ins;
|
||||
GtkTextBuffer *contents;
|
||||
|
||||
buffer->clipboard_contents =
|
||||
gtk_text_buffer_new (gtk_text_buffer_get_tag_table (buffer));
|
||||
contents = get_clipboard_contents_buffer (buffer, clipboard, TRUE);
|
||||
|
||||
gtk_text_buffer_get_iter_at_offset (buffer->clipboard_contents,
|
||||
&ins, 0);
|
||||
gtk_text_buffer_get_iter_at_offset (contents, &ins, 0);
|
||||
|
||||
gtk_text_buffer_insert_range (buffer->clipboard_contents,
|
||||
&ins,
|
||||
&start,
|
||||
&end);
|
||||
gtk_text_buffer_insert_range (contents, &ins, &start, &end);
|
||||
|
||||
if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
|
||||
clipboard_get_contents_cb,
|
||||
@ -3124,34 +3249,38 @@ cut_or_copy (GtkTextBuffer *buffer,
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_cut_clipboard:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @clipboard: the #GtkClipboard object to cut to.
|
||||
* @default_editable: default editability of the buffer
|
||||
*
|
||||
* Copies the currently-selected text to the clipboard, then deletes
|
||||
* Copies the currently-selected text to a clipboard, then deletes
|
||||
* said text if it's editable.
|
||||
*
|
||||
**/
|
||||
void
|
||||
gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard,
|
||||
gboolean default_editable)
|
||||
{
|
||||
gtk_text_buffer_begin_user_action (buffer);
|
||||
cut_or_copy (buffer, TRUE, TRUE, default_editable);
|
||||
cut_or_copy (buffer, clipboard, TRUE, TRUE, default_editable);
|
||||
gtk_text_buffer_end_user_action (buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_text_buffer_copy_clipboard:
|
||||
* @buffer: a #GtkTextBuffer
|
||||
* @clipboard: the #GtkClipboard object to copy to.
|
||||
*
|
||||
* Copies the currently-selected text to the clipboard.
|
||||
* Copies the currently-selected text to a clipboard.
|
||||
*
|
||||
**/
|
||||
void
|
||||
gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer)
|
||||
gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard)
|
||||
{
|
||||
gtk_text_buffer_begin_user_action (buffer);
|
||||
cut_or_copy (buffer, FALSE, TRUE, TRUE);
|
||||
cut_or_copy (buffer, clipboard, FALSE, TRUE, TRUE);
|
||||
gtk_text_buffer_end_user_action (buffer);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define GTK_TEXT_BUFFER_H
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
#include <gtk/gtkclipboard.h>
|
||||
#include <gtk/gtktexttagtable.h>
|
||||
#include <gtk/gtktextiter.h>
|
||||
#include <gtk/gtktextmark.h>
|
||||
@ -62,7 +63,8 @@ struct _GtkTextBuffer
|
||||
GtkTextTagTable *tag_table;
|
||||
GtkTextBTree *btree;
|
||||
|
||||
GtkTextBuffer *clipboard_contents;
|
||||
GSList *clipboard_contents_buffers;
|
||||
GSList *selection_clipboards;
|
||||
|
||||
GtkTextLogAttrCache *log_attr_cache;
|
||||
|
||||
@ -324,13 +326,19 @@ gboolean gtk_text_buffer_get_modified (GtkTextBuffer *buffer);
|
||||
void gtk_text_buffer_set_modified (GtkTextBuffer *buffer,
|
||||
gboolean setting);
|
||||
|
||||
void gtk_text_buffer_paste_primary (GtkTextBuffer *buffer,
|
||||
const GtkTextIter *override_location,
|
||||
gboolean default_editable);
|
||||
void gtk_text_buffer_add_selection_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard);
|
||||
void gtk_text_buffer_remove_selection_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard);
|
||||
|
||||
void gtk_text_buffer_cut_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard,
|
||||
gboolean default_editable);
|
||||
void gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer);
|
||||
void gtk_text_buffer_copy_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard);
|
||||
void gtk_text_buffer_paste_clipboard (GtkTextBuffer *buffer,
|
||||
GtkClipboard *clipboard,
|
||||
GtkTextIter *override_location,
|
||||
gboolean default_editable);
|
||||
|
||||
gboolean gtk_text_buffer_get_selection_bounds (GtkTextBuffer *buffer,
|
||||
|
@ -1050,6 +1050,10 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
|
||||
gtk_text_view_mark_set_handler, text_view);
|
||||
g_object_unref (G_OBJECT (text_view->buffer));
|
||||
text_view->dnd_mark = NULL;
|
||||
|
||||
if (GTK_WIDGET_REALIZED (text_view))
|
||||
gtk_text_buffer_remove_selection_clipboard (text_view->buffer,
|
||||
gtk_clipboard_get (GDK_SELECTION_PRIMARY));
|
||||
}
|
||||
|
||||
text_view->buffer = buffer;
|
||||
@ -1077,6 +1081,10 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
|
||||
|
||||
g_signal_connect (G_OBJECT (text_view->buffer), "mark_set",
|
||||
G_CALLBACK (gtk_text_view_mark_set_handler), text_view);
|
||||
|
||||
if (GTK_WIDGET_REALIZED (text_view))
|
||||
gtk_text_buffer_remove_selection_clipboard (text_view->buffer,
|
||||
gtk_clipboard_get (GDK_SELECTION_PRIMARY));
|
||||
}
|
||||
|
||||
if (GTK_WIDGET_VISIBLE (text_view))
|
||||
@ -2939,6 +2947,10 @@ gtk_text_view_realize (GtkWidget *widget)
|
||||
widget->window);
|
||||
|
||||
gtk_text_view_ensure_layout (text_view);
|
||||
|
||||
if (text_view->buffer)
|
||||
gtk_text_buffer_add_selection_clipboard (text_view->buffer,
|
||||
gtk_clipboard_get (GDK_SELECTION_PRIMARY));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2948,6 +2960,10 @@ gtk_text_view_unrealize (GtkWidget *widget)
|
||||
|
||||
text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
if (text_view->buffer)
|
||||
gtk_text_buffer_remove_selection_clipboard (text_view->buffer,
|
||||
gtk_clipboard_get (GDK_SELECTION_PRIMARY));
|
||||
|
||||
if (text_view->first_validate_idle)
|
||||
{
|
||||
g_source_remove (text_view->first_validate_idle);
|
||||
@ -3290,9 +3306,10 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
|
||||
event->x + text_view->xoffset,
|
||||
event->y + text_view->yoffset);
|
||||
|
||||
gtk_text_buffer_paste_primary (get_buffer (text_view),
|
||||
&iter,
|
||||
text_view->editable);
|
||||
gtk_text_buffer_paste_clipboard (get_buffer (text_view),
|
||||
gtk_clipboard_get (GDK_SELECTION_PRIMARY),
|
||||
&iter,
|
||||
text_view->editable);
|
||||
return TRUE;
|
||||
}
|
||||
else if (event->button == 3)
|
||||
@ -4170,7 +4187,9 @@ gtk_text_view_delete_from_cursor (GtkTextView *text_view,
|
||||
static void
|
||||
gtk_text_view_cut_clipboard (GtkTextView *text_view)
|
||||
{
|
||||
gtk_text_buffer_cut_clipboard (get_buffer (text_view), text_view->editable);
|
||||
gtk_text_buffer_cut_clipboard (get_buffer (text_view),
|
||||
gtk_clipboard_get (GDK_NONE),
|
||||
text_view->editable);
|
||||
DV(g_print (G_STRLOC": scrolling onscreen\n"));
|
||||
gtk_text_view_scroll_mark_onscreen (text_view,
|
||||
gtk_text_buffer_get_mark (get_buffer (text_view),
|
||||
@ -4180,7 +4199,8 @@ gtk_text_view_cut_clipboard (GtkTextView *text_view)
|
||||
static void
|
||||
gtk_text_view_copy_clipboard (GtkTextView *text_view)
|
||||
{
|
||||
gtk_text_buffer_copy_clipboard (get_buffer (text_view));
|
||||
gtk_text_buffer_copy_clipboard (get_buffer (text_view),
|
||||
gtk_clipboard_get (GDK_NONE));
|
||||
DV(g_print (G_STRLOC": scrolling onscreen\n"));
|
||||
gtk_text_view_scroll_mark_onscreen (text_view,
|
||||
gtk_text_buffer_get_mark (get_buffer (text_view),
|
||||
@ -4190,7 +4210,10 @@ gtk_text_view_copy_clipboard (GtkTextView *text_view)
|
||||
static void
|
||||
gtk_text_view_paste_clipboard (GtkTextView *text_view)
|
||||
{
|
||||
gtk_text_buffer_paste_clipboard (get_buffer (text_view), text_view->editable);
|
||||
gtk_text_buffer_paste_clipboard (get_buffer (text_view),
|
||||
gtk_clipboard_get (GDK_NONE),
|
||||
NULL,
|
||||
text_view->editable);
|
||||
DV(g_print (G_STRLOC": scrolling onscreen\n"));
|
||||
gtk_text_view_scroll_mark_onscreen (text_view,
|
||||
gtk_text_buffer_get_mark (get_buffer (text_view),
|
||||
|
Loading…
Reference in New Issue
Block a user