> Date: Tue, 06 Oct 2009 15:11:06 +0200 > From: Geoff Bache <geoff.ba...@jeppesen.com> > Subject: [pygtk] More on cut+paste accelerators > To: pygtk@daa.com.au > Message-ID: <4acb41ea.9010...@jeppesen.com> > Content-Type: text/plain; charset=ISO-8859-1; format=flowed > > Hi all, > > I'm also having some issues with the default cut and paste which is > that > my application can also cut and paste files. These file actions have > naturally been assigned the accelerators Ctrl+X, Ctrl+V etc but this > naturally means that currently these accelerators don't work for > selected text in the TextView widgets. What I'd like is for Ctrl+C to > copy a file if a file is selected and copy some text (as the > default) if > some text is selected. > > What's the easiest or "normal" way of fixing something like this?
Hi Geoff, I've also come up against this problem with glade. I couldn't find a canonical way to fix it. My approach has been to create custom accelerator handlers which return False if a global copy/paste is not appropiate for the focused widget, allowing the keypress event to percolate to the TextView widget and trigger its keybindings. I've included the relevant code below. The wrinkle is that, as glade is no longer handling their bindings, the glade-created copy/paste menu items no longer show "CTRL-C"/"CTRL- V". So I kludge it by giving them fake accelerators. There may well be a cleaner way to do this. best, Richard. def setup_global_copy_paste_accelerators(accel_group, fake_accel_group, wTree, action_factory): # Here's the problem. GTK AccelGroups key-bindings trump # widget key-bindings, and the AccelGroup handlers for the accelerators # added by glade always accept an invocation. Therefore # adding, e.g. CTRL-V, will always override the CTRL-V binding # for the TextView object which is used to edit the outcomes. # # So, we install our custom AccelGroup handlers, which test to # see if the GlobalClipboardAction in question is valid in the # given context. If not, the accelerator invocation will # be rejected and the widget key-bindings tried. paste_action=action_factory.make(actions.GlobalPaste) copy_action=action_factory.make(actions.GlobalCopy) def _dispatch_paste(accel_group, toplevel, keyval, modifier): if paste_action.is_valid(): paste_action.execute() return True # This accel group binding handled return False def _dispatch_copy(accel_group, toplevel, keyval, modifier): if copy_action.is_valid(): copy_action.execute() return True # This accel group binding handled return False # TODO: Lookup the bindings for these generic operations? accel_group.connect_group(gtk.keysyms.V, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE, _dispatch_paste) accel_group.connect_group(gtk.keysyms.C, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE, _dispatch_copy) # Make these bindings appear in the menu bar menu items. paste_item=wTree.get_widget("paste") paste_item.add_accelerator('activate', fake_accel_group, gtk.keysyms.V, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) copy_item=wTree.get_widget("copy") copy_item.add_accelerator('activate', fake_accel_group, gtk.keysyms.C, gtk.gdk.CONTROL_MASK, gtk.ACCEL_VISIBLE) # HACK: This accel_group is never added to any toplevel. Why? We # want some way to show an accelerator label in a menu item # without actually creating a key-binding. We must also keep it # alive until process termination; adding an accelerator is # insufficient. fake_global_accel_group = gtk.AccelGroup() setup_global_copy_paste_accelerators(global_accel_group, fake_global_accel_group, wTree, action_factory) > Regards, > Geoff _______________________________________________ pygtk mailing list pygtk@daa.com.au http://www.daa.com.au/mailman/listinfo/pygtk Read the PyGTK FAQ: http://faq.pygtk.org/