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:
Owen Taylor 2001-08-31 01:33:11 +00:00 committed by Owen Taylor
parent d5f469987b
commit b97a0a452f
10 changed files with 446 additions and 181 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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,

View File

@ -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),