]>
git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/masked/ipaddrctrl.py
   1 #---------------------------------------------------------------------------- 
   2 # Name:         masked.ipaddrctrl.py 
   4 # Email:        wsadkin@nameconnector.com 
   6 # Copyright:    (c) 2003 by Will Sadkin, 2003 
   8 # License:      wxWidgets license 
   9 #---------------------------------------------------------------------------- 
  11 #   Masked.IpAddrCtrl is a minor modification to masked.TextCtrl, that is 
  12 #   specifically tailored for entering IP addresses.  It allows for 
  13 #   right-insert fields and provides an accessor to obtain the entered 
  14 #   address with extra whitespace removed. 
  16 #---------------------------------------------------------------------------- 
  19 from wx
.lib
.masked 
import BaseMaskedTextCtrl
 
  21 # jmg 12/9/03 - when we cut ties with Py 2.2 and earlier, this would 
  22 # be a good place to implement the 2.3 logger class 
  23 from wx
.tools
.dbg 
import Logger
 
  27 class IpAddrCtrlAccessorsMixin
: 
  28     # Define IpAddrCtrl's list of attributes having their own 
  29     # Get/Set functions, exposing only those that make sense for 
  30     # an IP address control. 
  32     exposed_basectrl_params 
= ( 
  34         'retainFieldValidation', 
  41         'signedForegroundColour', 
  42         'emptyBackgroundColour', 
  43         'validBackgroundColour', 
  44         'invalidBackgroundColour', 
  51     for param 
in exposed_basectrl_params
: 
  52         propname 
= param
[0].upper() + param
[1:] 
  53         exec('def Set%s(self, value): self.SetCtrlParameters(%s=value)' % (propname
, param
)) 
  54         exec('def Get%s(self): return self.GetCtrlParameter("%s")''' % (propname, param)) 
  56         if param.find('Colour
') != -1: 
  57             # add non-british spellings, for backward-compatibility 
  58             propname.replace('Colour
', 'Color
') 
  60             exec('def Set
%s(self
, value
): self
.SetCtrlParameters(%s=value
)' % (propname, param)) 
  61             exec('def Get
%s(self
): return self
.GetCtrlParameter("%s")''' % (propname, param)) 
  64 class IpAddrCtrl( BaseMaskedTextCtrl, IpAddrCtrlAccessorsMixin ): 
  66     This class is a particular type of MaskedTextCtrl that accepts 
  67     and understands the semantics of IP addresses, reformats input 
  68     as you move from field to field, and accepts '.' as a navigation 
  69     character, so that typing an IP address can be done naturally. 
  74     def __init__( self, parent, id=-1, value = '', 
  75                   pos = wx.DefaultPosition, 
  76                   size = wx.DefaultSize, 
  77                   style = wx.TE_PROCESS_TAB, 
  78                   validator = wx.DefaultValidator, 
  80                   setupEventHandling = True,        ## setup event handling by default 
  83         if not kwargs.has_key('mask'): 
  84            kwargs['mask'] = mask = "###.###.###.###" 
  85         if not kwargs.has_key('formatcodes'): 
  86             kwargs['formatcodes'] = 'F_Sr<' 
  87         if not kwargs.has_key('validRegex'): 
  88             kwargs['validRegex'] = "(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))(\.(  \d| \d\d|(1\d\d|2[0-4]\d|25[0-5]))){3}" 
  91         BaseMaskedTextCtrl.__init__( 
  92                 self, parent, id=id, value = value, 
  95                 validator = validator, 
  97                 setupEventHandling = setupEventHandling, 
 101         # set up individual field parameters as well: 
 103         field_params['validRegex'] = "(   |  \d| \d |\d  | \d\d|\d\d |\d \d|(1\d\d|2[0-4]\d|25[0-5]))" 
 105         # require "valid" string; this prevents entry of any value > 255, but allows 
 106         # intermediate constructions; overall control validation requires well-formatted value. 
 107         field_params['formatcodes'] = 'V' 
 110             for i in self._field_indices: 
 111                 self.SetFieldParameters(i, **field_params) 
 113         # This makes '.' act like tab: 
 114         self._AddNavKey('.', handler=self.OnDot) 
 115         self._AddNavKey('>', handler=self.OnDot)    # for "shift-." 
 118     def OnDot(self, event): 
 119 ##        dbg('IpAddrCtrl::OnDot', indent=1) 
 120         pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode()) 
 121         oldvalue = self.GetValue() 
 122         edit_start, edit_end, slice = self._FindFieldExtent(pos, getslice=True) 
 123         if not event.ShiftDown(): 
 124             if pos > edit_start and pos < edit_end: 
 125                 # clip data in field to the right of pos, if adjusting fields 
 126                 # when not at delimeter; (assumption == they hit '.') 
 127                 newvalue = oldvalue[:pos] + ' ' * (edit_end - pos) + oldvalue[edit_end:] 
 128                 self._SetValue(newvalue) 
 129                 self._SetInsertionPoint(pos) 
 131         return self._OnChangeField(event) 
 135     def GetAddress(self): 
 136         value = BaseMaskedTextCtrl.GetValue(self) 
 137         return value.replace(' ','')    # remove spaces from the value 
 140     def _OnCtrl_S(self, event): 
 141 ##        dbg("IpAddrCtrl::_OnCtrl_S") 
 143             print "value:", self.GetAddress() 
 146     def SetValue(self, value): 
 147 ##        dbg('IpAddrCtrl::SetValue(%s)' % str(value), indent=1) 
 148         if type(value) not in (types.StringType, types.UnicodeType): 
 150             raise ValueError('%s must be a string', str(value)) 
 152         bValid = True   # assume True 
 153         parts = value.split('.') 
 159                 if not 0 <= len(part) <= 3: 
 162                 elif part.strip():  # non-empty part 
 164                         j = string.atoi(part) 
 165                         if not 0 <= j <= 255: 
 174                     # allow empty sections for SetValue (will result in "invalid" value, 
 175                     # but this may be useful for initializing the control: 
 176                     parts[i] = '   '    # convert empty field to 3-char length 
 180             raise ValueError('value (%s) must be a string of form n.n.n.n where n is empty or in range 0-255' % str(value)) 
 182 ##            dbg('parts:', parts) 
 183             value = string.join(parts, '.') 
 184             BaseMaskedTextCtrl.SetValue(self, value)