r21918 - gnucash/trunk/src/register/register-gnome - [r21886][Bug #667900] No clipboard copy and paste

John Ralls jralls at code.gnucash.org
Sun Jan 29 20:54:01 EST 2012


Author: jralls
Date: 2012-01-29 20:54:01 -0500 (Sun, 29 Jan 2012)
New Revision: 21918
Trac: http://svn.gnucash.org/trac/changeset/21918

Modified:
   gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c
   gnucash/trunk/src/register/register-gnome/gnucash-item-edit.h
   gnucash/trunk/src/register/register-gnome/gnucash-sheet.c
Log:
[r21886][Bug #667900] No clipboard copy and paste

Forward-port of r21886, done in the 2.4 branch to quickly resolve bug
#667900 and to give windows users a nightly build to test with.

Extends that change by also converting the GDK_SELECTION_PRIMARY
operations to use GtkClipboard instead of GtkSelection.



Modified: gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c
===================================================================
--- gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c	2012-01-30 00:28:06 UTC (rev 21917)
+++ gnucash/trunk/src/register/register-gnome/gnucash-item-edit.c	2012-01-30 01:54:01 UTC (rev 21918)
@@ -582,9 +582,7 @@
     item_edit->sheet = NULL;
     item_edit->parent = NULL;
     item_edit->editor = NULL;
-    item_edit->clipboard = NULL;
 
-    item_edit->has_selection = FALSE;
     item_edit->is_popup = FALSE;
     item_edit->show_popup = FALSE;
 
@@ -654,12 +652,6 @@
 {
     GncItemEdit *item_edit = GNC_ITEM_EDIT (object);
 
-    if (item_edit->clipboard != NULL)
-    {
-        g_free (item_edit->clipboard);
-        item_edit->clipboard = NULL;
-    }
-
     if (item_edit->gc)
     {
         g_object_unref (item_edit->gc);
@@ -831,6 +823,7 @@
 gnc_item_edit_cut_copy_clipboard (GncItemEdit *item_edit, guint32 time, gboolean cut)
 {
     GtkEditable *editable;
+    GtkClipboard *clipboard;
     gint start_sel, end_sel;
     gchar *clip;
 
@@ -842,16 +835,14 @@
     if (!gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel))
         return;
 
-    g_free(item_edit->clipboard);
+    clipboard = gtk_widget_get_clipboard (GTK_WIDGET (editable),
+					  clipboard_atom);
+    g_return_if_fail (clipboard != NULL);
+    g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
+    clip = gtk_editable_get_chars (editable, start_sel, end_sel);
+    gtk_clipboard_set_text (clipboard, clip, -1);
+    g_free (clip);
 
-    if (gtk_selection_owner_set (GTK_WIDGET(item_edit->sheet),
-                                 clipboard_atom, time))
-        clip = gtk_editable_get_chars (editable, start_sel, end_sel);
-    else
-        clip = NULL;
-
-    item_edit->clipboard = clip;
-
     if (!cut)
         return;
 
@@ -874,32 +865,53 @@
 }
 
 
-void
-gnc_item_edit_paste_clipboard (GncItemEdit *item_edit, guint32 time)
+
+static void
+paste_received (GtkClipboard *clipboard, const gchar *text, gpointer data)
 {
-    g_return_if_fail(item_edit != NULL);
-    g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
+    GtkEditable *editable = GTK_EDITABLE (data);
+    gboolean reselect = FALSE;
+    gint old_pos, tmp_pos;
+    gint start_sel, end_sel;
 
-    gtk_selection_convert(GTK_WIDGET(item_edit->sheet),
-                          clipboard_atom,
-                          gdk_atom_intern("UTF8_STRING", FALSE),
-                          time);
-}
+    if (text == NULL)
+	return;
+    if (gtk_editable_get_selection_bounds (editable, &start_sel, &end_sel))
+    {
+	reselect = TRUE;
+	gtk_editable_delete_text (editable, start_sel, end_sel);
+    }
 
+    tmp_pos = old_pos = gtk_editable_get_position (editable);
 
+    gtk_editable_insert_text (editable, text, -1, &tmp_pos);
+    gtk_editable_set_position (editable, tmp_pos);
+
+    if (!reselect)
+	return;
+
+    gtk_editable_select_region (editable, old_pos,
+				gtk_editable_get_position (editable));
+
+}
+
 void
-gnc_item_edit_paste_primary (GncItemEdit *item_edit, guint32 time)
+gnc_item_edit_paste_selection (GncItemEdit *item_edit, GdkAtom selection,
+			       guint32 time)
 {
+    GtkClipboard *clipboard;
     g_return_if_fail(item_edit != NULL);
     g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
 
-    gtk_selection_convert(GTK_WIDGET(item_edit->sheet),
-                          GDK_SELECTION_PRIMARY,
-                          gdk_atom_intern("UTF8_STRING", FALSE),
-                          time);
-}
+    clipboard = gtk_widget_get_clipboard (GTK_WIDGET (item_edit->sheet),
+					  selection);
 
+    g_return_if_fail (clipboard != NULL);
+    g_return_if_fail (GTK_IS_CLIPBOARD (clipboard));
 
+    gtk_clipboard_request_text (clipboard, paste_received, item_edit->editor);
+}
+
 static void
 gnc_item_edit_show_popup_toggle (GncItemEdit *item_edit,
                                  gint x, gint y,
@@ -1464,153 +1476,3 @@
     return gtk_editable_get_selection_bounds(editable, NULL, NULL);
 }
 
-gboolean
-gnc_item_edit_selection_clear (GncItemEdit          *item_edit,
-                               GdkEventSelection *event)
-{
-    g_return_val_if_fail(item_edit != NULL, FALSE);
-    g_return_val_if_fail(GNC_IS_ITEM_EDIT(item_edit), FALSE);
-    g_return_val_if_fail(event != NULL, FALSE);
-
-    /* Let the selection handling code know that the selection
-     * has been changed, since we've overriden the default handler */
-    if (!gtk_selection_clear (GTK_WIDGET(item_edit->sheet), event))
-        return FALSE;
-
-    if (event->selection == GDK_SELECTION_PRIMARY)
-    {
-        if (item_edit->has_selection)
-        {
-            item_edit->has_selection = FALSE;
-            /* TODO: redraw differently? */
-        }
-    }
-    else if (event->selection == clipboard_atom)
-    {
-        g_free (item_edit->clipboard);
-        item_edit->clipboard = NULL;
-    }
-
-    return TRUE;
-}
-
-
-void
-gnc_item_edit_selection_get (GncItemEdit      *item_edit,
-                             GtkSelectionData *selection_data,
-                             guint             info,
-                             guint             time)
-{
-    GtkEditable *editable;
-
-    gint start_pos;
-    gint end_pos;
-
-    gchar *str;
-    gint length;
-
-    g_return_if_fail(item_edit != NULL);
-    g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
-
-    editable = GTK_EDITABLE (item_edit->editor);
-
-    if (selection_data->selection == GDK_SELECTION_PRIMARY)
-    {
-        gtk_editable_get_selection_bounds (editable, &start_pos, &end_pos);
-
-        str = gtk_editable_get_chars(editable, start_pos, end_pos);
-    }
-    else /* CLIPBOARD */
-    {
-        str = item_edit->clipboard;
-    }
-
-    if (str == NULL)
-        return;
-
-    length = strlen(str);
-    gtk_selection_data_set_text(selection_data, str, length);
-
-    if (str != item_edit->clipboard)
-        g_free(str);
-}
-
-
-void
-gnc_item_edit_selection_received (GncItemEdit       *item_edit,
-                                  GtkSelectionData  *selection_data,
-                                  guint              time)
-{
-    GtkEditable *editable;
-    gboolean reselect;
-    gint old_pos;
-    gint tmp_pos;
-    gint start_sel, end_sel;
-    enum {INVALID, CTEXT} type;
-
-    g_return_if_fail(item_edit != NULL);
-    g_return_if_fail(GNC_IS_ITEM_EDIT(item_edit));
-
-    editable = GTK_EDITABLE(item_edit->editor);
-
-    /* @fixme: this should implement the fallback logic from
-     * gtkclipboard.c:request_text_received_func.  It'd be nice to have a
-     * good way to test the various request types. :( --jsled **/
-
-    if (selection_data->type == GDK_TARGET_STRING
-            || selection_data->type == gdk_atom_intern("UTF8_STRING", FALSE)
-            || selection_data->type == gdk_atom_intern("COMPOUND_TEXT", FALSE)
-            || selection_data->type == gdk_atom_intern("TEXT", FALSE))
-    {
-        type = CTEXT;
-    }
-    else
-    {
-        type = INVALID;
-    }
-
-    if (type == INVALID || selection_data->length < 0)
-    {
-        /* avoid infinite loop */
-        if (selection_data->target != GDK_TARGET_STRING)
-        {
-            gtk_selection_convert(GTK_WIDGET(item_edit->sheet),
-                                  selection_data->selection,
-                                  GDK_TARGET_STRING, time);
-        }
-        return;
-    }
-
-    reselect = FALSE;
-
-    if (gtk_editable_get_selection_bounds(editable, &start_sel, &end_sel)
-            && (!item_edit->has_selection
-                || selection_data->selection == clipboard_atom))
-    {
-        reselect = TRUE;
-        gtk_editable_delete_text(editable, start_sel, end_sel);
-    }
-
-    tmp_pos = old_pos = gtk_editable_get_position (editable);
-
-    {
-        guchar *sel = gtk_selection_data_get_text(selection_data);
-
-        if (sel)
-        {
-            gtk_editable_insert_text(editable,
-                                     (gchar *)sel,
-                                     strlen((char *)sel),
-                                     &tmp_pos);
-            gtk_editable_set_position(editable, tmp_pos);
-            g_free(sel);
-        }
-    }
-
-    if (!reselect)
-        return;
-
-    gtk_editable_select_region(editable, old_pos, gtk_editable_get_position (editable));
-}
-
-

Modified: gnucash/trunk/src/register/register-gnome/gnucash-item-edit.h
===================================================================
--- gnucash/trunk/src/register/register-gnome/gnucash-item-edit.h	2012-01-30 00:28:06 UTC (rev 21917)
+++ gnucash/trunk/src/register/register-gnome/gnucash-item-edit.h	2012-01-30 01:54:01 UTC (rev 21918)
@@ -75,8 +75,6 @@
     /* The editor whose status we reflect on the sheet */
     GtkWidget *editor;
 
-    gchar *clipboard;
-
     gboolean has_selection;
 
     gboolean is_popup;
@@ -147,24 +145,11 @@
 
 void gnc_item_edit_cut_clipboard (GncItemEdit *item_edit, guint32 time);
 void gnc_item_edit_copy_clipboard (GncItemEdit *item_edit, guint32 time);
-void gnc_item_edit_paste_clipboard (GncItemEdit *item_edit, guint32 time);
-void gnc_item_edit_paste_primary (GncItemEdit *item_edit, guint32 time);
+void gnc_item_edit_paste_selection (GncItemEdit *item_edit, GdkAtom selection,
+				    guint32 time);
 
 void gnc_item_edit_set_has_selection (GncItemEdit *item_edit, gboolean has_selection);
 gboolean gnc_item_edit_get_has_selection (GncItemEdit *item_edit);
-
-gboolean gnc_item_edit_selection_clear (GncItemEdit       *item_edit,
-                                        GdkEventSelection *event);
-
-void gnc_item_edit_selection_get (GncItemEdit         *item_edit,
-                                  GtkSelectionData *selection_data,
-                                  guint             info,
-                                  guint             time);
-
-void gnc_item_edit_selection_received (GncItemEdit       *item_edit,
-                                       GtkSelectionData  *selection_data,
-                                       guint              time);
-
 void gnc_item_edit_focus_in (GncItemEdit *item_edit);
 void gnc_item_edit_focus_out (GncItemEdit *item_edit);
 

Modified: gnucash/trunk/src/register/register-gnome/gnucash-sheet.c
===================================================================
--- gnucash/trunk/src/register/register-gnome/gnucash-sheet.c	2012-01-30 00:28:06 UTC (rev 21917)
+++ gnucash/trunk/src/register/register-gnome/gnucash-sheet.c	2012-01-30 01:54:01 UTC (rev 21918)
@@ -29,6 +29,8 @@
  */
 
 #include "config.h"
+#include <glib.h>
+#include <glib/gprintf.h>
 
 #include "gnucash-sheet.h"
 
@@ -1406,8 +1408,9 @@
     case 2:
         if (event->type != GDK_BUTTON_PRESS)
             return FALSE;
-        gnc_item_edit_paste_primary(GNC_ITEM_EDIT(sheet->item_editor),
-                                    event->time);
+        gnc_item_edit_paste_selection (GNC_ITEM_EDIT(sheet->item_editor),
+				       GDK_SELECTION_PRIMARY,
+				       event->time);
         return TRUE;
     case 3:
         do_popup = (sheet->popup != NULL);
@@ -1445,8 +1448,8 @@
     {
         gtk_grab_add(widget);
         sheet->grabbed = TRUE;
-        gnc_item_edit_set_has_selection
-        (GNC_ITEM_EDIT(sheet->item_editor), TRUE);
+        gnc_item_edit_set_has_selection (GNC_ITEM_EDIT(sheet->item_editor),
+					 TRUE);
     }
 
     if (virt_loc_equal (new_virt_loc, cur_virt_loc) && sheet->editing)
@@ -1549,7 +1552,8 @@
     sheet = GNUCASH_SHEET(reg->sheet);
     item_edit = GNC_ITEM_EDIT(sheet->item_editor);
 
-    gnc_item_edit_paste_clipboard(item_edit, GDK_CURRENT_TIME);
+    gnc_item_edit_paste_selection (item_edit, GDK_SELECTION_CLIPBOARD,
+				   GDK_CURRENT_TIME);
 }
 
 static void
