
# The options of a widget are described by the following attributes
# of the Pack and Widget dialogs:
#
# Dialog.current: {name: value}
# -- changes during Widget's lifetime
#
# Dialog.options: {name: (default, klass)}
# -- depends on widget class only
#
# Dialog.classes: {klass: (v0, v1, v2, ...) | 'boolean' | 'other'}
# -- totally static, though different between PackDialog and WidgetDialog
#    (but even that could be unified)

from Tkinter import *

class Option:

    varclass = StringVar            # May be overridden

    def __init__(self, dialog, option):
        self.dialog = dialog
        self.option = option
        self.master = dialog.top
        self.default, self.klass = dialog.options[option]
        self.var = self.varclass(self.master)
        self.frame = Frame(self.master)
        self.frame.pack(fill=X)
        self.label = Label(self.frame, text=(option + ":"))
        self.label.pack(side=LEFT)
        self.update()
        self.addoption()

    def refresh(self):
        self.dialog.refresh()
        self.update()

    def update(self):
        try:
            self.current = self.dialog.current[self.option]
        except KeyError:
            self.current = self.default
        self.var.set(self.current)

    def set(self, e=None):          # Should be overridden
        pass

class BooleanOption(Option):

    varclass = BooleanVar

    def addoption(self):
        self.button = Checkbutton(self.frame,
                                 text='on/off',
                                 onvalue=1,
                                 offvalue=0,
                                 variable=self.var,
                                 relief=RAISED,
                                 borderwidth=2,
                                 command=self.set)
        self.button.pack(side=RIGHT)

class EnumOption(Option):

    def addoption(self):
        self.button = Menubutton(self.frame,
                                 textvariable=self.var,
                                 relief=RAISED, borderwidth=2)
        self.button.pack(side=RIGHT)
        self.menu = Menu(self.button)
        self.button['menu'] = self.menu
        for v in self.dialog.classes[self.klass]:
            self.menu.add_radiobutton(
                label=v,
                variable=self.var,
                value=v,
                command=self.set)

class StringOption(Option):

    def addoption(self):
        self.entry = Entry(self.frame,
                           textvariable=self.var,
                           width=10,
                           relief=SUNKEN,
                           borderwidth=2)
        self.entry.pack(side=RIGHT, fill=X, expand=1)
        self.entry.bind('<Return>', self.set)

class ReadonlyOption(Option):

    def addoption(self):
        self.label = Label(self.frame, textvariable=self.var,
                           anchor=E)
        self.label.pack(side=RIGHT)

class Dialog:

    def __init__(self, master):
        self.master = master
        self.fixclasses()
        self.refresh()
        self.top = Toplevel(self.master)
        self.top.title(self.__class__.__name__)
        self.top.minsize(1, 1)
        self.addchoices()

    def refresh(self): pass         # Must override

    def fixclasses(self): pass      # May override

    def addchoices(self):
        self.choices = {}
        list = []
        for k, dc in list(self.options.items()):
            list.append((k, dc))
        list.sort()
        for k, (d, c) in list:
            try:
                cl = self.classes[c]
            except KeyError:
                cl = 'unknown'
            if type(cl) == TupleType:
                cl = self.enumoption
            elif cl == 'boolean':
                cl = self.booleanoption
            elif cl == 'readonly':
                cl = self.readonlyoption
            else:
                cl = self.stringoption
            self.choices[k] = cl(self, k)

    # Must override:
    options = {}
    classes = {}

    # May override:
    booleanoption = BooleanOption
    stringoption = StringOption
    enumoption = EnumOption
    readonlyoption = ReadonlyOption

