
import string

import  wx
import  wx.grid as gridlib

diz = {'0':'0 open','1':'1 suspended','2':'2 closed'}

class CustomCellChoiceEditor(wx.grid.PyGridCellEditor):
    def __init__(self, varDefDict, editable):
        wx.grid.PyGridCellEditor.__init__(self)
        self._varDefDict = varDefDict
        self._editable = editable        

    def Create(self, parent, id, evtHandler):
        """
        Called to create the control, which must derive from wxControl.
        """
        ls=self._varDefDict.keys()
        ls.sort()
        self.parent = parent
        self.startValue = None 
        self._tc = wx.Choice(parent, id, choices = [self._varDefDict[el] for el in ls]) #self._varDefDict.values())
        self._tc.chosen = False
        self._tc.Bind(wx.EVT_CHOICE, self.OnChoose)
##        self._tc.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeave)
##        self._tc.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
        if len(self._varDefDict.keys()):
            self._tc.SetSelection(0)
        self.SetControl(self._tc)
        if evtHandler:
            self._tc.PushEventHandler(evtHandler)

    def OnKillFocus(self,evt):
        print 'OnKillFocus',self._tc.IsExposed()
        evt.Skip()

    def OnLeave(self,evt):
        if self.startValue==str(self.grid.GetTable().GetValue(self.row, self.col)) and not self._tc.chosen:
            self.parent.SetFocus()
        evt.Skip()

    def OnChoose(self,evt):
        self._tc.chosen = True
        self.parent.SetFocus()
        evt.Skip()

    def SetSize(self, rect):
        """
        Called to position/size the edit control within the cell rectangle.
        If you don't fill the cell (the rect) then be sure to override
        PaintBackground and do something meaningful there.
        """
        self._tc.SetDimensions(rect.x, rect.y, rect.width+2, rect.height+2,
                               wx.SIZE_ALLOW_MINUS_ONE)


    def BeginEdit(self, row, col, grid):
        """
        Fetch the value from the table and prepare the edit control
        to begin editing.  Set the focus to the edit control.
        """
        self.startValue = str(grid.GetTable().GetValue(row, col))
        self.row = row
        self.col = col
        self.grid = grid
        self._tc.SetStringSelection(self._varDefDict[self.startValue])
        self._tc.SetFocus()        


    def EndEdit(self, row, col, grid, oldVal):
        """
        Complete the editing of the current cell. Returns true if the value
        has changed.  If necessary, the control may be destroyed.
        """        
        changed = False
        self.chosen = False

        pclDescr = self._tc.GetStringSelection()
        # extract pcl
        pcl = pclDescr[0]
        if pcl != oldVal:
            return pcl
        else:
            return None


    def ApplyEdit(self, row, col, grid):
        """
        This function should save the value of the control into the
        grid or grid table. It is called only after EndEdit() returns
        a non-None value.
        *Must Override*
        """        
        pclDescr = self._tc.GetStringSelection()
        pcl = pclDescr.split(' ')[0]
        grid.GetTable().SetValue(row, col, str(pcl)) # update the table        
        self.startValue = ''


    def Reset(self):
        """
        Reset the value in the control back to its starting value.
        """
        self._tc.SetStringSelection(self._varDefDict[self.startValue])


    def Clone(self):
        """
        Create a new object which is the copy of this one
        """
        return CustomCellChoiceEditor(self._varDefDict, self._editable)





#---------------------------------------------------------------------------
class GridEditorTest(gridlib.Grid):
    def __init__(self, parent, log):
        gridlib.Grid.__init__(self, parent, -1)
        self.log = log

        self.CreateGrid(10, 6)

        # Somebody changed the grid so the type registry takes precedence
        # over the default attribute set for editors and renderers, so we
        # have to set null handlers for the type registry before the
        # default editor will get used otherwise...
        #self.RegisterDataType(wxGRID_VALUE_STRING, None, None)
        #self.SetDefaultEditor(MyCellEditor(self.log))

        # Or we could just do it like this:
        #self.RegisterDataType(wx.GRID_VALUE_STRING,
        #                      wx.GridCellStringRenderer(),
        #                      MyCellEditor(self.log))
        #                       )

        # but for this example, we'll just set the custom editor on one cell
        self.SetCellEditor(1, 0, CustomCellChoiceEditor(diz,True))
        self.SetCellValue(1, 0, "0")

        # and on a column
        attr = gridlib.GridCellAttr()
##        attr.SetEditor(MyCellEditor(self.log))
        attr.SetEditor(CustomCellChoiceEditor(diz,True))
        self.SetColAttr(3, attr)
        self.SetCellValue(1, 3, "0")
##        self.SetCellValue(1, 2, "or any in this column")

        self.SetColSize(0, 150)
        self.SetColSize(1, 150)
        self.SetColSize(2, 150)


#---------------------------------------------------------------------------

class TestFrame(wx.Frame):
    def __init__(self, parent, log):
        wx.Frame.__init__(self, parent, -1, "Custom Grid Cell Editor Test",
                         size=(640,480))
        grid = GridEditorTest(self, log)

#---------------------------------------------------------------------------

if __name__ == '__main__':
    import sys
    app = wx.PySimpleApp()
    frame = TestFrame(None, sys.stdout)
    frame.Show(True)
    app.MainLoop()


