Hi All,
           I hope this is an appropriate place to share this.  I've been
wanting to have a DateTextBox as part of a grid column for a long time,
to simplify bulk data editing where dates are involved. 

I have managed to hack something together which does the job, I must
warn you that I do not have a lot of programming experience (thank you
to those out there whose code I poached in trying to put this
together).  If there is another way which I missed when trying to
resolve this, I would be interested in knowing.  Otherwise, here is some
code:

# gGridEditors.py
import wx
import dabo
import datetime
import time
import locale
import sys
dabo.ui.loadUI("wx")
#Todo: I still haven't got the Tool Tip showing for the control.

# I'm unsure of how to import this as dabo.ui.dDateTextBox.CalPanel is
not available.  Coppied and Pasted here, with some minor changes:
class CalPanel(dabo.ui.dPanel):
    def __init__(self, parent, pos=None, dt=None, ctrl=None ):
        if dt is None:
            self.date = datetime.date.today()
        else:
            self.date = dt
        self.ctrl = ctrl
        super(CalPanel, self).__init__(parent, pos=pos)
       
   
    def afterInit(self):
        """ Create the calendar control, and resize this panel
        to the calendar's size.
        """
        self.cal = dabo.ui.dCalendar(self, Position=(5, 5))
        self.cal.Date = self.date
        self.cal.bindEvent(dabo.dEvents.Hit, self.onCalSelection)
        self.cal.bindEvent(dabo.dEvents.KeyChar, self.onCalKey)
        wd, ht = self.cal.Size
        self.Size = (wd+10, ht+10)
        self.BackColor = (192, 192, 0)
        self.cal.Visible = True
       
       
    def onCalSelection(self, evt):
        if self.ctrl is not None:
            self.ctrl.setDate(self.cal.Date)
            self.ctrl.setFocus()
        self.Visible = False
   
   
    def onCalKey(self, evt):
        if evt.keyCode == wx.WXK_ESCAPE:
            evt.Continue = False
            if self.ctrl is not None:
                self.ctrl.setFocus()
            self.Visible = False



class GridDateTextBox(dabo.ui.dDateTextBox):
        def showCalendar(self):
        if self.ReadOnly:
            # ignore
            return
        availHt = self.Parent.Parent.Bottom - self.Bottom
        try:
            self.calPanel.cal.Date = self.Value
        except:
            self.calPanel = CalPanel(self.Parent, dt=self.Value, ctrl=self)
        cp = self.calPanel
        cp.Position = (self.Left, self.Bottom)
        if self.Bottom + cp.Height > self.Parent.Parent.Bottom:
            # Maybe we should move it above
            if cp.Height <= self.Top:
                cp.Bottom = self.Top
            else:
                # We can't fit it cleanly, so try to fit as much as possible
                cp.Top = max(0, (self.Parent.Parent.Height - cp.Height) )
        if self.Left + cp.Width > self.Parent.Parent.Right:
            # Try moving it to the left
            cp.Left = max(0, (self.Parent.Parent.Width - cp.Width) )
        cp.Visible = True
        cp.bringToFront()
        # Commented out so that the grid control will receive the update
from the Calendar
        #cp.setFocus()

class GridDateEditor(wx.grid.PyGridCellEditor):
    def __init__(self, *args, **kwargs):
        dabo.infoLog.write("GridDateEditor: Init ")
        dabo.infoLog.write(str(args))
        dabo.infoLog.write(str(kwargs))

                super(GridDateEditor, self).__init__(*args, **kwargs)

    def Create(self, parent, id, evtHandler, *args, **kwargs):
        dabo.infoLog.write("GridDateEditor: Create")
        dabo.infoLog.write(str(args))
        dabo.infoLog.write(str(kwargs))
        control = GridDateTextBox(parent=parent, id=id)
        self.control = control

        self.SetControl(self.control)
        if evtHandler:
            self.control.PushEventHandler(evtHandler)
