Bug 492794 – Pasting external text at end of view yields wrong scrolling

2009-01-12  Paolo Borelli  <pborelli@katamail.com>

	Bug 492794 – Pasting external text at end of view yields wrong
	scrolling to mark

	* gtk/gtktextbuffer.[ch]:
	* gtk/gtktextview.c:
	Add a "paste-done" signal and use it to propelry scroll the
	view at the end of the pasted text in the case of an async
	paste. Patch by Ignacio Casal Quintero based on a patch by
	Yevgen Muntyan.


svn path=/trunk/; revision=22100
This commit is contained in:
Paolo Borelli 2009-01-12 17:07:35 +00:00 committed by Paolo Borelli
parent 8a604cfe57
commit 1a7c0ed099
4 changed files with 72 additions and 6 deletions

View File

@ -1,3 +1,15 @@
2009-01-12 Paolo Borelli <pborelli@katamail.com>
Bug 492794 Pasting external text at end of view yields wrong
scrolling to mark
* gtk/gtktextbuffer.[ch]:
* gtk/gtktextview.c:
Add a "paste-done" signal and use it to propelry scroll the
view at the end of the pasted text in the case of an async
paste. Patch by Ignacio Casal Quintero based on a patch by
Yevgen Muntyan.
2009-01-12 Tor Lillqvist <tml@iki.fi> 2009-01-12 Tor Lillqvist <tml@iki.fi>
* gdk/gdk.c (gdk_arg_debug_cb) (gdk_arg_no_debug_cb): A * gdk/gdk.c (gdk_arg_debug_cb) (gdk_arg_no_debug_cb): A

View File

@ -83,6 +83,7 @@ enum {
REMOVE_TAG, REMOVE_TAG,
BEGIN_USER_ACTION, BEGIN_USER_ACTION,
END_USER_ACTION, END_USER_ACTION,
PASTE_DONE,
LAST_SIGNAL LAST_SIGNAL
}; };
@ -581,6 +582,27 @@ gtk_text_buffer_class_init (GtkTextBufferClass *klass)
G_TYPE_NONE, G_TYPE_NONE,
0); 0);
/**
* GtkTextBuffer::paste-done:
* @textbuffer: the object which received the signal
*
* The paste-done signal is emitted after paste operation has been completed.
* This is useful to properly scroll the view to the end of the pasted text.
* See gtk_text_buffer_paste_clipboard() for more details.
*
* Since: 2.16
*/
signals[PASTE_DONE] =
g_signal_new (I_("paste_done"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkTextBufferClass, paste_done),
NULL, NULL,
_gtk_marshal_VOID__OBJECT,
G_TYPE_NONE,
1,
GTK_TYPE_CLIPBOARD);
g_type_class_add_private (object_class, sizeof (GtkTextBufferPrivate)); g_type_class_add_private (object_class, sizeof (GtkTextBufferPrivate));
} }
@ -3301,6 +3323,13 @@ post_paste_cleanup (ClipboardRequest *request_data)
} }
} }
static void
emit_paste_done (GtkTextBuffer *buffer,
GtkClipboard *clipboard)
{
g_signal_emit (buffer, signals[PASTE_DONE], 0, clipboard);
}
static void static void
free_clipboard_request (ClipboardRequest *request_data) free_clipboard_request (ClipboardRequest *request_data)
{ {
@ -3338,6 +3367,8 @@ clipboard_text_received (GtkClipboard *clipboard,
if (request_data->interactive) if (request_data->interactive)
gtk_text_buffer_end_user_action (buffer); gtk_text_buffer_end_user_action (buffer);
emit_paste_done (buffer, clipboard);
} }
free_clipboard_request (request_data); free_clipboard_request (request_data);
@ -3448,6 +3479,8 @@ clipboard_rich_text_received (GtkClipboard *clipboard,
if (request_data->interactive) if (request_data->interactive)
gtk_text_buffer_end_user_action (request_data->buffer); gtk_text_buffer_end_user_action (request_data->buffer);
emit_paste_done (request_data->buffer, clipboard);
if (retval) if (retval)
{ {
post_paste_cleanup (request_data); post_paste_cleanup (request_data);
@ -3462,7 +3495,8 @@ clipboard_rich_text_received (GtkClipboard *clipboard,
} }
static void static void
paste_from_buffer (ClipboardRequest *request_data, paste_from_buffer (GtkClipboard *clipboard,
ClipboardRequest *request_data,
GtkTextBuffer *src_buffer, GtkTextBuffer *src_buffer,
const GtkTextIter *start, const GtkTextIter *start,
const GtkTextIter *end) const GtkTextIter *end)
@ -3495,6 +3529,8 @@ paste_from_buffer (ClipboardRequest *request_data,
if (request_data->interactive) if (request_data->interactive)
gtk_text_buffer_end_user_action (buffer); gtk_text_buffer_end_user_action (buffer);
emit_paste_done (buffer, clipboard);
g_object_unref (src_buffer); g_object_unref (src_buffer);
free_clipboard_request (request_data); free_clipboard_request (request_data);
@ -3518,13 +3554,13 @@ clipboard_clipboard_buffer_received (GtkClipboard *clipboard,
{ {
gtk_text_buffer_get_bounds (src_buffer, &start, &end); gtk_text_buffer_get_bounds (src_buffer, &start, &end);
paste_from_buffer (request_data, src_buffer, paste_from_buffer (clipboard, request_data, src_buffer,
&start, &end); &start, &end);
} }
else else
{ {
if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end)) if (gtk_text_buffer_get_selection_bounds (src_buffer, &start, &end))
paste_from_buffer (request_data, src_buffer, paste_from_buffer (clipboard, request_data, src_buffer,
&start, &end); &start, &end);
} }
} }

View File

@ -143,13 +143,15 @@ struct _GtkTextBufferClass
void (* begin_user_action) (GtkTextBuffer *buffer); void (* begin_user_action) (GtkTextBuffer *buffer);
void (* end_user_action) (GtkTextBuffer *buffer); void (* end_user_action) (GtkTextBuffer *buffer);
void (* paste_done) (GtkTextBuffer *buffer,
GtkClipboard *clipboard);
/* Padding for future expansion */ /* Padding for future expansion */
void (*_gtk_reserved1) (void); void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void); void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void); void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void); void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void); void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
}; };
GType gtk_text_buffer_get_type (void) G_GNUC_CONST; GType gtk_text_buffer_get_type (void) G_GNUC_CONST;

