# Based on iwidgets2.2.0/dialog.itk and iwidgets2.2.0/dialogshell.itk code. # Convention: # Each dialog window should have one of these as the rightmost button: # Close Close a window which only displays information. # Cancel Close a window which may be used to change the state of # the application. import sys import Tkinter import Pmw # A Toplevel with a ButtonBox and child site. class Dialog(Pmw.MegaToplevel): def __init__(self, parent = None, **kw): # Define the megawidget options. INITOPT = Pmw.INITOPT optiondefs = ( ('buttonbox_hull_borderwidth', 1, None), ('buttonbox_hull_relief', 'raised', None), ('buttonboxpos', 's', INITOPT), ('buttons', ('OK',), self._buttons), ('command', None, None), ('dialogchildsite_borderwidth', 1, None), ('dialogchildsite_relief', 'raised', None), ('defaultbutton', None, self._defaultButton), ('separatorwidth', 0, INITOPT), ) self.defineoptions(kw, optiondefs) # Initialise the base class (after defining the options). Pmw.MegaToplevel.__init__(self, parent) # Create the components. oldInterior = Pmw.MegaToplevel.interior(self) # Set up pack options according to the position of the button box. pos = self['buttonboxpos'] if pos not in 'nsew': raise ValueError, \ 'bad buttonboxpos option "%s": should be n, s, e, or w' \ % pos if pos in 'ns': orient = 'horizontal' fill = 'x' if pos == 'n': side = 'top' else: side = 'bottom' else: orient = 'vertical' fill = 'y' if pos == 'w': side = 'left' else: side = 'right' # Create the button box. self._buttonBox = self.createcomponent('buttonbox', (), None, Pmw.ButtonBox, (oldInterior,), orient = orient) self._buttonBox.pack(side = side, fill = fill) # Create the separating line. width = self['separatorwidth'] if width > 0: self._separator = self.createcomponent('separator', (), None, Tkinter.Frame, (oldInterior,), relief = 'sunken', height = width, width = width, borderwidth = width / 2) self._separator.pack(side = side, fill = fill) # Create the child site. self.__dialogChildSite = self.createcomponent('dialogchildsite', (), None, Tkinter.Frame, (oldInterior,)) self.__dialogChildSite.pack(side=side, fill='both', expand=1) self.oldButtons = () self.oldDefault = None self.bind('<Return>', self._invokeDefault) self.userdeletefunc(self._doCommand) self.usermodaldeletefunc(self._doCommand) # Check keywords and initialise options. self.initialiseoptions(Dialog) def interior(self): return self.__dialogChildSite def invoke(self, index = 'default'): return self._buttonBox.invoke(index) def _invokeDefault(self, event): try: self._buttonBox.index('default') except ValueError: sys.exc_traceback = None # Clean up object references return self._buttonBox.invoke() def _doCommand(self, name = None): command = self['command'] if callable(command): return command(name) else: if self.active(): self.deactivate(name) else: self.withdraw() def _buttons(self): buttons = self['buttons'] if type(buttons) != type(()) and type(buttons) != type([]): raise ValueError, \ 'bad buttons option "%s": should be a tuple' % str(buttons) if self.oldButtons == buttons: return self.oldButtons = buttons for index in range(self._buttonBox.numbuttons()): self._buttonBox.delete(0) for name in buttons: self._buttonBox.add(name, command=lambda self=self, name=name: self._doCommand(name)) if len(buttons) > 0: defaultbutton = self['defaultbutton'] if defaultbutton is None: self._buttonBox.setdefault(None) else: try: self._buttonBox.index(defaultbutton) except ValueError: sys.exc_traceback = None # Clean up object references else: self._buttonBox.setdefault(defaultbutton) self._buttonBox.alignbuttons() def _defaultButton(self): defaultbutton = self['defaultbutton'] if self.oldDefault == defaultbutton: return self.oldDefault = defaultbutton if len(self['buttons']) > 0: if defaultbutton is None: self._buttonBox.setdefault(None) else: try: self._buttonBox.index(defaultbutton) except ValueError: sys.exc_traceback = None # Clean up object references else: self._buttonBox.setdefault(defaultbutton)