#         super(GridDateEditor, self).Create(parent, id, evtHandler)

    def Clone(self):
        return self.__class__()

    def SetParameters(self, paramStr):
        dabo.infoLog.write("GridDateEditor: SetParameters: %s" % paramStr)
        #self.control.Choices = eval(paramStr)

    def BeginEdit(self, row, col, grid):
        dabo.infoLog.write("GridDateEditor: BeginEdit (%d,%d)" % (row, col))
        self.value = grid.GetTable().GetValue(row, col)
       
               
#datetime.datetime.fromtimestamp(time.mktime(time.strptime(mytime,
time_format)))
               
        try:
                try:
                        timeValue = time.strptime(self.value,
self.DateFormat)
                    except ValueError:
                            dabo.infoLog.write("GridDateEditor: Control
Text does not Match Date Format")
                            #Take our best Guess
                            dabo.infoLog.write("GridDateEditor: Guessing
Time Format")
                            try:
                                    timeValue =
self.control.strToDate(self.value).timetuple()
                            except:
                                    # Still No Luck, default to today
                                    dabo.infoLog.write("GridDateEditor:
%s" %(str(sys.exc_info()[0])))
                                    dabo.infoLog.write("GridDateEditor:
Setting Unknown Control Value to Today")
                                    timeValue =
datetime.date.today().timetuple()
                           
            dateValue = datetime.date(timeValue[0], timeValue[1],
timeValue[2])
            self.control.Value = dateValue

        except ValueError, vError:
            dabo.infoLog.write("GridDateEditor: ValueError in BeginEdit:
" + str(vError))
           
        self.control.SetFocus()

    def EndEdit(self, row, col, grid):
        changed = False
        v = self.control.Value.strftime(self.DateFormat)
       
        if v != self.value:
            changed = True
        if changed:
            grid.GetTable().SetValue(row, col, v)
            # I don't think the DateTextBox handles an empty value?
        #self.value = ""
        #self.control.Value = self.value
        return changed

    def Reset(self):
        self.control.Value = self.value

#     def SetSize(self, rectorig):
#         dabo.infoLog.write("GridDateEditor: SetSize: %s" % rectorig)
#         dabo.infoLog.write("GridDateEditor: type of rectorig: %s" %
type(rectorig))
# #         rect = wx.Rect(rectorig)
# #         dabo.infoLog.write("GridDateEditor RECT: %s" % rect)
#         super(GridDateEditor, self).SetSize(rectorig)

    def IsAcceptedKey(self, key):
        return true

        #Properties
    def _getDateFormat(self):
                # Get the date format - Make it up if none is given
using the system locale
                if hasattr(self, "_dateFormat"):
                return self._dateFormat
        else:
                        #dateFormat = locale.nl_langinfo(locale.D_FMT) #
%d/%m/%y
                        #pos = dateFormat.find("%")+1
                        #date1 = dateFormat[pos]
                        #pos = dateFormat.find("%", pos)+1
                        #date2 = dateFormat[pos]
                        #pos = dateFormat.find("%", pos)+1
                        #date3 = dateFormat[pos]
                        #return "%" + date1 + "-%" + date2 + "-%" + date3
                        return "%Y-%m-%d"
       
    def _setDateFormat(self, val):
            #Todo: Check format is valid
        self._dateFormat = val
    DateFormat = property(_getDateFormat, _setDateFormat, None,
            "Get or Set the Date Format String for this Control.")




class _dGrid_test(dabo.ui.dGrid):
    def initProperties(self):
        #I've just randomly placed some date strings in the below
dataset coppied from daboDemo
        #  My intention here is to check the durability of the control.
        self.DataSet = [
                {"name" : "Ed Leafe", "age" : 49, "coder" :  True,
"color": "2008-10-10"},
                {"name" : "Paul McNett", "age" : 37, "coder" :  True,
"color": "11-10-2008"},
                {"name" : "Ted Roche", "age" : 48, "coder" :  True,
"color": "2008-10-12"},
                {"name" : "Derek Jeter", "age": 32 , "coder" :  False,
"color": "white"},
                {"name" : "Halle Berry", "age" : 38, "coder" :  False,
"color": "orange"},
                {"name" : "Steve Wozniak", "age" : 56, "coder" :  True,
"color": "yellow"},
                {"name" : "LeBron James", "age" : 22, "coder" :  False,
"color": "gold"},
                {"name" : "Madeline Albright", "age" : 69, "coder" : 
False, "color": "red"}]
        self.Width = 360
        self.Height = 150
        self.Editable = True
        #self.Sortable = False
        #self.Searchable = False


    def afterInit(self):
        self.super()

        self.addColumn(Name="Geek", DataField="coder", Caption="Geek?",
                Order=10, DataType="bool", Width=60, Sortable=False,
                Searchable=False, Editable=True, HeaderFontBold=False)

        col = dabo.ui.dColumn(self, Name="Person", Order=20,
DataField="name",
                DataType="string", Width=200, Caption="Celebrity Name",
                Sortable=True, Searchable=True, Editable=True, Expand=False)
        self.addColumn(col)

        col.HeaderFontItalic = True
        col.HeaderBackColor = "orange"
        col.HeaderVerticalAlignment = "Top"
        col.HeaderHorizontalAlignment = "Left"

        self.addColumn(Name="Age", Order=30, DataField="age",
                DataType="integer", Width=40, Caption="Age",
                Sortable=True, Searchable=True, Editable=True)

        col = dabo.ui.dColumn(self, Name="Color", Order=40,
DataField="color",
                DataType="string", Width=40, Caption="Favorite Color",
                Sortable=True, Searchable=True, Editable=True, Expand=False)
        self.addColumn(col)

        #col.ListEditorChoices = dabo.dColors.colors
        #col.CustomEditorClass = gGridEditors.GridListEditor
        col.CustomEditorClass = GridDateEditor

        col.HeaderVerticalAlignment = "Bottom"
        col.HeaderHorizontalAlignment = "Right"
        col.HeaderForeColor = "brown"

        self.RowLabels = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
        #self.ShowRowLabels = True

if __name__ == '__main__':
    class TestForm(dabo.ui.dForm):
        def afterInit(self):
            self.BackColor = "khaki"
            g = self.grid = _dGrid_test(self, RegID="sampleGrid")
            self.Sizer.append(g, 1, "x", border=40, borderSides="all")
            self.Sizer.appendSpacer(10)
            gsz = dabo.ui.dGridSizer(HGap=50)

            chk = dabo.ui.dCheckBox(self, Caption="Edit Table",
RegID="geekEdit",
                    DataSource="sampleGrid", DataField="Editable")
            chk.refresh()
            gsz.append(chk, row=0, col=0)

            chk = dabo.ui.dCheckBox(self, Caption="Show Row Labels",
                    RegID="showRowLabels", DataSource="sampleGrid",
                    DataField="ShowRowLabels")
            gsz.append(chk, row=1, col=0)
            chk.refresh()

            chk = dabo.ui.dCheckBox(self, Caption="Allow Multiple
Selection",
                    RegID="multiSelect", DataSource="sampleGrid",
                    DataField="MultipleSelection")
            chk.refresh()
            gsz.append(chk, row=2, col=0)

            radSelect = dabo.ui.dRadioList(self, Choices=["Row", "Col",
"Cell"],
                    ValueMode="string", Caption="Sel Mode",
BackColor=self.BackColor,
                    DataSource="sampleGrid", DataField="SelectionMode",
RegID="radSelect")
            radSelect.refresh()
            gsz.append(radSelect, row=0, col=1, rowSpan=3)

            self.Sizer.append(gsz, halign="Center", border=10)
            gsz.setColExpand(True, 1)
            self.layout()

            self.fitToSizer(20,20)


    app = dabo.dApp(MainFormClass=TestForm)
    app.setup()
    app.MainForm.radSelect.setFocus()
    app.start()


_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users
Searchable Archives: http://leafe.com/archives/search/dabo-users
This message: http://leafe.com/archives/byMID/dabo-users/[EMAIL PROTECTED]

Reply via email to