@@ -1610,14 +1614,16 @@
     case GDK_v:
         if (event->state & GDK_CONTROL_MASK)
         {
-            gnc_item_edit_paste_clipboard(item_edit, time);
+            gnc_item_edit_paste_selection (item_edit, GDK_SELECTION_CLIPBOARD,
+					   time);
             handled = TRUE;
         }
         break;
     case GDK_Insert:
         if (event->state & GDK_SHIFT_MASK)
         {
-            gnc_item_edit_paste_clipboard(item_edit, time);
+            gnc_item_edit_paste_selection (item_edit, GDK_SELECTION_CLIPBOARD,
+					   time);
             handled = TRUE;
         }
         else if (event->state & GDK_CONTROL_MASK)
@@ -2544,54 +2550,7 @@
     gnucash_sheet_activate_cursor_cell (sheet, TRUE);
 }
 
-static gboolean
-gnucash_sheet_selection_clear (GtkWidget          *widget,
-                               GdkEventSelection  *event)
-{
-    GnucashSheet *sheet;
-
-    g_return_val_if_fail(widget != NULL, FALSE);
-    g_return_val_if_fail(GNUCASH_IS_SHEET(widget), FALSE);
-
-    sheet = GNUCASH_SHEET(widget);
-
-    return gnc_item_edit_selection_clear(GNC_ITEM_EDIT(sheet->item_editor), event);
-}
-
 static void
