summaryrefslogtreecommitdiff
path: root/rapid/ValidatedEntry.py
diff options
context:
space:
mode:
Diffstat (limited to 'rapid/ValidatedEntry.py')
-rw-r--r--rapid/ValidatedEntry.py383
1 files changed, 0 insertions, 383 deletions
diff --git a/rapid/ValidatedEntry.py b/rapid/ValidatedEntry.py
deleted file mode 100644
index cb453f4..0000000
--- a/rapid/ValidatedEntry.py
+++ /dev/null
@@ -1,383 +0,0 @@
-# Copyright (c) 2006, Daniel J. Popowich
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Send bug reports and contributions to:
-#
-# dpopowich AT astro dot umass dot edu
-#
-
-'''
-ValidatedEntry.py
-
-Provides ValidatedEntry, a subclass of gtk.Entry which validates
-input.
-
-Usage: create an instance of ValidatedEntry, specifying the function
-to validate input. E.g.:
-
- : def money(text):
- : "validate input to be monetary value"
- : ...
- :
- : money_entry = ValidatedEntry(money)
-
-Validation functions must accept one argument, the text to be
-validated, and must return one of:
-
- 1: the input is valid.
- 0: the input is invalid and should not be displayed.
- -1: the input is partially valid and will be displayed (and by
- default with a different background color).
-
-Three module-level variables are defined for the convenience of
-validation function writers: VALID (1), INVALID (0), PARTIAL (-1).
-
-There is one public method, isvalid(), which will return True if the
-current text is valid.
-
-Note: care should be taken when implementing validation functions to
-allow empty strings to be VALID or at least PARTIAL. An empty string
-should never be INVALID.
-
-Note: the hooks for calling the validation function are implemented by
-connecting the object to handlers for the gtk.Editable "insert-text"
-and "delete-text" signals. These handlers are connected to instances
-in the constructor, so will, by default, be called before other
-handlers connected to the widgets for "*-text" signals. When input is
-INVALID, stop_emission() is called, so later handlers for "*-text"
-signals will not be called.
-
-See the doc string for ValidatedEntry.__init__ for more details.
-
-'''
-
-import pygtk
-pygtk.require('2.0')
-
-import gtk
-import gtk.gdk
-
-if gtk.gtk_version < (2, 8):
- import warnings
-
- msg ='''This module was developed and tested with version 2.8.9 of gtk.
-You are using version %d.%d.%d. Your milage may vary''' % gtk.gtk_version
- warnings.warn(msg)
-
-# major, minor, patch
-version = 1, 0, 4
-
-PARTIAL, INVALID, VALID = range(-1,2)
-
-class ValidatedEntry(gtk.Entry):
-
- white = gtk.gdk.color_parse('white')
- yellow = gtk.gdk.color_parse('yellow')
-
- def __init__(self, valid_func,
- max=0,
- use_bg=True, valid_bg=white, partial_bg=yellow,
- error_func=None):
- '''
- Create instance of validating gtk.Entry.
-
- valid_func: the function to validate input. See module doc
- string for details.
-
- max: passed to gtk.Entry constructor. (default: 0)
-
- use_bg: if True (the default) set the base color of the
- widget to indicate validity; see valid_bg and partial_bg.
-
- valid_bg: a gtk.gdk.Color; the base color of the widget when
- the input is valid. (default: white)
-
- partial_bg: a gtk.gdk.Color; the base color of the widget when
- the input is partially valid. (default: yellow)
-
- error_func: a function to call (with no arguments) when
- valid_func returns INVALID. If None (the default)
- the default action will be to emit a short beep.
- '''
-
- assert valid_func('') != INVALID, 'valid_func cannot return INVALID for an empty string'
-
- gtk.Entry.__init__(self, max)
-
- self.__valid_func = valid_func
- self.__use_bg = use_bg
- self.__valid_bg = valid_bg
- self.__partial_bg = partial_bg
- self.__error_func = (error_func or
- gtk.gdk.display_get_default().beep)
-
- self.connect('insert-text', self.__insert_text_cb)
- self.connect('delete-text', self.__delete_text_cb)
-
- # bootstrap with an empty string (so the box will appear with
- # the partial_bg if an empty string is PARTIAL)
- self.insert_text('')
-
- def isvalid(self):
- return self.__isvalid
-
- def __insert_text_cb(self, entry, text, length, position):
- 'callback for "insert-text" signal'
-
- # generate what the new text will be
- text = text[:length]
- pos = self.get_position()
- old = self.get_text()
- new = old[:pos] + text + old[pos:]
-
- # validate the new text
- self.__validate(new, 'insert-text')
-
- def __delete_text_cb(self, entry, start, end):
- 'callback for "delete-text" signal'
-
- # generate what the new text will be
- old = self.get_text()
- new = old[:start] + old[end:]
-
- # validate the new text
- self.__validate(new, 'delete-text')
-
- def __validate(self, text, signal):
- 'calls the user-provided validation function'
-
- # validate
- r = self.__valid_func(text)
- if r == VALID:
- self.__isvalid = True
- if self.__use_bg:
- self.modify_base(gtk.STATE_NORMAL, self.__valid_bg)
- elif r == PARTIAL:
- self.__isvalid = False
- if self.__use_bg:
- self.modify_base(gtk.STATE_NORMAL, self.__partial_bg)
- else:
- # don't set self.__isvalid: since we're not displaying the
- # new value, the validity should be whatever it was before
- self.stop_emission(signal)
- self.__error_func()
-
-
-######################################################################
-#
-# Sample validation functions to use with ValidatedEntry
-#
-######################################################################
-
-import re
-
-
-# STRING (non-empty after stripping)
-def v_nonemptystring(value):
- '''
- VALID: non-empty string after stripping whitespace
- PARTAL: empty or all whitespace
- INVALID: N/A
- '''
- if value.strip():
- return VALID
- return PARTIAL
-
-# INT
-def v_int(value):
- '''
- VALID: any postive or negative integer
- PARTAL: empty or leading "-"
- INVALID: non-numeral
- '''
- v = value.strip()
- if not v or v == '-':
- return PARTIAL
- try:
- int(value)
- return VALID
- except:
- return INVALID
-
-# FLOAT
-def v_float(value):
- '''
- VALID: any postive or negative floating point
- PARTAL: empty or leading "-", "."
- INVALID: non-numeral
- '''
- v = value.strip()
- if not v or v in ('-', '.', '-.'):
- return PARTIAL
- try:
- float(value)
- return VALID
- except:
- return INVALID
-
-
-# ISBN
-_isbnpartial = re.compile('[0-9]{0,9}[0-9xX]?$')
-def v_isbn(v):
-
- '''Validate ISBN input.
-
- From the isbn manual, section 4.4:
-
- The check digit is the last digit of an ISBN. It is calculated on
- a modulus 11 with weights 10-2, using X in lieu of 10 where ten
- would occur as a check digit. This means that each of the first
- nine digits of the ISBN -- excluding the check digit itself -- is
- multiplied by a number ranging from 10 to 2 and that the resulting
- sum of the products, plus the check digit, must be divisible by 11
- without a remainder.'''
-
-
- if _isbnpartial.match(v):
- # isbn is ten characters in length
- if len(v) < 10:
- return PARTIAL
-
- s = 0
-
- for i, c in enumerate(v):
- s += (c in 'xX' and 10 or int(c)) * (10 - i)
-
- if s % 11 == 0:
- return VALID
-
- return INVALID
-
-# MONEY
-# re for (possibly negative) money
-_money_re = re.compile('-?\d*(\.\d{1,2})?$')
-# validation function for money
-def v_money(value):
- '''
- VALID: any postive or negative floating point with at most two
- digits after the decimal point.
- PARTAL: empty or leading "-", "."
- INVALID: non-numeral or more than two digits after the decimal
- point.
- '''
- if not value or value == '-' or value[-1] == '.':
- return PARTIAL
-
- if _money_re.match(value):
- return VALID
-
- return INVALID
-
-# PHONE
-# the characters in a phone number
-_phonechars = re.compile('[- 0-9]*$')
-# valid phone number: [AC +]EXT-LINE
-_phone = re.compile('([2-9][0-8][0-9]\s+)?[2-9][0-9]{2}-[0-9]{4}$')
-def v_phone(value):
- '''
- VALID: any phone number of the form: EXT-LINE -or- AC EXT-LINE.
- PARTAL: any characters that make up a valid #.
- INVALID: characters that are not used in a phone #.
- '''
- if _phone.match(value):
- return VALID
- if _phonechars.match(value):
- return PARTIAL
- return INVALID
-
-def empty_valid(vfunc):
-
- '''
- empty_valid is a factory function returning a validation function.
- All of the validation functions in this module return PARTIAL for
- empty strings which, in effect, forces non-empty input. There may
- be a case where, e.g., you want money input to be optional, but
- v_money will not consider empty input VALID. Instead of writing
- another validation function you can instead use empty_valid(). By
- wrapping a validation function with empty_valid(), input (after
- stripping), if empty, will be considered VALID. E.g.:
-
- ventry = ValidatedEntry(empty_valid(v_money))
-
- It is recommended that all your validation functions treat empty
- input as PARTIAL, for consistency across all validation functions
- and for use with empty_valid().
- '''
-
- def validate(value):
- if not value.strip():
- return VALID
- return vfunc(value)
-
- return validate
-
-
-def bounded(vfunc, conv, minv=None, maxv=None):
-
- '''
- bounded is a factory function returning a validation function
- providing bounded input. E.g., you may want an entry that accepts
- integers, but within a range, say, a score on a test graded in
- whole numbers from 0 to 100:
-
- score_entry = ValidatedEntry(bounded(v_int, int, 0, 100))
-
- Arguments:
-
- vfunc: A validation function.
- conv: A callable that accepts a string argument (the text in
- the entry) and returns a value to be compared to minv
- and maxv.
- minv: None or a value of the same type returned by conv. If
- None, there is no minimum value enforced. If a value,
- it will be the minimum value considered VALID.
- maxv: None or a value of the same type returned by conv. If
- None, there is no maximum value enforced. If a value,
- it will be the maximum value considered VALID.
-
- One or both of minv/maxv must be specified.
-
- The function returned will call vfunc on entry input and if vfunc
- returns VALID, the input will be converted by conv and compared to
- minv/maxv. If the converted value is within the bounds of
- minv/maxv then VALID will be returned, else PARTIAL will be
- returned.
-
- '''
-
- assert minv is not None or maxv is not None, \
- 'One of minv/maxv must be specified'
-
- def F(value):
-
- r = vfunc(value)
- if r == VALID:
- v = conv(value)
- if minv is not None and v < minv:
- return PARTIAL
- if maxv is not None and v > maxv:
- return PARTIAL
- return r
-
- return F
-
-