Force a GridCellEditor to accept value without return key

In a hex editor where the user can edit a two char representation of a
byte, I'd like the grid to advance to the next byte after the user
types the 2nd char so the user doesn't also have to press return or
tab to go to the next cell.

What I really want to do is tell the PyGridCellEditor that it's
finished from within the TextCtrl.

There's 3 attempts within the source fragment below, all not working.

1) I thought about the TextCtrl's EmulateKeyPress, but creating a
wx.KeyEvent doesn't seem to do anything. It seems like I must not be
creating the event properly.

2) So, I tried capturing a KEY_DOWN event and cloning it, but
EmulateKeyPress responds with:

TypeError: argument number 2: a 'wxKeyEvent *' is expected,
'PySwigObject(_p_wxEvent)' is received

3) Tried calling the PyGridCellEditor's HandleReturn method, but that
doesn't do anything.

Any ideas? It doesn't look like calling PyGridCellEditor.EndEdit
directly is an option -- somehow I need to find a way to trigger that
method to be called.

Thanks,

Rob

···

-----

class HexTextCtrl(wx.TextCtrl):
    def __init__(self,parent,id,evtHandler=None,editor=None):
        wx.TextCtrl.__init__(self,parent, id, validator = HexValidator(),
                             style=wx.TE_PROCESS_TAB|wx.TE_PROCESS_ENTER)
        self.SetInsertionPoint(0)
        self.SetMaxLength(2)
        self.Bind(wx.EVT_TEXT, self.OnText)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)

        self.retevent=None
        self.evtHandler=evtHandler
        if evtHandler:
            print "event handler=%s" % evtHandler
            self.PushEventHandler(evtHandler)
        self.editor=editor

    def OnKeyDown(self, evt):
        print "HexTextCtrl: key down before evt=%s" % evt.GetKeyCode()
        self.retevent=evt.Clone()
        self.retevent.m_keyCode=wx.WXK_RETURN
        print "HexTextCtrl: key down after evt=%s" % evt.GetKeyCode()
        evt.Skip()

    def OnText(self, evt):
        print "HexTextCtrl: evt=%s" % evt.GetString()
        if len(evt.GetString())>=2 and self.retevent!=None:
            print "HexTextCtrl: simulate a return keypress here"
            evt2=wx.KeyEvent()
            evt2.m_keyCode=wx.WXK_RETURN
            self.EmulateKeyPress(evt2)
            wx.CallAfter(self.editor.HandleReturn,evt2)

class HexCellEditor(Grid.PyGridCellEditor):
    def Create(self, parent, id, evtHandler):
        self._tc = HexTextCtrl(parent, id, evtHandler, self)
        self.SetControl(self._tc)

Rob McMullen wrote:

In a hex editor where the user can edit a two char representation of a
byte, I'd like the grid to advance to the next byte after the user
types the 2nd char so the user doesn't also have to press return or
tab to go to the next cell.

What I really want to do is tell the PyGridCellEditor that it's
finished from within the TextCtrl.

You can do it by telling the grid that you are finished eidting. You can also move to the next cell and start the editor there. Something like this:

  grid.DisableCellEditControl()
  grid.MoveCursorRight(False)
  grid.EnableCellEditControl()

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Thanks, Robin, I knew I was overthinking the problem somehow. That
works. For posterity, here's the rewritten HexTextCtrl.

Because the same HexTextCtrl is reused within the grid, you have to
use a flag to figure out when the ctrl has moved to a new cell. The
constructor also needs a reference to the grid.

class HexTextCtrl(wx.TextCtrl):
    def __init__(self,parent,id,parentgrid):
        wx.TextCtrl.__init__(self,parent, id, validator = HexValidator(),
                             style=wx.TE_PROCESS_TAB|wx.TE_PROCESS_ENTER)
        self.SetInsertionPoint(0)
        self.SetMaxLength(2)
        self.Bind(wx.EVT_TEXT, self.OnText)
        self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
        self.parentgrid=parentgrid
        self.userpressed=False

    def OnKeyDown(self, evt):
        self.userpressed=True
        evt.Skip()

    def OnText(self, evt):
        if len(evt.GetString())>=2 and self.userpressed:
            self.userpressed=False
            wx.CallAfter(self.parentgrid.advanceCursor)

where parentgrid.advanceCursor is the Disable/Move/Enable snippet from above.

Rob

···

On 10/16/06, Robin Dunn <robin@alldunn.com> wrote:

You can do it by telling the grid that you are finished eidting. You
can also move to the next cell and start the editor there. Something
like this:

        grid.DisableCellEditControl()
        grid.MoveCursorRight(False)
        grid.EnableCellEditControl()