class PackDialog(Dialog):

    def __init__(self, widget):
        self.widget = widget
        Dialog.__init__(self, widget)

    def refresh(self):
        self.current = self.widget.info()
        self.current['.class'] = self.widget.winfo_class()
        self.current['.name'] = self.widget._w

    class packoption: # Mix-in class
        def set(self, e=None):
            self.current = self.var.get()
            try:
                self.dialog.widget.pack(**{self.option: self.current})
            except TclError as msg:
                print(msg)
                self.refresh()

    class booleanoption(packoption, BooleanOption): pass
    class enumoption(packoption, EnumOption): pass
    class stringoption(packoption, StringOption): pass
    class readonlyoption(packoption, ReadonlyOption): pass

    options = {
            '.class': (None, 'Class'),
            '.name': (None, 'Name'),
            'after': (None, 'Widget'),
            'anchor': ('center', 'Anchor'),
            'before': (None, 'Widget'),
            'expand': ('no', 'Boolean'),
            'fill': ('none', 'Fill'),
            'in': (None, 'Widget'),
            'ipadx': (0, 'Pad'),
            'ipady': (0, 'Pad'),
            'padx': (0, 'Pad'),
            'pady': (0, 'Pad'),
            'side': ('top', 'Side'),
            }

    classes = {
            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
            'Boolean': 'boolean',
            'Class': 'readonly',
            'Expand': 'boolean',
            'Fill': (NONE, X, Y, BOTH),
            'Name': 'readonly',
            'Pad': 'pixel',
            'Side': (TOP, RIGHT, BOTTOM, LEFT),
            'Widget': 'readonly',
            }

class RemotePackDialog(PackDialog):

    def __init__(self, master, app, widget):
        self.master = master
        self.app = app
        self.widget = widget
        self.refresh()
        self.top = Toplevel(self.master)
        self.top.title(self.app + ' PackDialog')
        self.top.minsize(1, 1)
        self.addchoices()

    def refresh(self):
        try:
            words = self.master.tk.splitlist(
                    self.master.send(self.app,
                                     'pack',
                                     'info',
                                     self.widget))
        except TclError as msg:
            print(msg)
            return
        dict = {}
        for i in range(0, len(words), 2):
            key = words[i][1:]
            value = words[i+1]
            dict[key] = value
        dict['.class'] = self.master.send(self.app,
                                          'winfo',
                                          'class',
                                          self.widget)
        dict['.name'] = self.widget
        self.current = dict

    class remotepackoption: # Mix-in class
        def set(self, e=None):
            self.current = self.var.get()
            try:
                self.dialog.master.send(
                        self.dialog.app,
                        'pack',
                        'config',
                        self.dialog.widget,
                        '-'+self.option,
                        self.dialog.master.tk.merge(
                                self.current))
            except TclError as msg:
                print(msg)
                self.refresh()

    class booleanoption(remotepackoption, BooleanOption): pass
    class enumoption(remotepackoption, EnumOption): pass
    class stringoption(remotepackoption, StringOption): pass
    class readonlyoption(remotepackoption, ReadonlyOption): pass

class WidgetDialog(Dialog):

    def __init__(self, widget):
        self.widget = widget
        self.klass = widget.winfo_class()
        Dialog.__init__(self, widget)

    def fixclasses(self):
        if self.klass in self.addclasses:
            classes = {}
            for c in (self.classes,
                      self.addclasses[self.klass]):
                for k in list(c.keys()):
                    classes[k] = c[k]
            self.classes = classes

    def refresh(self):
        self.configuration = self.widget.config()
        self.update()
        self.current['.class'] = self.widget.winfo_class()
        self.current['.name'] = self.widget._w

    def update(self):
        self.current = {}
        self.options = {}
        for k, v in list(self.configuration.items()):
            if len(v) > 4:
                self.current[k] = v[4]
                self.options[k] = v[3], v[2] # default, klass
        self.options['.class'] = (None, 'Class')
        self.options['.name'] = (None, 'Name')

    class widgetoption: # Mix-in class
        def set(self, e=None):
            self.current = self.var.get()
            try:
                self.dialog.widget[self.option] = self.current
            except TclError as msg:
                print(msg)
                self.refresh()

    class booleanoption(widgetoption, BooleanOption): pass
    class enumoption(widgetoption, EnumOption): pass
    class stringoption(widgetoption, StringOption): pass
    class readonlyoption(widgetoption, ReadonlyOption): pass

    # Universal classes
    classes = {
            'Anchor': (N, NE, E, SE, S, SW, W, NW, CENTER),
            'Aspect': 'integer',
            'Background': 'color',
            'Bitmap': 'bitmap',
            'BorderWidth': 'pixel',
            'Class': 'readonly',
            'CloseEnough': 'double',
            'Command': 'command',
            'Confine': 'boolean',
            'Cursor': 'cursor',
            'CursorWidth': 'pixel',
            'DisabledForeground': 'color',
            'ExportSelection': 'boolean',
            'Font': 'font',
            'Foreground': 'color',
            'From': 'integer',
            'Geometry': 'geometry',
            'Height': 'pixel',
            'InsertWidth': 'time',
            'Justify': (LEFT, CENTER, RIGHT),
            'Label': 'string',
            'Length': 'pixel',
            'MenuName': 'widget',
            'Name': 'readonly',
            'OffTime': 'time',
            'OnTime': 'time',
            'Orient': (HORIZONTAL, VERTICAL),
            'Pad': 'pixel',
            'Relief': (RAISED, SUNKEN, FLAT, RIDGE, GROOVE),
            'RepeatDelay': 'time',
            'RepeatInterval': 'time',
            'ScrollCommand': 'command',
            'ScrollIncrement': 'pixel',
            'ScrollRegion': 'rectangle',
            'ShowValue': 'boolean',
            'SetGrid': 'boolean',
            'Sliderforeground': 'color',
            'SliderLength': 'pixel',
            'Text': 'string',
            'TickInterval': 'integer',
            'To': 'integer',
            'Underline': 'index',
            'Variable': 'variable',
            'Value': 'string',
            'Width': 'pixel',
            'Wrap': (NONE, CHAR, WORD),
            }

    # Classes that (may) differ per widget type
    _tristate = {'State': (NORMAL, ACTIVE, DISABLED)}
    _bistate = {'State': (NORMAL, DISABLED)}
    addclasses = {
            'Button': _tristate,
            'Radiobutton': _tristate,
            'Checkbutton': _tristate,
            'Entry': _bistate,
            'Text': _bistate,
            'Menubutton': _tristate,
            'Slider': _bistate,
            }

