fixes and updates that have been sitting on my disk for a while...
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@34305 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -27,6 +27,13 @@
|
||||
# Instead set set_x_mrg and set_y_mrg
|
||||
# o Changed default X and Y Margin to 1.
|
||||
# o Added wxCalendar.SetMargin.
|
||||
#
|
||||
# 17/03/2004 - Joerg "Adi" Sieker adi@sieker.info
|
||||
# o Added keyboard navigation to the control.
|
||||
# Use the cursor keys to navigate through the ages. :)
|
||||
# The Home key function as go to today
|
||||
# o select day is now a filled rect instead of just an outline
|
||||
|
||||
|
||||
from wxPython.wx import *
|
||||
|
||||
@@ -82,8 +89,8 @@ def DefaultColors():
|
||||
colors[COLOR_FONT] = wxSystemSettings_GetColour(wxSYS_COLOUR_WINDOWTEXT)
|
||||
colors[COLOR_3D_LIGHT] = wxSystemSettings_GetColour(wxSYS_COLOUR_BTNHIGHLIGHT)
|
||||
colors[COLOR_3D_DARK] = wxSystemSettings_GetColour(wxSYS_COLOUR_BTNSHADOW)
|
||||
colors[COLOR_HIGHLIGHT_FONT] = 'PINK'
|
||||
colors[COLOR_HIGHLIGHT_BACKGROUND] = 'RED'
|
||||
colors[COLOR_HIGHLIGHT_FONT] = wxSystemSettings_GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)
|
||||
colors[COLOR_HIGHLIGHT_BACKGROUND] = wxSystemSettings_GetColour(wxSYS_COLOUR_HIGHLIGHT)
|
||||
return colors
|
||||
|
||||
# calendar drawing routing
|
||||
@@ -202,14 +209,26 @@ class CalDraw:
|
||||
for val in list:
|
||||
self.cal_sel[val] = (cfont, cbackgrd)
|
||||
|
||||
def DrawBorder(self, DC): # draw border around the outside of the main display rectangle
|
||||
brush = wxBrush(MakeColor(self.colors[COLOR_BACKGROUND]), wxSOLID)
|
||||
DC.SetBrush(brush)
|
||||
DC.SetPen(wxPen(MakeColor(self.colors[COLOR_BORDER]), 1))
|
||||
|
||||
# draw border around the outside of the main display rectangle
|
||||
def DrawBorder(self, DC, transparent = False):
|
||||
if self.outer_border is True:
|
||||
rect = wxRect(self.cx_st, self.cy_st, self.sizew, self.sizeh) # full display window area
|
||||
DC.DrawRectangle(rect.x, rect.y, rect.width, rect.height)
|
||||
if transparent == False:
|
||||
brush = wxBrush(MakeColor(self.colors[COLOR_BACKGROUND]), wxSOLID)
|
||||
else:
|
||||
brush = wxTRANSPARENT_BRUSH
|
||||
DC.SetBrush(brush)
|
||||
DC.SetPen(wxPen(MakeColor(self.colors[COLOR_BORDER])))
|
||||
# full display window area
|
||||
rect = wxRect(self.cx_st, self.cy_st, self.sizew, self.sizeh)
|
||||
DC.DrawRectangleRect(rect)
|
||||
|
||||
def DrawFocusIndicator(self, DC):
|
||||
if self.outer_border is True:
|
||||
DC.SetBrush(wxTRANSPARENT_BRUSH)
|
||||
DC.SetPen(wxPen(MakeColor(self.colors[COLOR_HIGHLIGHT_BACKGROUND]), style=wxDOT))
|
||||
# full display window area
|
||||
rect = wxRect(self.cx_st, self.cy_st, self.sizew, self.sizeh)
|
||||
DC.DrawRectangleRect(rect)
|
||||
|
||||
def DrawNumVal(self):
|
||||
self.DrawNum()
|
||||
@@ -263,6 +282,9 @@ class CalDraw:
|
||||
|
||||
def GetRect(self): # get the display rectange list of the day grid
|
||||
cnt = 0
|
||||
h = 0
|
||||
w = 0
|
||||
|
||||
for y in self.gridy[1:-1]:
|
||||
if y == self.gridy[-2]:
|
||||
h = h + self.restH
|
||||
@@ -411,9 +433,7 @@ class CalDraw:
|
||||
DC.DrawText(day, x+diffx, y+diffy)
|
||||
cnt_x = cnt_x + 1
|
||||
|
||||
def DrawNum(self, DC): # draw the day numbers
|
||||
f = wxFont(10, self.font, wxNORMAL, self.bold) # initial font setting
|
||||
|
||||
def _CalcFontSize(self, DC, f):
|
||||
if self.num_auto == True:
|
||||
test_size = self.max_num_size # max size
|
||||
test_day = ' 99 '
|
||||
@@ -431,13 +451,18 @@ class CalDraw:
|
||||
f.SetPointSize(self.num_size) # set fixed size
|
||||
DC.SetFont(f)
|
||||
|
||||
# draw the day numbers
|
||||
def DrawNum(self, DC):
|
||||
f = wxFont(10, self.font, wxNORMAL, self.bold) # initial font setting
|
||||
self._CalcFontSize(DC, f)
|
||||
|
||||
cnt_x = 0
|
||||
cnt_y = 1
|
||||
for val in self.cal_days:
|
||||
x = self.gridx[cnt_x]
|
||||
y = self.gridy[cnt_y]
|
||||
|
||||
self.DrawDayText(x, y, val, f, DC)
|
||||
self._DrawDayText(x, y, val, f, DC)
|
||||
|
||||
if cnt_x < 6:
|
||||
cnt_x = cnt_x + 1
|
||||
@@ -445,7 +470,7 @@ class CalDraw:
|
||||
cnt_x = 0
|
||||
cnt_y = cnt_y + 1
|
||||
|
||||
def DrawDayText(self, x, y, text, font, DC):
|
||||
def _DrawDayText(self, x, y, text, font, DC):
|
||||
try:
|
||||
num_val = int(text)
|
||||
num_color = self.cal_sel[num_val][0]
|
||||
@@ -456,7 +481,7 @@ class CalDraw:
|
||||
DC.SetFont(font)
|
||||
|
||||
tw,th = DC.GetTextExtent(text)
|
||||
|
||||
|
||||
if self.num_align_horz == wxALIGN_CENTRE:
|
||||
adj_h = (self.cellW - tw)/2
|
||||
elif self.num_align_horz == wxALIGN_RIGHT:
|
||||
@@ -477,6 +502,17 @@ class CalDraw:
|
||||
|
||||
DC.DrawText(text, x+adj_h, y+adj_v)
|
||||
|
||||
def DrawDayText(self, DC, key):
|
||||
f = wxFont(10, self.font, wxNORMAL, self.bold) # initial font setting
|
||||
self._CalcFontSize(DC, f)
|
||||
|
||||
val = self.cal_days[key]
|
||||
cnt_x = key % 7
|
||||
cnt_y = int(key / 7)+1
|
||||
x = self.gridx[cnt_x]
|
||||
y = self.gridy[cnt_y]
|
||||
self._DrawDayText(x, y, val, f, DC)
|
||||
|
||||
def Center(self): # calculate the dimensions in the center of the drawing area
|
||||
borderW = self.x_mrg * 2
|
||||
borderH = self.y_mrg + self.y_end + self.title_offset
|
||||
@@ -486,7 +522,8 @@ class CalDraw:
|
||||
|
||||
self.restW = ((self.sizew - borderW)%7 ) - 1
|
||||
|
||||
self.weekHdrCellH = int(self.cellH * self.cal_week_scale) # week title adjustment
|
||||
# week title adjustment
|
||||
self.weekHdrCellH = int(self.cellH * self.cal_week_scale)
|
||||
# recalculate the cell height exkl. the week header and
|
||||
# subtracting the size
|
||||
self.cellH = int((self.sizeh - borderH - self.weekHdrCellH)/6)
|
||||
@@ -496,6 +533,7 @@ class CalDraw:
|
||||
self.calH = self.cellH * 6 + self.weekHdrCellH
|
||||
|
||||
def DrawSel(self, DC): # highlighted selected days
|
||||
|
||||
for key in self.cal_sel.keys():
|
||||
sel_color = self.cal_sel[key][1]
|
||||
brush = wxBrush(MakeColor(sel_color), wxSOLID)
|
||||
@@ -578,10 +616,13 @@ class PrtCalDraw(CalDraw):
|
||||
def SetPreview(self, preview):
|
||||
self.preview = preview
|
||||
|
||||
class wxCalendar(wxWindow):
|
||||
def __init__(self, parent, id, pos=wxDefaultPosition, size=wxDefaultSize):
|
||||
wxWindow.__init__(self, parent, id, pos, size)
|
||||
class wxCalendar( wxPyControl ):
|
||||
def __init__(self, parent, id, pos=wxDefaultPosition, size=(400,400),
|
||||
style= 0, validator=wxDefaultValidator,
|
||||
name= "calendar"):
|
||||
wxPyControl.__init__(self, parent, id, pos, size, style | wxWANTS_CHARS, validator, name)
|
||||
|
||||
self.hasFocus = False
|
||||
# set the calendar control attributes
|
||||
self.cal = None
|
||||
|
||||
@@ -604,6 +645,9 @@ class wxCalendar(wxWindow):
|
||||
self.Connect(-1, -1, wxEVT_LEFT_DCLICK, self.OnLeftDEvent)
|
||||
self.Connect(-1, -1, wxEVT_RIGHT_DOWN, self.OnRightEvent)
|
||||
self.Connect(-1, -1, wxEVT_RIGHT_DCLICK, self.OnRightDEvent)
|
||||
self.Connect(-1, -1, wxEVT_SET_FOCUS, self.OnSetFocus)
|
||||
self.Connect(-1, -1, wxEVT_KILL_FOCUS, self.OnKillFocus)
|
||||
self.Connect(-1, -1, wxEVT_KEY_DOWN, self.OnKeyDown)
|
||||
|
||||
self.sel_key = None # last used by
|
||||
self.sel_lst = [] # highlighted selected days
|
||||
@@ -616,6 +660,9 @@ class wxCalendar(wxWindow):
|
||||
EVT_PAINT(self, self.OnPaint)
|
||||
EVT_SIZE(self, self.OnSize)
|
||||
|
||||
def AcceptsFocus(self):
|
||||
return self.IsShown() and self.IsEnabled()
|
||||
|
||||
def GetColor(self, name):
|
||||
return MakeColor(self.colors[name])
|
||||
|
||||
@@ -657,6 +704,65 @@ class wxCalendar(wxWindow):
|
||||
self.click = 'DRIGHT'
|
||||
self.ProcessClick(event)
|
||||
|
||||
def OnSetFocus(self, event):
|
||||
self.hasFocus = True
|
||||
self.DrawFocusIndicator(True)
|
||||
|
||||
def OnKillFocus(self, event):
|
||||
self.hasFocus = False
|
||||
self.DrawFocusIndicator(False)
|
||||
|
||||
def OnKeyDown(self, event):
|
||||
if not self.hasFocus:
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
key_code = event.KeyCode()
|
||||
|
||||
if key_code == WXK_TAB:
|
||||
forward = not event.ShiftDown()
|
||||
ne = wxNavigationKeyEvent()
|
||||
ne.SetDirection(forward)
|
||||
ne.SetCurrentFocus(self)
|
||||
ne.SetEventObject(self)
|
||||
self.GetParent().GetEventHandler().ProcessEvent(ne)
|
||||
event.Skip()
|
||||
return
|
||||
|
||||
delta = None
|
||||
|
||||
if key_code == WXK_UP:
|
||||
delta = -7
|
||||
elif key_code == WXK_DOWN:
|
||||
delta = 7
|
||||
elif key_code == WXK_LEFT:
|
||||
delta = -1
|
||||
elif key_code == WXK_RIGHT:
|
||||
delta = 1
|
||||
elif key_code == wx.WXK_HOME:
|
||||
curDate = wxDateTimeFromDMY(int(self.cal_days[self.sel_key]),self.month - 1,self.year)
|
||||
newDate = wxDateTime_Now()
|
||||
ts = newDate - curDate
|
||||
delta = ts.GetDays()
|
||||
|
||||
if delta <> None:
|
||||
curDate = wxDateTimeFromDMY(int(self.cal_days[self.sel_key]),self.month - 1,self.year)
|
||||
timeSpan = wxTimeSpan_Days(delta)
|
||||
newDate = curDate + timeSpan
|
||||
|
||||
if curDate.GetMonth() == newDate.GetMonth():
|
||||
self.set_day = newDate.GetDay()
|
||||
key = self.sel_key + delta
|
||||
self.SelectDay(key)
|
||||
else:
|
||||
self.month = newDate.GetMonth() + 1
|
||||
self.year = newDate.GetYear()
|
||||
self.set_day = newDate.GetDay()
|
||||
self.sel_key = None
|
||||
self.DoDrawing(wxClientDC(self))
|
||||
|
||||
event.Skip()
|
||||
|
||||
def SetSize(self, set_size):
|
||||
self.size = set_size
|
||||
|
||||
@@ -840,7 +946,36 @@ class wxCalendar(wxWindow):
|
||||
DC.EndDrawing()
|
||||
|
||||
# draw the selection rectangle
|
||||
def DrawRect(self, key, fgcolor = None, width = 0):
|
||||
def DrawFocusIndicator(self, draw):
|
||||
DC = wxClientDC(self)
|
||||
try:
|
||||
if draw == True:
|
||||
self.caldraw.DrawFocusIndicator(DC)
|
||||
else:
|
||||
self.caldraw.DrawBorder(DC,True)
|
||||
except:
|
||||
pass
|
||||
|
||||
def DrawRect(self, key, bgcolor = 'WHITE', fgcolor= 'PINK',width = 0):
|
||||
if key == None:
|
||||
return
|
||||
|
||||
DC = wxClientDC(self)
|
||||
DC.BeginDrawing()
|
||||
|
||||
brush = wxBrush(MakeColor(bgcolor))
|
||||
DC.SetBrush(brush)
|
||||
|
||||
DC.SetPen(wxTRANSPARENT_PEN)
|
||||
|
||||
rect = self.rg[key]
|
||||
DC.DrawRectangle(rect.x+1, rect.y+1, rect.width-2, rect.height-2)
|
||||
|
||||
self.caldraw.DrawDayText(DC,key)
|
||||
|
||||
DC.EndDrawing()
|
||||
|
||||
def DrawRectOrg(self, key, fgcolor = 'BLACK', width = 0):
|
||||
|
||||
if key == None:
|
||||
return
|
||||
@@ -867,12 +1002,24 @@ class wxCalendar(wxWindow):
|
||||
day = day + self.st_pos - 1
|
||||
self.SelectDay(day)
|
||||
|
||||
def IsDayInWeekend(self, key):
|
||||
try:
|
||||
t = Date(self.year, self.month, 1)
|
||||
|
||||
day = self.cal_days[key]
|
||||
day = int(day) + t.day_of_week
|
||||
|
||||
if day % 7 == 6 or day % 7 == 0:
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
def SelectDay(self, key):
|
||||
sel_size = 1
|
||||
self.DrawRect(self.sel_key, self.GetColor(COLOR_BACKGROUND), sel_size) # clear large selection
|
||||
|
||||
if self.hide_grid is False:
|
||||
self.DrawRect(self.sel_key, self.GetColor(COLOR_GRID_LINES),sel_size )
|
||||
|
||||
if self.sel_key != None:
|
||||
(cfont, bgcolor) = self.__GetColorsForDay(self.sel_key)
|
||||
self.DrawRect(self.sel_key, bgcolor,cfont, sel_size)
|
||||
|
||||
self.DrawRect(key, self.GetColor(COLOR_HIGHLIGHT_BACKGROUND), sel_size)
|
||||
self.sel_key = key # store last used by
|
||||
@@ -884,6 +1031,21 @@ class wxCalendar(wxWindow):
|
||||
self.set_x_mrg = xmarg
|
||||
self.set_y_mrg = ymarg
|
||||
self.set_y_end = ymarg
|
||||
def __GetColorsForDay(self, key):
|
||||
cfont = self.GetColor(COLOR_FONT)
|
||||
bgcolor = self.GetColor(COLOR_BACKGROUND)
|
||||
|
||||
if self.IsDayInWeekend(key) is True and self.show_weekend is True:
|
||||
cfont = self.GetColor(COLOR_WEEKEND_FONT)
|
||||
bgcolor = self.GetColor(COLOR_WEEKEND_BACKGROUND)
|
||||
|
||||
try:
|
||||
dayIdx = int(self.cal_days[key])
|
||||
(cfont, bgcolor) = self.caldraw.cal_sel[dayIdx]
|
||||
except:
|
||||
pass
|
||||
|
||||
return (cfont, bgcolor)
|
||||
|
||||
class CalenDlg(wxDialog):
|
||||
def __init__(self, parent, month=None, day = None, year=None):
|
||||
|
@@ -75,11 +75,6 @@ class ImageView(wxWindow):
|
||||
dc = wxPaintDC(self)
|
||||
self.DrawImage(dc)
|
||||
|
||||
def DrawImage(self, dc):
|
||||
dc.BeginDrawing()
|
||||
self.DrawImage(dc)
|
||||
dc.EndDrawing()
|
||||
|
||||
def SetValue(self, file_nm): # display the selected file in the panel
|
||||
image = ConvertBMP(file_nm)
|
||||
self.image = image
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,7 @@
|
||||
# are exceeded.
|
||||
#
|
||||
# wxMaskedNumCtrl is intended to support fixed-point numeric entry, and
|
||||
# is derived from wxMaskedTextCtrl. As such, it supports a limited range
|
||||
# is derived from wxBaseMaskedTextCtrl. As such, it supports a limited range
|
||||
# of values to comply with a fixed-width entry mask.
|
||||
"""<html><body>
|
||||
<P>
|
||||
@@ -74,6 +74,7 @@ Here's the API:
|
||||
<B>emptyBackgroundColour</B> = "White",
|
||||
<B>validBackgroundColour</B> = "White",
|
||||
<B>invalidBackgroundColour</B> = "Yellow",
|
||||
<B>autoSize</B> = True
|
||||
)
|
||||
</PRE>
|
||||
<UL>
|
||||
@@ -164,6 +165,15 @@ Here's the API:
|
||||
<DT><B>invalidBackgroundColour</B>
|
||||
<DD>Color value used for illegal values or values out-of-bounds of the
|
||||
control when the bounds are set but the control is not limited.
|
||||
<BR>
|
||||
<DT><B>autoSize</B>
|
||||
<DD>Boolean indicating whether or not the control should set its own
|
||||
width based on the integer and fraction widths. True by default.
|
||||
<B><I>Note:</I></B> Setting this to False will produce seemingly odd
|
||||
behavior unless the control is large enough to hold the maximum
|
||||
specified value given the widths and the sign positions; if not,
|
||||
the control will appear to "jump around" as the contents scroll.
|
||||
(ie. autoSize is highly recommended.)
|
||||
</UL>
|
||||
<BR>
|
||||
<BR>
|
||||
@@ -340,6 +350,12 @@ within the control. (The default is True.)
|
||||
the field values on entry.
|
||||
<BR>
|
||||
<BR>
|
||||
<DT><B>SetAutoSize(bool)</B>
|
||||
<DD>Resets the autoSize attribute of the control.
|
||||
<DT><B>GetAutoSize()</B>
|
||||
<DD>Returns the current state of the autoSize attribute for the control.
|
||||
<BR>
|
||||
<BR>
|
||||
</DL>
|
||||
</body></html>
|
||||
"""
|
||||
@@ -351,7 +367,7 @@ MAXINT = maxint # (constants should be in upper case)
|
||||
MININT = -maxint-1
|
||||
|
||||
from wxPython.tools.dbg import Logger
|
||||
from wxPython.lib.maskededit import wxMaskedEditMixin, wxMaskedTextCtrl, Field
|
||||
from wxPython.lib.maskededit import wxMaskedEditMixin, wxBaseMaskedTextCtrl, Field
|
||||
import wxPython.utils
|
||||
dbg = Logger()
|
||||
dbg(enable=0)
|
||||
@@ -381,16 +397,54 @@ class wxMaskedNumNumberUpdatedEvent(wxPyCommandEvent):
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
class wxMaskedNumCtrlAccessorsMixin:
|
||||
# Define wxMaskedNumCtrl's list of attributes having their own
|
||||
# Get/Set functions, ignoring those that make no sense for
|
||||
# an numeric control.
|
||||
exposed_basectrl_params = (
|
||||
'decimalChar',
|
||||
'shiftDecimalChar',
|
||||
'groupChar',
|
||||
'useParensForNegatives',
|
||||
'defaultValue',
|
||||
'description',
|
||||
|
||||
class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
'useFixedWidthFont',
|
||||
'autoSize',
|
||||
'signedForegroundColour',
|
||||
'emptyBackgroundColour',
|
||||
'validBackgroundColour',
|
||||
'invalidBackgroundColour',
|
||||
|
||||
'emptyInvalid',
|
||||
'validFunc',
|
||||
'validRequired',
|
||||
)
|
||||
for param in exposed_basectrl_params:
|
||||
propname = param[0].upper() + param[1:]
|
||||
exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
|
||||
exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
|
||||
|
||||
if param.find('Colour') != -1:
|
||||
# add non-british spellings, for backward-compatibility
|
||||
propname.replace('Colour', 'Color')
|
||||
|
||||
exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
|
||||
exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class wxMaskedNumCtrl(wxBaseMaskedTextCtrl, wxMaskedNumCtrlAccessorsMixin):
|
||||
|
||||
valid_ctrl_params = {
|
||||
'integerWidth': 10, # by default allow all 32-bit integers
|
||||
'fractionWidth': 0, # by default, use integers
|
||||
'fractionWidth': 0, # by default, use integers
|
||||
'decimalChar': '.', # by default, use '.' for decimal point
|
||||
'allowNegative': True, # by default, allow negative numbers
|
||||
'useParensForNegatives': False, # by default, use '-' to indicate negatives
|
||||
'groupDigits': True, # by default, don't insert grouping
|
||||
'groupDigits': True, # by default, don't insert grouping
|
||||
'groupChar': ',', # by default, use ',' for grouping
|
||||
'min': None, # by default, no bounds set
|
||||
'max': None,
|
||||
@@ -402,7 +456,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
'emptyBackgroundColour': "White",
|
||||
'validBackgroundColour': "White",
|
||||
'invalidBackgroundColour': "Yellow",
|
||||
'useFixedWidthFont': True, # by default, use a fixed-width font
|
||||
'useFixedWidthFont': True, # by default, use a fixed-width font
|
||||
'autoSize': True, # by default, set the width of the control based on the mask
|
||||
}
|
||||
|
||||
|
||||
@@ -475,6 +530,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
del init_args['integerWidth']
|
||||
del init_args['fractionWidth']
|
||||
|
||||
self._autoSize = init_args['autoSize']
|
||||
if self._autoSize:
|
||||
formatcodes = 'FR<'
|
||||
else:
|
||||
formatcodes = 'R<'
|
||||
|
||||
|
||||
mask = intmask+fracmask
|
||||
|
||||
@@ -484,11 +545,11 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
self._typedSign = False
|
||||
|
||||
# Construct the base control:
|
||||
wxMaskedTextCtrl.__init__(
|
||||
wxBaseMaskedTextCtrl.__init__(
|
||||
self, parent, id, '',
|
||||
pos, size, style, validator, name,
|
||||
mask = mask,
|
||||
formatcodes = 'FR<',
|
||||
formatcodes = formatcodes,
|
||||
fields = fields,
|
||||
validFunc=self.IsInBounds,
|
||||
setupEventHandling = False)
|
||||
@@ -525,7 +586,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
|
||||
if( (kwargs.has_key('integerWidth') and kwargs['integerWidth'] != self._integerWidth)
|
||||
or (kwargs.has_key('fractionWidth') and kwargs['fractionWidth'] != self._fractionWidth)
|
||||
or (kwargs.has_key('groupDigits') and kwargs['groupDigits'] != self._groupDigits) ):
|
||||
or (kwargs.has_key('groupDigits') and kwargs['groupDigits'] != self._groupDigits)
|
||||
or (kwargs.has_key('autoSize') and kwargs['autoSize'] != self._autoSize) ):
|
||||
|
||||
fields = {}
|
||||
|
||||
@@ -601,7 +663,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
dbg('kwargs:', kwargs)
|
||||
|
||||
# reprocess existing format codes to ensure proper resulting format:
|
||||
formatcodes = self.GetFormatcodes()
|
||||
formatcodes = self.GetCtrlParameter('formatcodes')
|
||||
if kwargs.has_key('allowNegative'):
|
||||
if kwargs['allowNegative'] and '-' not in formatcodes:
|
||||
formatcodes += '-'
|
||||
@@ -628,6 +690,16 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
formatcodes = formatcodes.replace('S','')
|
||||
maskededit_kwargs['formatcodes'] = formatcodes
|
||||
|
||||
if kwargs.has_key('autoSize'):
|
||||
self._autoSize = kwargs['autoSize']
|
||||
if kwargs['autoSize'] and 'F' not in formatcodes:
|
||||
formatcodes += 'F'
|
||||
maskededit_kwargs['formatcodes'] = formatcodes
|
||||
elif not kwargs['autoSize'] and 'F' in formatcodes:
|
||||
formatcodes = formatcodes.replace('F', '')
|
||||
maskededit_kwargs['formatcodes'] = formatcodes
|
||||
|
||||
|
||||
if 'r' in formatcodes and self._fractionWidth:
|
||||
# top-level mask should only be right insert if no fractional
|
||||
# part will be shown; ie. if reconfiguring control, remove
|
||||
@@ -635,6 +707,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
formatcodes = formatcodes.replace('r', '')
|
||||
maskededit_kwargs['formatcodes'] = formatcodes
|
||||
|
||||
|
||||
if kwargs.has_key('limited'):
|
||||
if kwargs['limited'] and not self._limited:
|
||||
maskededit_kwargs['validRequired'] = True
|
||||
@@ -720,7 +793,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
dbg('abs(value):', value)
|
||||
self._isNeg = False
|
||||
|
||||
elif not self._allowNone and wxMaskedTextCtrl.GetValue(self) == '':
|
||||
elif not self._allowNone and wxBaseMaskedTextCtrl.GetValue(self) == '':
|
||||
if self._min > 0:
|
||||
value = self._min
|
||||
else:
|
||||
@@ -762,7 +835,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
else:
|
||||
fracstart, fracend = self._fields[1]._extent
|
||||
if candidate is None:
|
||||
value = self._toGUI(wxMaskedTextCtrl.GetValue(self))
|
||||
value = self._toGUI(wxBaseMaskedTextCtrl.GetValue(self))
|
||||
else:
|
||||
value = self._toGUI(candidate)
|
||||
fracstring = value[fracstart:fracend].strip()
|
||||
@@ -811,8 +884,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
|
||||
if numvalue == "":
|
||||
if self._allowNone:
|
||||
dbg('calling base wxMaskedTextCtrl._SetValue(self, "%s")' % value)
|
||||
wxMaskedTextCtrl._SetValue(self, value)
|
||||
dbg('calling base wxBaseMaskedTextCtrl._SetValue(self, "%s")' % value)
|
||||
wxBaseMaskedTextCtrl._SetValue(self, value)
|
||||
self.Refresh()
|
||||
return
|
||||
elif self._min > 0 and self.IsLimited():
|
||||
@@ -912,7 +985,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
# reasonable instead:
|
||||
dbg('setting replacement value:', replacement)
|
||||
self._SetValue(self._toGUI(replacement))
|
||||
sel_start = wxMaskedTextCtrl.GetValue(self).find(str(abs(replacement))) # find where it put the 1, so we can select it
|
||||
sel_start = wxBaseMaskedTextCtrl.GetValue(self).find(str(abs(replacement))) # find where it put the 1, so we can select it
|
||||
sel_to = sel_start + len(str(abs(replacement)))
|
||||
dbg('queuing selection of (%d, %d)' %(sel_start, sel_to))
|
||||
wxCallAfter(self.SetInsertionPoint, sel_start)
|
||||
@@ -938,8 +1011,8 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
|
||||
|
||||
sel_start, sel_to = self._GetSelection() # record current insertion point
|
||||
dbg('calling base wxMaskedTextCtrl._SetValue(self, "%s")' % adjvalue)
|
||||
wxMaskedTextCtrl._SetValue(self, adjvalue)
|
||||
dbg('calling base wxBaseMaskedTextCtrl._SetValue(self, "%s")' % adjvalue)
|
||||
wxBaseMaskedTextCtrl._SetValue(self, adjvalue)
|
||||
# After all actions so far scheduled, check that resulting cursor
|
||||
# position is appropriate, and move if not:
|
||||
wxCallAfter(self._CheckInsertionPoint)
|
||||
@@ -972,7 +1045,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
# delete next digit to appropriate side:
|
||||
if self._groupDigits:
|
||||
key = event.GetKeyCode()
|
||||
value = wxMaskedTextCtrl.GetValue(self)
|
||||
value = wxBaseMaskedTextCtrl.GetValue(self)
|
||||
sel_start, sel_to = self._GetSelection()
|
||||
|
||||
if key == WXK_BACK:
|
||||
@@ -998,7 +1071,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
self.SetInsertionPoint(sel_start)
|
||||
self.SetSelection(sel_start, sel_to+1)
|
||||
|
||||
wxMaskedTextCtrl._OnErase(self, event)
|
||||
wxBaseMaskedTextCtrl._OnErase(self, event)
|
||||
dbg(indent=0)
|
||||
|
||||
|
||||
@@ -1012,7 +1085,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
before passing the events on.
|
||||
"""
|
||||
dbg('wxMaskedNumCtrl::OnTextChange', indent=1)
|
||||
if not wxMaskedTextCtrl._OnTextChange(self, event):
|
||||
if not wxBaseMaskedTextCtrl._OnTextChange(self, event):
|
||||
dbg(indent=0)
|
||||
return
|
||||
|
||||
@@ -1033,7 +1106,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
|
||||
def _GetValue(self):
|
||||
"""
|
||||
Override of wxMaskedTextCtrl to allow amixin to get the raw text value of the
|
||||
Override of wxBaseMaskedTextCtrl to allow mixin to get the raw text value of the
|
||||
control with this function.
|
||||
"""
|
||||
return wxTextCtrl.GetValue(self)
|
||||
@@ -1043,7 +1116,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
"""
|
||||
Returns the current numeric value of the control.
|
||||
"""
|
||||
return self._fromGUI( wxMaskedTextCtrl.GetValue(self) )
|
||||
return self._fromGUI( wxBaseMaskedTextCtrl.GetValue(self) )
|
||||
|
||||
def SetValue(self, value):
|
||||
"""
|
||||
@@ -1054,16 +1127,16 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
A ValueError exception will be raised if an invalid value
|
||||
is specified.
|
||||
"""
|
||||
wxMaskedTextCtrl.SetValue( self, self._toGUI(value) )
|
||||
wxBaseMaskedTextCtrl.SetValue( self, self._toGUI(value) )
|
||||
|
||||
|
||||
def SetIntegerWidth(self, value):
|
||||
self.SetCtrlParameters(integerWidth=value)
|
||||
self.SetParameters(integerWidth=value)
|
||||
def GetIntegerWidth(self):
|
||||
return self._integerWidth
|
||||
|
||||
def SetFractionWidth(self, value):
|
||||
self.SetCtrlParameters(fractionWidth=value)
|
||||
self.SetParameters(fractionWidth=value)
|
||||
def GetFractionWidth(self):
|
||||
return self._fractionWidth
|
||||
|
||||
@@ -1208,7 +1281,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
except ValueError, e:
|
||||
dbg('error getting NumValue(self._toGUI(value)):', e, indent=0)
|
||||
return False
|
||||
if value == '':
|
||||
if value.strip() == '':
|
||||
value = None
|
||||
elif self._fractionWidth:
|
||||
value = float(value)
|
||||
@@ -1281,6 +1354,12 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
def GetSelectOnEntry(self):
|
||||
return self._selectOnEntry
|
||||
|
||||
def SetAutoSize(self, value):
|
||||
self.SetParameters(autoSize=value)
|
||||
def GetAutoSize(self):
|
||||
return self._autoSize
|
||||
|
||||
|
||||
# (Other parameter accessors are inherited from base class)
|
||||
|
||||
|
||||
@@ -1298,6 +1377,14 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
elif type(value) in (types.StringType, types.UnicodeType):
|
||||
value = self._GetNumValue(value)
|
||||
dbg('cleansed num value: "%s"' % value)
|
||||
if value == "":
|
||||
if self.IsNoneAllowed():
|
||||
dbg(indent=0)
|
||||
return self._template
|
||||
else:
|
||||
dbg('exception raised:', e, indent=0)
|
||||
raise ValueError ('wxMaskedNumCtrl requires numeric value, passed %s'% repr(value) )
|
||||
# else...
|
||||
try:
|
||||
if self._fractionWidth or value.find('.') != -1:
|
||||
value = float(value)
|
||||
@@ -1367,7 +1454,7 @@ class wxMaskedNumCtrl(wxMaskedTextCtrl):
|
||||
# So, to ensure consistency and to prevent spurious ValueErrors,
|
||||
# we make the following test, and react accordingly:
|
||||
#
|
||||
if value == '':
|
||||
if value.strip() == '':
|
||||
if not self.IsNoneAllowed():
|
||||
dbg('empty value; not allowed,returning 0', indent = 0)
|
||||
if self._fractionWidth:
|
||||
@@ -1503,3 +1590,12 @@ i=0
|
||||
## =============================##
|
||||
## 1. Add support for printf-style format specification.
|
||||
## 2. Add option for repositioning on 'illegal' insertion point.
|
||||
##
|
||||
## Version 1.1
|
||||
## 1. Fixed .SetIntegerWidth() and .SetFractionWidth() functions.
|
||||
## 2. Added autoSize parameter, to allow manual sizing of the control.
|
||||
## 3. Changed inheritance to use wxBaseMaskedTextCtrl, to remove exposure of
|
||||
## nonsensical parameter methods from the control, so it will work
|
||||
## properly with Boa.
|
||||
## 4. Fixed allowNone bug found by user sameerc1@grandecom.net
|
||||
|
||||
|
@@ -53,7 +53,9 @@ Here's the API for wxTimeCtrl:
|
||||
<B>style</B> = wxTE_PROCESS_TAB,
|
||||
<B>validator</B> = wxDefaultValidator,
|
||||
name = "time",
|
||||
<B>format</B> = 'HHMMSS',
|
||||
<B>fmt24hr</B> = False,
|
||||
<B>displaySeconds</B> = True,
|
||||
<B>spinButton</B> = None,
|
||||
<B>min</B> = None,
|
||||
<B>max</B> = None,
|
||||
@@ -77,10 +79,21 @@ Here's the API for wxTimeCtrl:
|
||||
of its validation for entry control is handled internally. However, a validator
|
||||
can be supplied to provide data transfer capability to the control.
|
||||
<BR>
|
||||
<DT><B>format</B>
|
||||
<DD>This parameter can be used instead of the fmt24hr and displaySeconds
|
||||
parameters, respectively; it provides a shorthand way to specify the time
|
||||
format you want. Accepted values are 'HHMMSS', 'HHMM', '24HHMMSS', and
|
||||
'24HHMM'. If the format is specified, the other two arguments will be ignored.
|
||||
<DT><B>fmt24hr</B>
|
||||
<DD>If True, control will display time in 24 hour time format; if False, it will
|
||||
use 12 hour AM/PM format. SetValue() will adjust values accordingly for the
|
||||
control, based on the format specified.
|
||||
control, based on the format specified. (This value is ignored if the <i>format</i>
|
||||
parameter is specified.)
|
||||
<BR>
|
||||
<DT><B>displaySeconds</B>
|
||||
<DD>If True, control will include a seconds field; if False, it will
|
||||
just show hours and minutes. (This value is ignored if the <i>format</i>
|
||||
parameter is specified.)
|
||||
<BR>
|
||||
<DT><B>spinButton</B>
|
||||
<DD>If specified, this button's events will be bound to the behavior of the
|
||||
@@ -242,7 +255,7 @@ value to fall within the current bounds.
|
||||
import string, copy
|
||||
from wxPython.wx import *
|
||||
from wxPython.tools.dbg import Logger
|
||||
from wxPython.lib.maskededit import wxMaskedTextCtrl, Field
|
||||
from wxPython.lib.maskededit import wxBaseMaskedTextCtrl, Field
|
||||
import wxPython.utils
|
||||
dbg = Logger()
|
||||
dbg(enable=0)
|
||||
@@ -267,11 +280,41 @@ class TimeUpdatedEvent(wxPyCommandEvent):
|
||||
"""Retrieve the value of the time control at the time this event was generated"""
|
||||
return self.value
|
||||
|
||||
class wxTimeCtrlAccessorsMixin:
|
||||
# Define wxMaskedNumCtrl's list of attributes having their own
|
||||
# Get/Set functions, ignoring those that make no sense for
|
||||
# an numeric control.
|
||||
exposed_basectrl_params = (
|
||||
'defaultValue',
|
||||
'description',
|
||||
|
||||
class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
'useFixedWidthFont',
|
||||
'emptyBackgroundColour',
|
||||
'validBackgroundColour',
|
||||
'invalidBackgroundColour',
|
||||
|
||||
'validFunc',
|
||||
'validRequired',
|
||||
)
|
||||
for param in exposed_basectrl_params:
|
||||
propname = param[0].upper() + param[1:]
|
||||
exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
|
||||
exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
|
||||
|
||||
if param.find('Colour') != -1:
|
||||
# add non-british spellings, for backward-compatibility
|
||||
propname.replace('Colour', 'Color')
|
||||
|
||||
exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname, param))
|
||||
exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param))
|
||||
|
||||
|
||||
|
||||
class wxTimeCtrl(wxBaseMaskedTextCtrl):
|
||||
|
||||
valid_ctrl_params = {
|
||||
'display_seconds' : True, # by default, shows seconds
|
||||
'format' : 'HHMMSS', # default format code
|
||||
'displaySeconds' : True, # by default, shows seconds
|
||||
'min': None, # by default, no bounds set
|
||||
'max': None,
|
||||
'limited': False, # by default, no limiting even if bounds set
|
||||
@@ -303,60 +346,39 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
limited = self.__limited
|
||||
self.__posCurrent = 0
|
||||
|
||||
# handle deprecated keword argument name:
|
||||
if kwargs.has_key('display_seconds'):
|
||||
kwargs['displaySeconds'] = kwargs['display_seconds']
|
||||
del kwargs['display_seconds']
|
||||
if not kwargs.has_key('displaySeconds'):
|
||||
kwargs['displaySeconds'] = True
|
||||
|
||||
# (handle positional args (from original release) differently from rest of kwargs:)
|
||||
self.__fmt24hr = fmt24hr
|
||||
# (handle positional arg (from original release) differently from rest of kwargs:)
|
||||
self.__fmt24hr = False
|
||||
if not kwargs.has_key('format'):
|
||||
if fmt24hr:
|
||||
if kwargs.has_key('displaySeconds') and kwargs['displaySeconds']:
|
||||
kwargs['format'] = '24HHMMSS'
|
||||
del kwargs['displaySeconds']
|
||||
else:
|
||||
kwargs['format'] = '24HHMM'
|
||||
else:
|
||||
if kwargs.has_key('displaySeconds') and kwargs['displaySeconds']:
|
||||
kwargs['format'] = 'HHMMSS'
|
||||
del kwargs['displaySeconds']
|
||||
else:
|
||||
kwargs['format'] = 'HHMM'
|
||||
|
||||
maskededit_kwargs = {}
|
||||
if not kwargs.has_key('useFixedWidthFont'):
|
||||
# allow control over font selection:
|
||||
kwargs['useFixedWidthFont'] = self.__useFixedWidthFont
|
||||
|
||||
# assign keyword args as appropriate:
|
||||
for key, param_value in kwargs.items():
|
||||
if key not in wxTimeCtrl.valid_ctrl_params.keys():
|
||||
raise AttributeError('invalid keyword argument "%s"' % key)
|
||||
maskededit_kwargs = self.SetParameters(**kwargs)
|
||||
|
||||
if key == "display_seconds":
|
||||
self.__display_seconds = param_value
|
||||
|
||||
elif key == "min": min = param_value
|
||||
elif key == "max": max = param_value
|
||||
elif key == "limited": limited = param_value
|
||||
|
||||
elif key == "useFixedWidthFont":
|
||||
maskededit_kwargs[key] = param_value
|
||||
elif key == "oob_color":
|
||||
maskededit_kwargs['invalidBackgroundColor'] = param_value
|
||||
|
||||
if self.__fmt24hr:
|
||||
if self.__display_seconds: maskededit_kwargs['autoformat'] = 'MILTIMEHHMMSS'
|
||||
else: maskededit_kwargs['autoformat'] = 'MILTIMEHHMM'
|
||||
|
||||
# Set hour field to zero-pad, right-insert, require explicit field change,
|
||||
# select entire field on entry, and require a resultant valid entry
|
||||
# to allow character entry:
|
||||
hourfield = Field(formatcodes='0r<SV', validRegex='0\d|1\d|2[0123]', validRequired=True)
|
||||
else:
|
||||
if self.__display_seconds: maskededit_kwargs['autoformat'] = 'TIMEHHMMSS'
|
||||
else: maskededit_kwargs['autoformat'] = 'TIMEHHMM'
|
||||
|
||||
# Set hour field to allow spaces (at start), right-insert,
|
||||
# require explicit field change, select entire field on entry,
|
||||
# and require a resultant valid entry to allow character entry:
|
||||
hourfield = Field(formatcodes='_0<rSV', validRegex='0[1-9]| [1-9]|1[012]', validRequired=True)
|
||||
ampmfield = Field(formatcodes='S', emptyInvalid = True, validRequired = True)
|
||||
|
||||
# Field 1 is always a zero-padded right-insert minute field,
|
||||
# similarly configured as above:
|
||||
minutefield = Field(formatcodes='0r<SV', validRegex='[0-5]\d', validRequired=True)
|
||||
|
||||
fields = [ hourfield, minutefield ]
|
||||
if self.__display_seconds:
|
||||
fields.append(copy.copy(minutefield)) # second field has same constraints as field 1
|
||||
|
||||
if not self.__fmt24hr:
|
||||
fields.append(ampmfield)
|
||||
|
||||
# set fields argument:
|
||||
maskededit_kwargs['fields'] = fields
|
||||
# allow for explicit size specification:
|
||||
if size != wxDefaultSize:
|
||||
# override (and remove) "autofit" autoformat code in standard time formats:
|
||||
maskededit_kwargs['formatcodes'] = 'T!'
|
||||
|
||||
# This allows range validation if set
|
||||
maskededit_kwargs['validFunc'] = self.IsInBounds
|
||||
@@ -365,16 +387,9 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
# dynamically without affecting individual field constraint validation
|
||||
maskededit_kwargs['retainFieldValidation'] = True
|
||||
|
||||
# allow control over font selection:
|
||||
maskededit_kwargs['useFixedWidthFont'] = self.__useFixedWidthFont
|
||||
|
||||
# allow for explicit size specification:
|
||||
if size != wxDefaultSize:
|
||||
# override (and remove) "autofit" autoformat code in standard time formats:
|
||||
maskededit_kwargs['formatcodes'] = 'T!'
|
||||
|
||||
# Now we can initialize the base control:
|
||||
wxMaskedTextCtrl.__init__(
|
||||
wxBaseMaskedTextCtrl.__init__(
|
||||
self, parent, id=id,
|
||||
pos=pos, size=size,
|
||||
style = style,
|
||||
@@ -411,7 +426,7 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
EVT_LEFT_DCLICK(self, self._OnDoubleClick ) ## select field under cursor on dclick
|
||||
EVT_KEY_DOWN( self, self._OnKeyDown ) ## capture control events not normally seen, eg ctrl-tab.
|
||||
EVT_CHAR( self, self.__OnChar ) ## remove "shift" attribute from colon key event,
|
||||
## then call wxMaskedTextCtrl._OnChar with
|
||||
## then call wxBaseMaskedTextCtrl._OnChar with
|
||||
## the possibly modified event.
|
||||
EVT_TEXT( self, self.GetId(), self.__OnTextChange ) ## color control appropriately and EVT_TIMEUPDATE events
|
||||
|
||||
@@ -428,6 +443,111 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
self.BindSpinButton(spinButton) # bind spin button up/down events to this control
|
||||
|
||||
|
||||
def SetParameters(self, **kwargs):
|
||||
dbg('wxTimeCtrl::SetParameters(%s)' % repr(kwargs), indent=1)
|
||||
maskededit_kwargs = {}
|
||||
reset_format = False
|
||||
|
||||
if kwargs.has_key('display_seconds'):
|
||||
kwargs['displaySeconds'] = kwargs['display_seconds']
|
||||
del kwargs['display_seconds']
|
||||
if kwargs.has_key('format') and kwargs.has_key('displaySeconds'):
|
||||
del kwargs['displaySeconds'] # always apply format if specified
|
||||
|
||||
# assign keyword args as appropriate:
|
||||
for key, param_value in kwargs.items():
|
||||
if key not in wxTimeCtrl.valid_ctrl_params.keys():
|
||||
raise AttributeError('invalid keyword argument "%s"' % key)
|
||||
|
||||
if key == 'format':
|
||||
# handle both local or generic 'maskededit' autoformat codes:
|
||||
if param_value == 'HHMMSS' or param_value == 'TIMEHHMMSS':
|
||||
self.__displaySeconds = True
|
||||
self.__fmt24hr = False
|
||||
elif param_value == 'HHMM' or param_value == 'TIMEHHMM':
|
||||
self.__displaySeconds = False
|
||||
self.__fmt24hr = False
|
||||
elif param_value == '24HHMMSS' or param_value == '24HRTIMEHHMMSS':
|
||||
self.__displaySeconds = True
|
||||
self.__fmt24hr = True
|
||||
elif param_value == '24HHMM' or param_value == '24HRTIMEHHMM':
|
||||
self.__displaySeconds = False
|
||||
self.__fmt24hr = True
|
||||
else:
|
||||
raise AttributeError('"%s" is not a valid format' % param_value)
|
||||
reset_format = True
|
||||
|
||||
elif key in ("displaySeconds", "display_seconds") and not kwargs.has_key('format'):
|
||||
self.__displaySeconds = param_value
|
||||
reset_format = True
|
||||
|
||||
elif key == "min": min = param_value
|
||||
elif key == "max": max = param_value
|
||||
elif key == "limited": limited = param_value
|
||||
|
||||
elif key == "useFixedWidthFont":
|
||||
maskededit_kwargs[key] = param_value
|
||||
|
||||
elif key == "oob_color":
|
||||
maskededit_kwargs['invalidBackgroundColor'] = param_value
|
||||
|
||||
if reset_format:
|
||||
if self.__fmt24hr:
|
||||
if self.__displaySeconds: maskededit_kwargs['autoformat'] = '24HRTIMEHHMMSS'
|
||||
else: maskededit_kwargs['autoformat'] = '24HRTIMEHHMM'
|
||||
|
||||
# Set hour field to zero-pad, right-insert, require explicit field change,
|
||||
# select entire field on entry, and require a resultant valid entry
|
||||
# to allow character entry:
|
||||
hourfield = Field(formatcodes='0r<SV', validRegex='0\d|1\d|2[0123]', validRequired=True)
|
||||
else:
|
||||
if self.__displaySeconds: maskededit_kwargs['autoformat'] = 'TIMEHHMMSS'
|
||||
else: maskededit_kwargs['autoformat'] = 'TIMEHHMM'
|
||||
|
||||
# Set hour field to allow spaces (at start), right-insert,
|
||||
# require explicit field change, select entire field on entry,
|
||||
# and require a resultant valid entry to allow character entry:
|
||||
hourfield = Field(formatcodes='_0<rSV', validRegex='0[1-9]| [1-9]|1[012]', validRequired=True)
|
||||
ampmfield = Field(formatcodes='S', emptyInvalid = True, validRequired = True)
|
||||
|
||||
# Field 1 is always a zero-padded right-insert minute field,
|
||||
# similarly configured as above:
|
||||
minutefield = Field(formatcodes='0r<SV', validRegex='[0-5]\d', validRequired=True)
|
||||
|
||||
fields = [ hourfield, minutefield ]
|
||||
if self.__displaySeconds:
|
||||
fields.append(copy.copy(minutefield)) # second field has same constraints as field 1
|
||||
|
||||
if not self.__fmt24hr:
|
||||
fields.append(ampmfield)
|
||||
|
||||
# set fields argument:
|
||||
maskededit_kwargs['fields'] = fields
|
||||
|
||||
# This allows range validation if set
|
||||
maskededit_kwargs['validFunc'] = self.IsInBounds
|
||||
|
||||
# This allows range limits to affect insertion into control or not
|
||||
# dynamically without affecting individual field constraint validation
|
||||
maskededit_kwargs['retainFieldValidation'] = True
|
||||
|
||||
if hasattr(self, 'controlInitialized') and self.controlInitialized:
|
||||
self.SetCtrlParameters(**maskededit_kwargs) # set appropriate parameters
|
||||
|
||||
# Validate initial value and set if appropriate
|
||||
try:
|
||||
self.SetBounds(min, max)
|
||||
self.SetLimited(limited)
|
||||
self.SetValue(value)
|
||||
except:
|
||||
self.SetValue('12:00:00 AM')
|
||||
dbg(indent=0)
|
||||
return {} # no arguments to return
|
||||
else:
|
||||
dbg(indent=0)
|
||||
return maskededit_kwargs
|
||||
|
||||
|
||||
|
||||
def BindSpinButton(self, sb):
|
||||
"""
|
||||
@@ -482,7 +602,7 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
elif as_mxDateTimeDelta:
|
||||
value = DateTime.DateTimeDelta(0, value.GetHour(), value.GetMinute(), value.GetSecond())
|
||||
else:
|
||||
value = wxMaskedTextCtrl.GetValue(self)
|
||||
value = wxBaseMaskedTextCtrl.GetValue(self)
|
||||
return value
|
||||
|
||||
|
||||
@@ -874,6 +994,16 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
def SetFormat(self, format):
|
||||
self.SetParameters(format=format)
|
||||
|
||||
def GetFormat(self):
|
||||
if self.__displaySeconds:
|
||||
if self.__fmt24hr: return '24HHMMSS'
|
||||
else: return 'HHMMSS'
|
||||
else:
|
||||
if self.__fmt24hr: return '24HHMM'
|
||||
else: return 'HHMM'
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------------
|
||||
# these are private functions and overrides:
|
||||
@@ -891,7 +1021,7 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
## event iff the value has actually changed. The masked edit
|
||||
## OnTextChange routine does this, and returns True on a valid event,
|
||||
## False otherwise.
|
||||
if not wxMaskedTextCtrl._OnTextChange(self, event):
|
||||
if not wxBaseMaskedTextCtrl._OnTextChange(self, event):
|
||||
return
|
||||
|
||||
dbg('firing TimeUpdatedEvent...')
|
||||
@@ -908,7 +1038,7 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
point is lost when the focus shifts to the spin button.
|
||||
"""
|
||||
dbg('wxTimeCtrl::SetInsertionPoint', pos, indent=1)
|
||||
wxMaskedTextCtrl.SetInsertionPoint(self, pos) # (causes EVT_TEXT event to fire)
|
||||
wxBaseMaskedTextCtrl.SetInsertionPoint(self, pos) # (causes EVT_TEXT event to fire)
|
||||
self.__posCurrent = self.GetInsertionPoint()
|
||||
dbg(indent=0)
|
||||
|
||||
@@ -927,7 +1057,7 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
sel_to = cell_end
|
||||
|
||||
self.__bSelection = sel_start != sel_to
|
||||
wxMaskedTextCtrl.SetSelection(self, sel_start, sel_to)
|
||||
wxBaseMaskedTextCtrl.SetSelection(self, sel_start, sel_to)
|
||||
dbg(indent=0)
|
||||
|
||||
|
||||
@@ -984,7 +1114,7 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
if keycode == ord(':'):
|
||||
dbg('colon seen! removing shift attribute')
|
||||
event.m_shiftDown = False
|
||||
wxMaskedTextCtrl._OnChar(self, event ) ## handle each keypress
|
||||
wxBaseMaskedTextCtrl._OnChar(self, event ) ## handle each keypress
|
||||
dbg(indent=0)
|
||||
|
||||
|
||||
@@ -1070,10 +1200,10 @@ class wxTimeCtrl(wxMaskedTextCtrl):
|
||||
converts it to a string appropriate for the format of the control.
|
||||
"""
|
||||
if self.__fmt24hr:
|
||||
if self.__display_seconds: strval = wxdt.Format('%H:%M:%S')
|
||||
if self.__displaySeconds: strval = wxdt.Format('%H:%M:%S')
|
||||
else: strval = wxdt.Format('%H:%M')
|
||||
else:
|
||||
if self.__display_seconds: strval = wxdt.Format('%I:%M:%S %p')
|
||||
if self.__displaySeconds: strval = wxdt.Format('%I:%M:%S %p')
|
||||
else: strval = wxdt.Format('%I:%M %p')
|
||||
|
||||
return strval
|
||||
@@ -1164,3 +1294,11 @@ if __name__ == '__main__':
|
||||
app.MainLoop()
|
||||
except:
|
||||
traceback.print_exc()
|
||||
i=0
|
||||
## Version 1.2
|
||||
## 1. Changed parameter name display_seconds to displaySeconds, to follow
|
||||
## other masked edit conventions.
|
||||
## 2. Added format parameter, to remove need to use both fmt24hr and displaySeconds.
|
||||
## 3. Changed inheritance to use wxBaseMaskedTextCtrl, to remove exposure of
|
||||
## nonsensical parameter methods from the control, so it will work
|
||||
## properly with Boa.
|
||||
|
@@ -61,6 +61,10 @@ def getAttributeNames(object, includeMagic=1, includeSingle=1,
|
||||
for item in attributes:
|
||||
dict[item] = None
|
||||
attributes = dict.keys()
|
||||
# new-style swig wrappings can result in non-string attributes
|
||||
# e.g. ITK http://www.itk.org/
|
||||
attributes = [attribute for attribute in attributes \
|
||||
if type(attribute) == str]
|
||||
attributes.sort(lambda x, y: cmp(x.upper(), y.upper()))
|
||||
if not includeSingle:
|
||||
attributes = filter(lambda item: item[0]!='_' \
|
||||
|
Reference in New Issue
Block a user