from Tkinter import * from baw_tktools import * # Grail will also download this util module! import sys import regex import regsub import string import urllib # The purpose of this section is to store the global state of the text # fields you will fill in later. If state_dict isn't defined, it is # initialized to a reasonable value. When you return to the page # containing this applet, the text entry widgets will be initialized # with their previous values. try: state_dict.keys() except NameError: state_dict = {} state_dict['org'] = '' state_dict['name'] = '' state_dict['age'] = '' INTEGER_RE = regex.compile("^[0-9]+$") # A bit of boilerplate to turn this applet into a standalone Tkinter # program. __name__ will only be equal to '__main__' when running # standalone. This test will be false when running under Grail. See # end of file for details. inGrail = 1 if __name__ == '__main__': inGrail = None class Validation: def validate(self): # Both value() and performValidation() must be implemented in # the subclass. value() should be implemented by the GUI # class, and validation should be implemented by the validator # class. value = self.value() return self.performValidation(value) class NoValidation (Validation): def performValidation(self, text): return 1 class InputRequiredValidation (Validation): def performValidation(self, text): if not text or len(text) <= 0: return None else: return 1 class IntegerValidation (Validation): def performValidation(self, text): if INTEGER_RE.match(text) < 0: return None else: return 1 class RequiredField: def __init__(self, master, label='Enter:'): self.master = master # don't sweat not finding make_form_entry. It comes from # baw_tktools module self.entry, self.frame, self.label = \ make_form_entry(master, label, 30) self.label_bg = self.label['background'] self.label_fg = self.label['foreground'] def value(self): return self.entry.get() def highlight(self, onoff=None): if onoff: foreground = self.label_bg background = self.label_fg else: foreground = self.label_fg background=self.label_bg self.label.config(foreground=foreground) self.label.config(background=background) class NothingRequiredField (NoValidation, RequiredField): def __init__(self, master, label): RequiredField.__init__(self, master, label) class InputRequiredField (InputRequiredValidation, RequiredField): def __init__(self, master, label): RequiredField.__init__(self, master, label) class IntegerRequiredField (IntegerValidation, RequiredField): def __init__(self, master, label): RequiredField.__init__(self, master, label) # This is the class that gets instantiated as the applet. class FieldsDemo: def __init__(self, master): self.master = master frame = Frame(master) self.vlist = {} # create the text entry fields self.vlist['name'] = InputRequiredField(frame, 'Name') self.vlist['age'] = IntegerRequiredField(frame, 'Age (in years)') self.vlist['org'] = NothingRequiredField(frame, 'Organization (optional)') # initialize their values for n in ['name', 'age', 'org']: self.vlist[n].entry.insert(0, state_dict[n]) btnframe = Frame(frame) self.validatebtn = Button(btnframe, text='Validate', command=self.validate) self.validatebtn.pack(side='left') self.sendbtn = Button(btnframe, text='Send', command=self.send) self.sendbtn.pack(side='left') if not inGrail: self.quitbtn = Button(btnframe, text='Quit', command=self.quit) self.quitbtn.pack(side='left') btnframe.pack(ipadx=10, ipady=10) self.label = Label(frame,width=20) self.label.pack(fill='x') frame.pack(ipadx=5, ipady=5, padx=5, pady=5) def quit(self): sys.exit(0) def validate(self): msg = '' for f in self.vlist.values(): if not f.validate(): msg = 'Highlighted fields are not valid' f.highlight(1) else: f.highlight() self.label.config(text=msg) return not msg def send(self): if self.validate(): self.label.config(text='sending...') if inGrail: where_im_going = "/cgi-bin/bwarsaw/echovalid.py?" + \ string.joinfields(self.encode_validfields(), '+') self.master.grail_context.follow(where_im_going) # after this point, we better not try to do anything # more with the applet as it's been destroyed once we # are viewing a new page! def encode_validfields(self): rtn = [] for k in self.vlist.keys(): # update the global state state_dict[k] = self.vlist[k].value() # make sure we quote the value part of the string rtn.append(k + '=' + urllib.quote(self.vlist[k].value())) return rtn # Here's a bit of boilerplate to turn this applet into a standalone # Tkinter program. See the comment at the top of the file for details. if not inGrail: root = Tk() FieldsDemo(root) root.mainloop()