View File

@ -329,6 +329,9 @@ static void gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
static void gtk_text_view_target_list_notify (GtkTextBuffer *buffer, static void gtk_text_view_target_list_notify (GtkTextBuffer *buffer,
const GParamSpec *pspec, const GParamSpec *pspec,
gpointer data); gpointer data);
static void gtk_text_view_paste_done_handler (GtkTextBuffer *buffer,
GtkClipboard *clipboard,
gpointer data);
static void gtk_text_view_get_cursor_location (GtkTextView *text_view, static void gtk_text_view_get_cursor_location (GtkTextView *text_view,
GdkRectangle *pos); GdkRectangle *pos);
static void gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view, static void gtk_text_view_get_virtual_cursor_pos (GtkTextView *text_view,
@ -1384,6 +1387,9 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
g_signal_handlers_disconnect_by_func (text_view->buffer, g_signal_handlers_disconnect_by_func (text_view->buffer,
gtk_text_view_target_list_notify, gtk_text_view_target_list_notify,
text_view); text_view);
g_signal_handlers_disconnect_by_func (text_view->buffer,
gtk_text_view_paste_done_handler,
text_view);
g_object_unref (text_view->buffer); g_object_unref (text_view->buffer);
text_view->dnd_mark = NULL; text_view->dnd_mark = NULL;
text_view->first_para_mark = NULL; text_view->first_para_mark = NULL;
@ -1425,6 +1431,9 @@ gtk_text_view_set_buffer (GtkTextView *text_view,
g_signal_connect (text_view->buffer, "notify::paste-target-list", g_signal_connect (text_view->buffer, "notify::paste-target-list",
G_CALLBACK (gtk_text_view_target_list_notify), G_CALLBACK (gtk_text_view_target_list_notify),
text_view); text_view);
g_signal_connect (text_view->buffer, "paste-done",
G_CALLBACK (gtk_text_view_paste_done_handler),
text_view);
gtk_text_view_target_list_notify (text_view->buffer, NULL, text_view); gtk_text_view_target_list_notify (text_view->buffer, NULL, text_view);
@ -5702,9 +5711,16 @@ gtk_text_view_paste_clipboard (GtkTextView *text_view)
clipboard, clipboard,
NULL, NULL,
text_view->editable); text_view->editable);
}
static void
gtk_text_view_paste_done_handler (GtkTextBuffer *buffer,
GtkClipboard *clipboard,
gpointer data)
{
GtkTextView *text_view = data;
DV(g_print (G_STRLOC": scrolling onscreen\n")); DV(g_print (G_STRLOC": scrolling onscreen\n"));
gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_buffer_get_insert (buffer));
gtk_text_buffer_get_insert (get_buffer (text_view)));
} }
static void static void