-gnucash_sheet_selection_get (GtkWidget         *widget,
-                             GtkSelectionData  *selection_data,
-                             guint              info,
-                             guint              time)
-{
-    GnucashSheet *sheet;
-
-    g_return_if_fail(widget != NULL);
-    g_return_if_fail(GNUCASH_IS_SHEET(widget));
-
-    sheet = GNUCASH_SHEET(widget);
-
-    gnc_item_edit_selection_get(GNC_ITEM_EDIT(sheet->item_editor),
-                                selection_data, info, time);
-}
-
-static void
-gnucash_sheet_selection_received (GtkWidget          *widget,
-                                  GtkSelectionData   *selection_data,
-                                  guint               time)
-{
-    GnucashSheet *sheet;
-
-    g_return_if_fail(widget != NULL);
-    g_return_if_fail(GNUCASH_IS_SHEET(widget));
-
-    sheet = GNUCASH_SHEET(widget);
-
-    gnc_item_edit_selection_received(GNC_ITEM_EDIT(sheet->item_editor),
-                                     selection_data, time);
-}
-
-static void
 gnucash_sheet_realize_entry (GnucashSheet *sheet, GtkWidget *entry)
 {
     GValue gval = {0,};
@@ -2738,9 +2697,6 @@
     widget_class->motion_notify_event = gnucash_motion_event;
     widget_class->scroll_event = gnucash_scroll_event;
 
-    widget_class->selection_clear_event = gnucash_sheet_selection_clear;
-    widget_class->selection_received = gnucash_sheet_selection_received;
-    widget_class->selection_get = gnucash_sheet_selection_get;
 }
 
 



More information about the gnucash-changes mailing list