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]