class RemoteWidgetDialog(WidgetDialog):

    def __init__(self, master, app, widget):
        self.app = app
        self.widget = widget
        self.klass = master.send(self.app,
                                 'winfo',
                                 'class',
                                 self.widget)
        Dialog.__init__(self, master)

    def refresh(self):
        try:
            items = self.master.tk.splitlist(
                    self.master.send(self.app,
                                     self.widget,
                                     'config'))
        except TclError as msg:
            print(msg)
            return
        dict = {}
        for item in items:
            words = self.master.tk.splitlist(item)
            key = words[0][1:]
            value = (key,) + words[1:]
            dict[key] = value
        self.configuration = dict
        self.update()
        self.current['.class'] = self.klass
        self.current['.name'] = self.widget

    class remotewidgetoption: # Mix-in class
        def set(self, e=None):
            self.current = self.var.get()
            try:
                self.dialog.master.send(
                        self.dialog.app,
                        self.dialog.widget,
                        'config',
                        '-'+self.option,
                        self.current)
            except TclError as msg:
                print(msg)
                self.refresh()

    class booleanoption(remotewidgetoption, BooleanOption): pass
    class enumoption(remotewidgetoption, EnumOption): pass
    class stringoption(remotewidgetoption, StringOption): pass
    class readonlyoption(remotewidgetoption, ReadonlyOption): pass

def test():
    import sys
    root = Tk()
    root.minsize(1, 1)
    if sys.argv[1:]:
        remotetest(root, sys.argv[1])
    else:
        frame = Frame(root, name='frame')
        frame.pack(expand=1, fill=BOTH)
        button = Button(frame, name='button', text='button')
        button.pack(expand=1)
        canvas = Canvas(frame, name='canvas')
        canvas.pack()
        fpd = PackDialog(frame)
        fwd = WidgetDialog(frame)
        bpd = PackDialog(button)
        bwd = WidgetDialog(button)
        cpd = PackDialog(canvas)
        cwd = WidgetDialog(canvas)
    root.mainloop()

def remotetest(root, app):
    from listtree import listtree
    list = listtree(root, app)
    list.bind('<Any-Double-1>', opendialogs)
    list.app = app                  # Pass it on to handler

def opendialogs(e):
    import string
    list = e.widget
    sel = list.curselection()
    for i in sel:
        item = list.get(i)
        widget = string.split(item)[0]
        RemoteWidgetDialog(list, list.app, widget)
        if widget == '.': continue
        try:
            RemotePackDialog(list, list.app, widget)
        except TclError as msg:
            print(msg)

test()
