/env/Lib/site-packages/wx-2.8-msw-unicode/wx/lib/masked/ipaddrctrl.py
Python | 220 lines | 198 code | 0 blank | 22 comment | 1 complexity | ccc933817c6cdbe038de4398d7530947 MD5 | raw file
- #----------------------------------------------------------------------------
- # Name: masked.ipaddrctrl.py
- # Authors: Will Sadkin
- # Email: wsadkin@nameconnector.com
- # Created: 02/11/2003
- # Copyright: (c) 2003 by Will Sadkin, 2003
- # RCS-ID: $Id: ipaddrctrl.py 29787 2004-10-11 22:13:18Z RD $
- # License: wxWidgets license
- #----------------------------------------------------------------------------
- # NOTE:
- # Masked.IpAddrCtrl is a minor modification to masked.TextCtrl, that is
- # specifically tailored for entering IP addresses. It allows for
- # right-insert fields and provides an accessor to obtain the entered
- # address with extra whitespace removed.
- #
- #----------------------------------------------------------------------------
- """
- Provides a smart text input control that understands the structure and
- limits of IP Addresses, and allows automatic field navigation as the
- user hits '.' when typing.
- """
- import wx, types, string
- from wx.lib.masked import BaseMaskedTextCtrl
- # jmg 12/9/03 - when we cut ties with Py 2.2 and earlier, this would
- # be a good place to implement the 2.3 logger class
- from wx.tools.dbg import Logger
- ##dbg = Logger()
- ##dbg(enable=0)
- class IpAddrCtrlAccessorsMixin:
- """
- Defines IpAddrCtrl's list of attributes having their own
- Get/Set functions, exposing only those that make sense for
- an IP address control.
- """
- exposed_basectrl_params = (
- 'fields',
- 'retainFieldValidation',
- 'formatcodes',
- 'fillChar',
- 'defaultValue',
- 'description',
- 'useFixedWidthFont',
- '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 IpAddrCtrl( BaseMaskedTextCtrl, IpAddrCtrlAccessorsMixin ):
- """
- This class is a particular type of MaskedTextCtrl that accepts
- and understands the semantics of IP addresses, reformats input
- as you move from field to field, and accepts '.' as a navigation
- character, so that typing an IP address can be done naturally.
- """
- def __init__( self, parent, id=-1, value = '',
- pos = wx.DefaultPosition,
- size = wx.DefaultSize,
- style = wx.TE_PROCESS_TAB,
- validator = wx.DefaultValidator,
- name = 'IpAddrCtrl',
- setupEventHandling = True, ## setup event handling by default
- **kwargs):
- if not kwargs.has_key('mask'):
- kwargs['mask'] = mask = "###.###.###.###"
- if not kwargs.has_key('formatcodes'):
- kwargs['formatcodes'] = 'F_Sr<>'
- if not kwargs.has_key('validRegex'):
- 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}"
- BaseMaskedTextCtrl.__init__(
- self, parent, id=id, value = value,
- pos=pos, size=size,
- style = style,
- validator = validator,
- name = name,
- setupEventHandling = setupEventHandling,
- **kwargs)
- # set up individual field parameters as well:
- field_params = {}
- field_params['validRegex'] = "( | \d| \d |\d | \d\d|\d\d |\d \d|(1\d\d|2[0-4]\d|25[0-5]))"
- # require "valid" string; this prevents entry of any value > 255, but allows
- # intermediate constructions; overall control validation requires well-formatted value.
- field_params['formatcodes'] = 'V'
- if field_params:
- for i in self._field_indices:
- self.SetFieldParameters(i, **field_params)
- # This makes '.' act like tab:
- self._AddNavKey('.', handler=self.OnDot)
- self._AddNavKey('>', handler=self.OnDot) # for "shift-."
- def OnDot(self, event):
- """
- Defines what action to take when the '.' character is typed in the
- control. By default, the current field is right-justified, and the
- cursor is placed in the next field.
- """
- ## dbg('IpAddrCtrl::OnDot', indent=1)
- pos = self._adjustPos(self._GetInsertionPoint(), event.GetKeyCode())
- oldvalue = self.GetValue()
- edit_start, edit_end, slice = self._FindFieldExtent(pos, getslice=True)
- if not event.ShiftDown():
- if pos > edit_start and pos < edit_end:
- # clip data in field to the right of pos, if adjusting fields
- # when not at delimeter; (assumption == they hit '.')
- newvalue = oldvalue[:pos] + ' ' * (edit_end - pos) + oldvalue[edit_end:]
- self._SetValue(newvalue)
- self._SetInsertionPoint(pos)
- ## dbg(indent=0)
- return self._OnChangeField(event)
- def GetAddress(self):
- """
- Returns the control value, with any spaces removed.
- """
- value = BaseMaskedTextCtrl.GetValue(self)
- return value.replace(' ','') # remove spaces from the value
- def _OnCtrl_S(self, event):
- ## dbg("IpAddrCtrl::_OnCtrl_S")
- if self._demo:
- print "value:", self.GetAddress()
- return False
- def SetValue(self, value):
- """
- Takes a string value, validates it for a valid IP address,
- splits it into an array of 4 fields, justifies it
- appropriately, and inserts it into the control.
- Invalid values will raise a ValueError exception.
- """
- ## dbg('IpAddrCtrl::SetValue(%s)' % str(value), indent=1)
- if type(value) not in (types.StringType, types.UnicodeType):
- ## dbg(indent=0)
- raise ValueError('%s must be a string', str(value))
- bValid = True # assume True
- parts = value.split('.')
- if len(parts) != 4:
- bValid = False
- else:
- for i in range(4):
- part = parts[i]
- if not 0 <= len(part) <= 3:
- bValid = False
- break
- elif part.strip(): # non-empty part
- try:
- j = string.atoi(part)
- if not 0 <= j <= 255:
- bValid = False
- break
- else:
- parts[i] = '%3d' % j
- except:
- bValid = False
- break
- else:
- # allow empty sections for SetValue (will result in "invalid" value,
- # but this may be useful for initializing the control:
- parts[i] = ' ' # convert empty field to 3-char length
- if not bValid:
- ## dbg(indent=0)
- 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))
- else:
- ## dbg('parts:', parts)
- value = string.join(parts, '.')
- BaseMaskedTextCtrl.SetValue(self, value)
- ## dbg(indent=0)
- __i=0
- ## CHANGELOG:
- ## ====================
- ## Version 1.2
- ## 1. Fixed bugs involving missing imports now that these classes are in
- ## their own module.
- ## 2. Added doc strings for ePyDoc.
- ## 3. Renamed helper functions, vars etc. not intended to be visible in public
- ## interface to code.
- ##
- ## Version 1.1
- ## Made ipaddrctrls allow right-insert in subfields, now that insert/cut/paste works better