1#
2# #### OUTDATE MODULE ####
3# This has been superceded by the tktable.py that ships in the lib area.
4# This is kept for compatibility as the newer wrapper is not 100% compatible.
5# #### OUTDATE MODULE ####
6#
7# This file is taken from the usenet:
8#    http://groups.google.com/groups?selm=351A52BC.27EA0BE2%40desys.de
9#    From: Klaus Roethemeyer <klaus.roethemeyer at desys.de>
10#
11# It is provided here as an example of using Tktable with Python/Tkinter.
12
13#============================================================================
14#
15# MODULE:	This module contains the wrapper class for the tktable widget
16#
17# CREATED:	Roethemeyer, 20.01.98
18#
19# VERSION:	$Id: tktable.py,v 1.2 2008/11/14 22:49:35 hobbs Exp $
20#
21#============================================================================
22
23#============================================================================
24# import modules
25#----------------------------------------------------------------------------
26import string, types, Tkinter
27#----------------------------------------------------------------------------
28
29#============================================================================
30# ArrayVar
31#----------------------------------------------------------------------------
32class ArrayVar(Tkinter.Variable):
33    _default = ''
34
35    def __init__(self, master = None):
36        Tkinter.Variable.__init__(self, master)
37
38    def get(self, index = None):
39        if not index:
40            res = {}
41            for i in self.names():
42                res[i] = self._tk.globalgetvar(self._name, i)
43            try: del res['None']
44            except KeyError: pass
45            return res
46        else:
47            return self._tk.globalgetvar(self._name, index)
48
49    def names(self):
50        return string.split(self._tk.call('array', 'names', self._name))
51
52    def set(self, index, value = ''):
53        if value == None:
54            value = ''
55        return self._tk.globalsetvar(self._name, index, value)
56#----------------------------------------------------------------------------
57
58
59#============================================================================
60# Table
61#----------------------------------------------------------------------------
62class Table(Tkinter.Widget):
63
64    _switches1 = ('cols', 'holddimensions', 'holdtags', 'keeptitles', 'rows', '-')
65    _tabsubst_format = ('%c', '%C', '%i', '%r', '%s', '%S', '%W')
66    _tabsubst_commands = ('browsecommand', 'browsecmd', 'command',
67                          'selectioncommand', 'selcmd',
68                          'validatecommand', 'valcmd')
69
70    def __init__(self, master, cnf={}, **kw):
71        try:
72            master.tk.call('package', 'require', 'Tktable')
73        except Tkinter.TclError:
74            master.tk.call('load', '', 'Tktable')
75        Tkinter.Widget.__init__(self, master, 'table', cnf, kw)
76
77    def _options(self, cnf, kw = None):
78        if kw:
79            cnf = Tkinter._cnfmerge((cnf, kw))
80        else:
81            cnf = Tkinter._cnfmerge(cnf)
82        res = ()
83        for k, v in cnf.items():
84            if v is not None:
85                if k[-1] == '_': k = k[:-1]
86                if callable(v):
87                    if k in self._tabsubst_commands:
88                        v = "%s %s"  % (self._register(v, self._tabsubst),
89                                        string.join(self._tabsubst_format))
90                    else:
91                        v = self._register(v)
92                res = res + ('-'+k, v)
93        return res
94
95    def _tabsubst(self, *args):
96        tk = self.tk
97        if len(args) != len(self._tabsubst_format): return args
98        c, C, i, r, s, S, W = args
99        e = Tkinter.Event()
100        e.widget = self
101        e.c = tk.getint(c)
102        e.i = tk.getint(i)
103        e.r = tk.getint(r)
104        e.C = (e.r, e.c)
105        try: e.s = tk.getint(s)
106        except Tkinter.TclError: e.s = s
107        try: e.S = tk.getint(S)
108        except Tkinter.TclError: e.S = S
109        e.W = W
110        return (e,)
111
112
113    def _getCells(self, cellString):
114        res = []
115        for i in string.split(cellString):
116            res.append(tuple(map(int, string.split(i, ','))))
117        return res
118
119    def _getLines(self, lineString):
120        return map(int, string.split(lineString))
121
122    def _prepareArgs1(self, args):
123        args = list(args)
124
125        for i in xrange(len(args)):
126            if args[i] in self._switches1:
127                args[i] = "-" + args[i]
128
129        return tuple(args)
130
131
132    def activate(self, index):
133        self.tk.call(self._w, 'activate', index)
134
135    def bbox(self, first, last=None):
136        return self._getints(self.tk.call(self._w, 'bbox', first, last)) or None
137
138    def border_mark(self, x, y, row=None, col=None):
139        self.tk.call(self._w, 'border', 'mark', x, y, row, col)
140
141    def border_dragto(self, x, y):
142        self.tk.call(self._w, 'border', 'dragto', x, y)
143
144    def curselection(self, setValue = None):
145        if setValue != None:
146            self.tk.call(self._w, 'curselection', 'set', setValue)
147
148        else:
149            return self._getCells(self.tk.call(self._w, 'curselection'))
150
151    def delete_active(self, index, more = None):
152        self.tk.call(self._w, 'delete', 'active', index, more)
153
154    def delete_cols(self, *args):
155        apply(self.tk.call, (self._w, 'delete', 'cols') + self._prepareArgs1(args))
156
157    def delete_rows(self, *args):
158        apply(self.tk.call, (self._w, 'delete', 'rows') + self._prepareArgs1(args))
159
160    def flush(self, first=None, last=None):
161        self.tk.call(self._w, 'flush', first, last)
162
163    def get(self, first, last=None):
164        return self.tk.call(self._w, 'get', first, last)
165
166    def height(self, *args):
167        apply(self.tk.call, (self._w, 'height') + args)
168
169    def icursor(self, arg):
170        self.tk.call(self._w, 'icursor', arg)
171
172    def index(self, index, rc = None):
173        if rc == None:
174            return self._getCells(self.tk.call(self._w, 'index', index, rc))[0]
175        else:
176            return self._getCells(self.tk.call(self._w, 'index', index, rc))[0][0]
177
178    def insert_active(self, index, value):
179        self.tk.call(self._w, 'insert', 'active', index, value)
180
181    def insert_cols(self, *args):
182        apply(self.tk.call, (self._w, 'insert', 'cols') + self._prepareArgs1(args))
183
184    def insert_rows(self, *args):
185        apply(self.tk.call, (self._w, 'insert', 'rows') + self._prepareArgs1(args))
186
187    def reread(self):
188        self.tk.call(self._w, 'reread')
189
190    def scan_mark(self, x, y):
191        self.tk.call(self._w, 'scan', 'mark', x, y)
192
193    def scan_dragto(self, x, y):
194        self.tk.call(self._w, 'scan', 'dragto', x, y)
195
196    def see(self, index):
197        self.tk.call(self._w, 'see', index)
198
199    def selection_anchor(self, index):
200        self.tk.call(self._w, 'selection', 'anchor', index)
201
202    def selection_clear(self, first, last=None):
203        self.tk.call(self._w, 'selection', 'clear', first, last)
204
205    def selection_includes(self, index):
206        return int(self.tk.call(self._w, 'selection', 'includes', index))
207
208    def selection_set(self, first, last=None):
209        self.tk.call(self._w, 'selection', 'set', first, last)
210
211    def set(self, *args):
212        apply(self.tk.call, (self._w, 'set') + args)
213
214    def tag_cell(self, tagName, *args):
215        result = apply(self.tk.call, (self._w, 'tag', 'cell', tagName) + args)
216        if not args: return self._getCells(result)
217
218    def tag_cget(self, tagName, option):
219        return self.tk.call(self._w, 'tag', 'cget', tagName, '-' + option)
220
221    def tag_col(self, tagName, *args):
222        result = apply(self.tk.call, (self._w, 'tag', 'col', tagName) + args)
223        if not args: return self._getLines(result)
224
225    def tag_configure(self, tagName, cnf={}, **kw):
226        if not cnf and not kw:
227            return self.tk.call(self._w, 'tag', 'configure', tagName)
228        if type(cnf) == types.StringType and not kw:
229            return self.tk.call(self._w, 'tag', 'configure', tagName, '-' + cnf)
230        if type(cnf) == types.DictType:
231            apply(self.tk.call,
232                  (self._w, 'tag', 'configure', tagName)
233                  + self._options(cnf, kw))
234        else:
235            raise TypeError, "usage: <instance>.tag_configure tagName [option] | [option=value]+"
236
237    def tag_delete(self, tagName):
238        self.tk.call(self._w, 'tag', 'delete', tagName)
239
240    def tag_exists(self, tagName):
241        return self.getboolean(self.tk.call(self._w, 'tag', 'exists', tagName))
242
243    def tag_includes(self, tagName, index):
244        return self.getboolean(self.tk.call(self._w, 'tag', 'includes', tagName, index))
245
246    def tag_names(self, pattern=None):
247        return self.tk.call(self._w, 'tag', 'names', pattern)
248
249    def tag_row(self, tagName, *args):
250        result = apply(self.tk.call, (self._w, 'tag', 'row', tagName) + args)
251        if not args: return self._getLines(result)
252
253    def validate(self, index):
254        self.tk.call(self._w, 'validate', index)
255
256    def width(self, *args):
257        result = apply(self.tk.call, (self._w, 'width') + args)
258        if not args:
259            str = string.replace(result, '{', '')
260            str = string.replace(str, '}', '')
261            lst = string.split(str)
262            x = len(lst)
263            x2 = x / 2
264            return tuple(map(lambda i, j, l=lst: (int(l[i]), int(l[j])),
265                             xrange(x2), xrange(x2, x)))
266        elif len(args) == 1:
267            return int(result)
268        else:
269            return result
270
271    def xview(self, *args):
272        if not args:
273            return self._getdoubles(self.tk.call(self._w, 'xview'))
274        apply(self.tk.call, (self._w, 'xview') + args)
275
276    def yview(self, *args):
277        if not args:
278            return self._getdoubles(self.tk.call(self._w, 'yview'))
279        apply(self.tk.call, (self._w, 'yview') + args)
280#----------------------------------------------------------------------------
281
282
283#============================================================================
284# Test-Function
285#----------------------------------------------------------------------------
286if __name__ == '__main__':
287    from Tkinter import Tk, Label, Button
288    import pprint
289
290    prn = pprint.PrettyPrinter(indent = 6).pprint
291
292    def test_cmd(event=None):
293        if event.i == 0:
294            return '%i, %i' % (event.r, event.c)
295        else:
296            return 'set'
297
298
299    def browsecmd(event):
300        print "event:", event.__dict__
301        print "curselection:", test.curselection()
302        print "active:", test.index('active', 'row')
303        print "anchor:", test.index('anchor', 'row')
304
305    root = Tk()
306    #root.tk.call('load', '', 'Tktable')
307
308    var = ArrayVar(root)
309    for y in range(-1, 4):
310        for x in range(-1, 5):
311            index = "%i,%i" % (y, x)
312            var.set(index, index)
313
314    label = Label(root, text="Proof-of-existence test for Tktable")
315    label.pack(side = 'top', fill = 'x')
316
317    quit = Button(root, text="QUIT", command=root.destroy)
318    quit.pack(side = 'bottom', fill = 'x')
319
320    test = Table(root,
321                 rows=10,
322                 cols=5,
323                 state='disabled',
324                 width=6,
325                 height=6,
326                 titlerows=1,
327                 titlecols=1,
328                 roworigin=-1,
329                 colorigin=-1,
330                 selectmode='browse',
331                 selecttype='row',
332                 rowstretch='unset',
333                 colstretch='last',
334                 browsecmd=browsecmd,
335                 flashmode='on',
336                 variable=var,
337                 usecommand=0,
338                 command=test_cmd)
339    test.pack(expand=1, fill='both')
340    test.tag_configure('sel', background = 'yellow')
341    test.tag_configure('active', background = 'blue')
342    test.tag_configure('title', anchor='w', bg='red', relief='sunken')
343    root.mainloop()
344#----------------------------------------------------------------------------
345