From 7f8170c5c5afa9a08930e29c0ef15683ee79d60c Mon Sep 17 00:00:00 2001 From: thegame1999 Date: Wed, 25 Feb 2026 18:49:17 +0200 Subject: [PATCH] Improve the usability of cut-copy-paste-delete operations to allow yanking the whole row --- xed/xed-commands-edit.c | 8 +- xed/xed-view.c | 169 ++++++++-------------------------------- xed/xed-view.h | 7 +- xed/xed-window.c | 39 +--------- 4 files changed, 42 insertions(+), 181 deletions(-) diff --git a/xed/xed-commands-edit.c b/xed/xed-commands-edit.c index 79f753b9..4250df3e 100644 --- a/xed/xed-commands-edit.c +++ b/xed/xed-commands-edit.c @@ -92,7 +92,7 @@ _xed_cmd_edit_cut (GtkAction *action, active_view = xed_window_get_active_view (window); g_return_if_fail (active_view); - xed_view_cut_clipboard (active_view); + xed_view_cut_clipboard (GTK_TEXT_VIEW (active_view)); gtk_widget_grab_focus (GTK_WIDGET (active_view)); } @@ -108,7 +108,7 @@ _xed_cmd_edit_copy (GtkAction *action, active_view = xed_window_get_active_view (window); g_return_if_fail (active_view); - xed_view_copy_clipboard (active_view); + xed_view_copy_clipboard (GTK_TEXT_VIEW (active_view)); gtk_widget_grab_focus (GTK_WIDGET (active_view)); } @@ -124,7 +124,7 @@ _xed_cmd_edit_paste (GtkAction *action, active_view = xed_window_get_active_view (window); g_return_if_fail (active_view); - xed_view_paste_clipboard (active_view); + g_signal_emit_by_name(GTK_TEXT_VIEW (active_view), "paste-clipboard"); gtk_widget_grab_focus (GTK_WIDGET (active_view)); } @@ -140,7 +140,7 @@ _xed_cmd_edit_delete (GtkAction *action, active_view = xed_window_get_active_view (window); g_return_if_fail (active_view); - xed_view_delete_selection (active_view); + xed_view_delete_selection (GTK_TEXT_VIEW (active_view)); gtk_widget_grab_focus (GTK_WIDGET (active_view)); } diff --git a/xed/xed-view.c b/xed/xed-view.c index 8f698554..6adc2f10 100644 --- a/xed/xed-view.c +++ b/xed/xed-view.c @@ -442,40 +442,23 @@ xed_view_realize (GtkWidget *widget) } static void -delete_line (GtkTextView *text_view, - gint count) +copy_cut_delete (GtkTextView *text_view, + const gboolean copy, + const gboolean delete) { + GtkTextBuffer *buffer; GtkTextIter start; GtkTextIter end; - GtkTextBuffer *buffer; - - buffer = gtk_text_view_get_buffer (text_view); - - gtk_text_view_reset_im_context (text_view); - /* If there is a selection delete the selected lines and - * ignore count */ - if (gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) - { - gtk_text_iter_order (&start, &end); - if (gtk_text_iter_starts_line (&end)) - { - /* Do no delete the line with the cursor if the cursor - * is at the beginning of the line */ - count = 0; - } - else - { - count = 1; - } - } + xed_debug (DEBUG_VIEW); - gtk_text_iter_set_line_offset (&start, 0); + buffer = gtk_text_view_get_buffer (text_view); + g_return_if_fail(buffer != NULL); - if (count > 0) + if (!gtk_text_buffer_get_selection_bounds (buffer, &start, &end)) { - gtk_text_iter_forward_lines (&end, count); - if (gtk_text_iter_is_end (&end)) + gtk_text_iter_set_line_offset (&start, 0); + if (!gtk_text_iter_forward_line (&end)) { if (gtk_text_iter_backward_line (&start) && !gtk_text_iter_ends_line (&start)) { @@ -483,49 +466,26 @@ delete_line (GtkTextView *text_view, } } } - else if (count < 0) - { - if (!gtk_text_iter_ends_line (&end)) - { - gtk_text_iter_forward_to_line_end (&end); - } - while (count < 0) - { - if (!gtk_text_iter_backward_line (&start)) - { - break; - } - ++count; - } + if (gtk_text_iter_equal (&start, &end)) + return; - if (count == 0) - { - if (!gtk_text_iter_ends_line (&start)) - { - gtk_text_iter_forward_to_line_end (&start); - } - } - else - { - gtk_text_iter_forward_line (&end); - } + if (copy) + { + GtkClipboard *clipboard = gtk_widget_get_clipboard (GTK_WIDGET(text_view), GDK_SELECTION_CLIPBOARD); + + gchar *str = gtk_text_iter_get_visible_text (&start, &end); + gtk_clipboard_set_text (clipboard, str, -1); + gtk_clipboard_set_can_store (clipboard, NULL, 0); + g_free (str); } - if (!gtk_text_iter_equal (&start, &end)) + if (delete) { - GtkTextIter cur = start; - gtk_text_iter_set_line_offset (&cur, 0); - gtk_text_buffer_begin_user_action (buffer); - gtk_text_buffer_place_cursor (buffer, &cur); - gtk_text_buffer_delete_interactive (buffer, &start, &end, gtk_text_view_get_editable (text_view)); - gtk_text_buffer_end_user_action (buffer); + const gboolean default_editable = gtk_text_view_get_editable (text_view); + gtk_text_buffer_delete_interactive (buffer, &start, &end, default_editable); gtk_text_view_scroll_mark_onscreen (text_view, gtk_text_buffer_get_insert (buffer)); } - else - { - gtk_widget_error_bell (GTK_WIDGET(text_view)); - } } static void @@ -540,7 +500,7 @@ xed_view_delete_from_cursor (GtkTextView *text_view, switch (type) { case GTK_DELETE_PARAGRAPHS: - delete_line (text_view, count); + copy_cut_delete(text_view, FALSE, TRUE); break; default: GTK_TEXT_VIEW_CLASS (xed_view_parent_class)->delete_from_cursor (text_view, type, count); @@ -589,6 +549,8 @@ xed_view_class_init (XedViewClass *klass) text_view_class->delete_from_cursor = xed_view_delete_from_cursor; text_view_class->create_buffer = xed_view_create_buffer; + text_view_class->cut_clipboard = xed_view_cut_clipboard; + text_view_class->copy_clipboard = xed_view_copy_clipboard; /* A new signal DROP_URIS has been added to allow plugins to intercept * the default dnd behaviour of 'text/uri-list'. XedView now handles @@ -670,88 +632,21 @@ xed_view_new (XedDocument *doc) } void -xed_view_cut_clipboard (XedView *view) -{ - GtkTextBuffer *buffer; - GtkClipboard *clipboard; - - xed_debug (DEBUG_VIEW); - g_return_if_fail(XED_IS_VIEW (view)); - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view)); - g_return_if_fail(buffer != NULL); - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD); - - /* FIXME: what is default editability of a buffer? */ - gtk_text_buffer_cut_clipboard (buffer, clipboard, !xed_document_get_readonly (XED_DOCUMENT(buffer))); - - gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW(view), gtk_text_buffer_get_insert (buffer), XED_VIEW_SCROLL_MARGIN, - FALSE, 0.0, 0.0); -} - -void -xed_view_copy_clipboard (XedView *view) +xed_view_cut_clipboard (GtkTextView *text_view) { - GtkTextBuffer *buffer; - GtkClipboard *clipboard; - - xed_debug (DEBUG_VIEW); - g_return_if_fail(XED_IS_VIEW (view)); - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view)); - g_return_if_fail(buffer != NULL); - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD); - gtk_text_buffer_copy_clipboard (buffer, clipboard); + copy_cut_delete(text_view, TRUE, TRUE); } void -xed_view_paste_clipboard (XedView *view) +xed_view_copy_clipboard (GtkTextView *text_view) { - GtkTextBuffer *buffer; - GtkClipboard *clipboard; - - xed_debug (DEBUG_VIEW); - - g_return_if_fail(XED_IS_VIEW (view)); - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view)); - g_return_if_fail(buffer != NULL); - - clipboard = gtk_widget_get_clipboard (GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD); - - /* FIXME: what is default editability of a buffer? */ - gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, !xed_document_get_readonly (XED_DOCUMENT(buffer))); - - gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW(view), gtk_text_buffer_get_insert (buffer), XED_VIEW_SCROLL_MARGIN, - FALSE, 0.0, 0.0); + copy_cut_delete(text_view, TRUE, FALSE); } -/** - * xed_view_delete_selection: - * @view: a #XedView - * - * Deletes the text currently selected in the #GtkTextBuffer associated - * to the view and scroll to the cursor position. - **/ void -xed_view_delete_selection (XedView *view) +xed_view_delete_selection (GtkTextView *text_view) { - GtkTextBuffer *buffer = NULL; - - xed_debug (DEBUG_VIEW); - - g_return_if_fail(XED_IS_VIEW (view)); - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view)); - g_return_if_fail(buffer != NULL); - - /* FIXME: what is default editability of a buffer? */ - gtk_text_buffer_delete_selection (buffer, TRUE, !xed_document_get_readonly (XED_DOCUMENT(buffer))); - - gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW(view), gtk_text_buffer_get_insert (buffer), XED_VIEW_SCROLL_MARGIN, - FALSE, 0.0, 0.0); + copy_cut_delete(text_view, FALSE, TRUE); } /** diff --git a/xed/xed-view.h b/xed/xed-view.h index e730b8fe..00f296e0 100644 --- a/xed/xed-view.h +++ b/xed/xed-view.h @@ -54,10 +54,9 @@ struct _XedViewClass */ GType xed_view_get_type (void) G_GNUC_CONST; GtkWidget *xed_view_new (XedDocument *doc); -void xed_view_cut_clipboard (XedView *view); -void xed_view_copy_clipboard (XedView *view); -void xed_view_paste_clipboard (XedView *view); -void xed_view_delete_selection (XedView *view); +void xed_view_cut_clipboard (GtkTextView *text_view); +void xed_view_copy_clipboard (GtkTextView *text_view); +void xed_view_delete_selection (GtkTextView *text_view); void xed_view_duplicate (XedView *view); void xed_view_select_all (XedView *view); void xed_view_scroll_to_cursor (XedView *view); diff --git a/xed/xed-window.c b/xed/xed-window.c index 5c9356ca..21f36e53 100644 --- a/xed/xed-window.c +++ b/xed/xed-window.c @@ -688,13 +688,11 @@ set_sensitivity_according_to_tab (XedWindow *window, gtk_action_set_sensitive (action, state_normal && gtk_source_buffer_can_redo (GTK_SOURCE_BUFFER(doc))); action = gtk_action_group_get_action (window->priv->action_group, "EditCut"); - gtk_action_set_sensitive (action, - state_normal && editable && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(doc))); + gtk_action_set_sensitive (action, state_normal && editable); action = gtk_action_group_get_action (window->priv->action_group, "EditCopy"); gtk_action_set_sensitive (action, - (state_normal || state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) - && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(doc))); + (state_normal || state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)); action = gtk_action_group_get_action (window->priv->action_group, "EditPaste"); if (state_normal && editable) @@ -707,8 +705,7 @@ set_sensitivity_according_to_tab (XedWindow *window, } action = gtk_action_group_get_action (window->priv->action_group, "EditDelete"); - gtk_action_set_sensitive (action, - state_normal && editable && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(doc))); + gtk_action_set_sensitive (action, state_normal && editable); action = gtk_action_group_get_action (window->priv->action_group, "SearchFind"); gtk_action_set_sensitive (action, (state_normal || state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION)); @@ -2712,40 +2709,10 @@ selection_changed (XedDocument *doc, GParamSpec *pspec, XedWindow *window) { - XedTab *tab; - XedView *view; - GtkAction *action; - XedTabState state; - gboolean state_normal; - gboolean editable; - - xed_debug (DEBUG_WINDOW); - if (doc != xed_window_get_active_document (window)) { return; } - - tab = xed_tab_get_from_document (doc); - state = xed_tab_get_state (tab); - state_normal = (state == XED_TAB_STATE_NORMAL); - - view = xed_tab_get_view (tab); - editable = gtk_text_view_get_editable (GTK_TEXT_VIEW(view)); - - action = gtk_action_group_get_action (window->priv->action_group, "EditCut"); - gtk_action_set_sensitive (action, - state_normal && editable && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(doc))); - - action = gtk_action_group_get_action (window->priv->action_group, "EditCopy"); - gtk_action_set_sensitive (action, - (state_normal || state == XED_TAB_STATE_EXTERNALLY_MODIFIED_NOTIFICATION) - && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(doc))); - - action = gtk_action_group_get_action (window->priv->action_group, "EditDelete"); - gtk_action_set_sensitive (action, - state_normal && editable && gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER(doc))); - peas_extension_set_call (window->priv->extensions, "update_state"); }