Ticket #1138: gGridEditors.2.py

File gGridEditors.2.py, 10.6 kB (added by gary, 5 months ago)

Updated to request user response for update if invalid date value exists in field

Line 
1 """Grid Editors
2
3 20080131 - GNT
4 """
5
6 import wx
7 import dabo
8 import datetime
9 import time
10 import locale
11 import sys
12 dabo.ui.loadUI("wx")
13 #Todo: I still haven't got the Tool Tip showing for the control.
14
15 # I'm unsure of how to import this as dabo.ui.dDateTextBox.CalPanel is not available.  Coppied and Pasted here, with some minor changes:
16 class CalPanel(dabo.ui.dPanel):
17     def __init__(self, parent, pos=None, dt=None, ctrl=None ):
18         if dt is None:
19             self.date = datetime.date.today()
20         else:
21             self.date = dt
22         self.ctrl = ctrl
23         super(CalPanel, self).__init__(parent, pos=pos)
24        
25    
26     def afterInit(self):
27         """ Create the calendar control, and resize this panel
28         to the calendar's size.
29         """
30         self.cal = dabo.ui.dCalendar(self, Position=(5, 5))
31         self.cal.Date = self.date
32         self.cal.bindEvent(dabo.dEvents.Hit, self.onCalSelection)
33         self.cal.bindEvent(dabo.dEvents.KeyChar, self.onCalKey)
34         wd, ht = self.cal.Size
35         self.Size = (wd+10, ht+10)
36         self.BackColor = (192, 192, 0)
37         self.cal.Visible = True
38        
39        
40     def onCalSelection(self, evt):
41         if self.ctrl is not None:
42             self.ctrl.setDate(self.cal.Date)
43             self.ctrl.setFocus()
44         self.Visible = False
45    
46    
47     def onCalKey(self, evt):
48         if evt.keyCode == wx.WXK_ESCAPE:
49             evt.Continue = False
50             if self.ctrl is not None:
51                 self.ctrl.setFocus()
52             self.Visible = False
53
54
55
56 class GridDateTextBox(dabo.ui.dDateTextBox):
57         def showCalendar(self):
58         if self.ReadOnly:
59             # ignore
60             return
61         availHt = self.Parent.Parent.Bottom - self.Bottom
62         try:
63             self.calPanel.cal.Date = self.Value
64         except:
65             self.calPanel = CalPanel(self.Parent, dt=self.Value, ctrl=self)
66         cp = self.calPanel
67         cp.Position = (self.Left, self.Bottom)
68         if self.Bottom + cp.Height > self.Parent.Parent.Bottom:
69             # Maybe we should move it above
70             if cp.Height <= self.Top:
71                 cp.Bottom = self.Top
72             else:
73                 # We can't fit it cleanly, so try to fit as much as possible
74                 cp.Top = max(0, (self.Parent.Parent.Height - cp.Height) )
75         if self.Left + cp.Width > self.Parent.Parent.Right:
76             # Try moving it to the left
77             cp.Left = max(0, (self.Parent.Parent.Width - cp.Width) )
78         cp.Visible = True
79         cp.bringToFront()
80         # Commented out so that the grid control will receive the update from the Calendar
81         # For some reaons the application crashes when the Cal losses focus and the focus
82         #  doesn't return to the control.  I might need to execute this line but pass to the
83         #  control the "End Edit" function from the GridDataEditor.
84         #  Now it appears this doesn't work at all? Correction:  Seems to die when editing
85         #  a bizobj DataSource?  It turns out the crash is just once the control is selected...
86         # Crash is a segfault within wx libraries
87         #cp.setFocus()
88
89 class GridDateEditor(wx.grid.PyGridCellEditor):
90     def __init__(self, *args, **kwargs):
91         dabo.infoLog.write("GridDateEditor: Init ")
92         dabo.infoLog.write(str(args))
93         dabo.infoLog.write(str(kwargs))
94
95                 super(GridDateEditor, self).__init__(*args, **kwargs)
96
97     def Create(self, parent, id, evtHandler, *args, **kwargs):
98         dabo.infoLog.write("GridDateEditor: Create")
99         dabo.infoLog.write(str(args))
100         dabo.infoLog.write(str(kwargs))
101         control = GridDateTextBox(parent=parent, id=id)
102         self.control = control
103
104         self.SetControl(self.control)
105         if evtHandler:
106             self.control.PushEventHandler(evtHandler)
107 #       super(GridDateEditor, self).Create(parent, id, evtHandler)
108
109     def Clone(self):
110         return self.__class__()
111
112     def SetParameters(self, paramStr):
113         dabo.infoLog.write("GridDateEditor: SetParameters: %s" % paramStr)
114         #self.control.Choices = eval(paramStr)
115
116     def BeginEdit(self, row, col, grid):
117         dabo.infoLog.write("GridDateEditor: BeginEdit (%d,%d)" % (row, col))
118         self.value = grid.GetTable().GetValue(row, col)
119        
120                 #datetime.datetime.fromtimestamp(time.mktime(time.strptime(mytime, time_format)))
121                
122         try:
123                 try:
124                         timeValue = time.strptime(self.value, self.DateFormat)
125                     except ValueError:
126                             dabo.infoLog.write("GridDateEditor: Control Text does not Match Date Format")
127                             #Take our best Guess
128                             dabo.infoLog.write("GridDateEditor: Guessing Time Format")
129                             try:
130                                     timeValue = self.control.strToDate(self.value).timetuple()
131                             except:
132                                     # Still No Luck, default to today
133                                     dabo.infoLog.write("GridDateEditor: %s" %(str(sys.exc_info()[0])))
134                                     dabo.infoLog.write("GridDateEditor: Setting Unknown Control Value to Today")
135                                     dlg = dabo.ui.areYouSure(title='Error in Existing Date Format', message='Do you want to reset this date field?'
136                                                              cancelButton=False)
137                                     if dlg:
138                                                 timeValue = datetime.date.today().timetuple()
139                            
140             dateValue = datetime.date(timeValue[0], timeValue[1], timeValue[2])
141             self.control.Value = dateValue
142
143         except ValueError, vError:
144             dabo.infoLog.write("GridDateEditor: ValueError in BeginEdit: " + str(vError))
145            
146         self.control.SetFocus()
147
148     def EndEdit(self, row, col, grid):
149             print "End Control Focus"
150         changed = False
151         v = self.control.Value.strftime(self.DateFormat)
152        
153         if v != self.value:
154             changed = True
155         if changed:
156             grid.GetTable().SetValue(row, col, v)
157             # I don't think the DateTextBox handles an empty value?
158         #self.value = ""
159         #self.control.Value = self.value
160         return changed
161
162     def Reset(self):
163         self.control.Value = self.value
164
165 #   def SetSize(self, rectorig):
166 #       dabo.infoLog.write("GridDateEditor: SetSize: %s" % rectorig)
167 #       dabo.infoLog.write("GridDateEditor: type of rectorig: %s" % type(rectorig))
168 # #         rect = wx.Rect(rectorig)
169 # #         dabo.infoLog.write("GridDateEditor RECT: %s" % rect)
170 #       super(GridDateEditor, self).SetSize(rectorig)
171
172     def IsAcceptedKey(self, key):
173         return true
174
175         #Properties
176     def _getDateFormat(self):
177                 # Get the date format - Make it up if none is given using the system locale
178                 if hasattr(self, "_dateFormat"):
179                 return self._dateFormat
180         else:
181                         #dateFormat = locale.nl_langinfo(locale.D_FMT) # %d/%m/%y
182                         #pos = dateFormat.find("%")+1
183                         #date1 = dateFormat[pos]
184                         #pos = dateFormat.find("%", pos)+1
185                         #date2 = dateFormat[pos]
186                         #pos = dateFormat.find("%", pos)+1
187                         #date3 = dateFormat[pos]
188                         #return "%" + date1 + "-%" + date2 + "-%" + date3
189                         return "%Y-%m-%d"
190        
191     def _setDateFormat(self, val):
192             #Todo: Check format is valid
193         self._dateFormat = val
194     DateFormat = property(_getDateFormat, _setDateFormat, None,
195             "Get or Set the Date Format String for this Control.")
196
197
198 #gbd info:
199 #Program received signal SIGSEGV, Segmentation fault.
200 #[Switching to Thread 0xb7c9b6c0 (LWP 6096)]
201 #---Type <return> to continue, or q <return> to quit---
202 #0xb733a91e in wxGridCellEditor::Show () from /usr/lib/libwx_gtk2u_adv-2.8.so.0
203
204
205
206
207 class _dGrid_test(dabo.ui.dGrid):
208     def initProperties(self):
209         self.DataSet = [
210                 {"name" : "Ed Leafe", "age" : 49, "coder" :  True, "color": "2008-10-10"},
211                 {"name" : "Paul McNett", "age" : 37, "coder" :  True, "color": "11-10-2008"},
212                 {"name" : "Ted Roche", "age" : 48, "coder" :  True, "color": "2008-10-12"},
213                 {"name" : "Derek Jeter", "age": 32 , "coder" :  False, "color": "white"},
214                 {"name" : "Halle Berry", "age" : 38, "coder" :  False, "color": "orange"},
215                 {"name" : "Steve Wozniak", "age" : 56, "coder" :  True, "color": "yellow"},
216                 {"name" : "LeBron James", "age" : 22, "coder" :  False, "color": "gold"},
217                 {"name" : "Madeline Albright", "age" : 69, "coder" :  False, "color": "red"}]
218         self.Width = 360
219         self.Height = 150
220         self.Editable = True
221         #self.Sortable = False
222         #self.Searchable = False
223
224
225     def afterInit(self):
226         self.super()
227
228         self.addColumn(Name="Geek", DataField="coder", Caption="Geek?",
229                 Order=10, DataType="bool", Width=60, Sortable=False,
230                 Searchable=False, Editable=True, HeaderFontBold=False)
231
232         col = dabo.ui.dColumn(self, Name="Person", Order=20, DataField="name",
233                 DataType="string", Width=200, Caption="Celebrity Name",
234                 Sortable=True, Searchable=True, Editable=True, Expand=False)
235         self.addColumn(col)
236
237         col.HeaderFontItalic = True
238         col.HeaderBackColor = "orange"
239         col.HeaderVerticalAlignment = "Top"
240         col.HeaderHorizontalAlignment = "Left"
241
242         self.addColumn(Name="Age", Order=30, DataField="age",
243                 DataType="integer", Width=40, Caption="Age",
244                 Sortable=True, Searchable=True, Editable=True)
245
246         col = dabo.ui.dColumn(self, Name="Color", Order=40, DataField="color",
247                 DataType="string", Width=40, Caption="Favorite Color",
248                 Sortable=True, Searchable=True, Editable=True, Expand=False)
249         self.addColumn(col)
250
251         #col.ListEditorChoices = dabo.dColors.colors
252         #col.CustomEditorClass = gGridEditors.GridListEditor
253         col.CustomEditorClass = GridDateEditor
254
255         col.HeaderVerticalAlignment = "Bottom"
256         col.HeaderHorizontalAlignment = "Right"
257         col.HeaderForeColor = "brown"
258
259         self.RowLabels = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
260         #self.ShowRowLabels = True
261
262 if __name__ == '__main__':
263     class TestForm(dabo.ui.dForm):
264         def afterInit(self):
265             self.BackColor = "khaki"
266             g = self.grid = _dGrid_test(self, RegID="sampleGrid")
267             self.Sizer.append(g, 1, "x", border=40, borderSides="all")
268             self.Sizer.appendSpacer(10)
269             gsz = dabo.ui.dGridSizer(HGap=50)
270
271             chk = dabo.ui.dCheckBox(self, Caption="Edit Table", RegID="geekEdit",
272                     DataSource="sampleGrid", DataField="Editable")
273             chk.refresh()
274             gsz.append(chk, row=0, col=0)
275
276             chk = dabo.ui.dCheckBox(self, Caption="Show Row Labels",
277                     RegID="showRowLabels", DataSource="sampleGrid",
278                     DataField="ShowRowLabels")
279             gsz.append(chk, row=1, col=0)
280             chk.refresh()
281
282             chk = dabo.ui.dCheckBox(self, Caption="Allow Multiple Selection",
283                     RegID="multiSelect", DataSource="sampleGrid",
284                     DataField="MultipleSelection")
285             chk.refresh()
286             gsz.append(chk, row=2, col=0)
287
288             radSelect = dabo.ui.dRadioList(self, Choices=["Row", "Col", "Cell"],
289                     ValueMode="string", Caption="Sel Mode", BackColor=self.BackColor,
290                     DataSource="sampleGrid", DataField="SelectionMode", RegID="radSelect")
291             radSelect.refresh()
292             gsz.append(radSelect, row=0, col=1, rowSpan=3)
293
294             self.Sizer.append(gsz, halign="Center", border=10)
295             gsz.setColExpand(True, 1)
296             self.layout()
297
298             self.fitToSizer(20,20)
299
300
301     app = dabo.dApp(MainFormClass=TestForm)
302     app.setup()
303     app.MainForm.radSelect.setFocus()
304     app.start()