~ubuntu-branches/ubuntu/dapper/newt/dapper

« back to all changes in this revision

Viewing changes to snack.py

  • Committer: Bazaar Package Importer
  • Author(s): Colin Watson
  • Date: 2005-03-22 12:44:37 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050322124437-nuhl0pqjcijjno9z
Tags: 0.51.6-20ubuntu3
Add Xhosa translation (thanks, Adi Attar).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# snack.py: maps C extension module _snack to proper python types in module
2
 
# snack.
3
 
# The first section is a very literal mapping.
4
 
# The second section contains convenience classes that amalgamate
5
 
# the literal classes and make them more object-oriented.
6
 
 
7
 
import _snack
8
 
import types
9
 
import string
10
 
 
11
 
snackArgs = {}
12
 
snackArgs['append'] = -1
13
 
 
14
 
FLAG_DISABLED = _snack.FLAG_DISABLED
15
 
FLAGS_SET = _snack.FLAGS_SET
16
 
FLAGS_RESET = _snack.FLAGS_RESET
17
 
FLAGS_TOGGLE = _snack.FLAGS_TOGGLE
18
 
 
19
 
class Widget:
20
 
    def setCallback(self, obj, data = None):
21
 
        if data:
22
 
            self.w.setCallback(obj, data)
23
 
        else:
24
 
            self.w.setCallback(obj)
25
 
 
26
 
class Button(Widget):
27
 
 
28
 
    def __init__(self, text):
29
 
        self.w = _snack.button(text)
30
 
 
31
 
class Checkbox(Widget):
32
 
 
33
 
    def value(self):
34
 
        return self.w.checkboxValue
35
 
 
36
 
    def selected(self):
37
 
        return self.w.checkboxValue != 0
38
 
 
39
 
    def setFlags (self, flag, sense):
40
 
        return self.w.checkboxSetFlags(flag, sense)
41
 
 
42
 
    def setValue (self, value):
43
 
        return self.w.checkboxSetValue(value)
44
 
 
45
 
    def __init__(self, text, isOn = 0):
46
 
        self.w = _snack.checkbox(text, isOn)
47
 
 
48
 
class SingleRadioButton(Widget):
49
 
 
50
 
    def selected(self):
51
 
        return self.w.key == self.w.radioValue;
52
 
    
53
 
    def __init__(self, text, group, isOn = 0):
54
 
        if group:
55
 
            self.w = _snack.radiobutton(text, group.w, isOn)
56
 
        else:
57
 
            self.w = _snack.radiobutton(text, None, isOn)
58
 
 
59
 
class Listbox(Widget):
60
 
 
61
 
    def append(self, text, item):
62
 
        key = self.w.listboxAddItem(text)
63
 
        self.key2item[key] = item
64
 
        self.item2key[item] = key
65
 
 
66
 
    def insert(self, text, item, before):
67
 
        if (not before):
68
 
            key = self.w.listboxInsertItem(text, 0)
69
 
        else:
70
 
            key = self.w.listboxInsertItem(text, self.item2key[before])
71
 
        self.key2item[key] = item
72
 
        self.item2key[item] = key
73
 
 
74
 
    def delete(self, item):
75
 
        self.w.listboxDeleteItem(self.item2key[item])
76
 
        del self.key2item[self.item2key[item]]
77
 
        del self.item2key[item]
78
 
 
79
 
    def replace(self, text, item):
80
 
        key = self.w.listboxInsertItem(text, self.item2key[item])
81
 
        self.w.listboxDeleteItem(self.item2key[item])
82
 
        del self.key2item[self.item2key[item]]
83
 
        self.item2key[item] = key
84
 
        self.key2item[key] = item
85
 
 
86
 
    def current(self):
87
 
        return self.key2item[self.w.listboxGetCurrent()]
88
 
 
89
 
    def setCurrent(self, item):
90
 
        self.w.listboxSetCurrent(self.item2key[item])
91
 
 
92
 
    def __init__(self, height, scroll = 0, returnExit = 0, width = 0):
93
 
        self.w = _snack.listbox(height, scroll, returnExit)
94
 
        self.key2item = {}
95
 
        self.item2key = {}
96
 
        if (width):
97
 
            self.w.listboxSetWidth(width)
98
 
 
99
 
class Textbox(Widget):
100
 
 
101
 
    def setText(self, text):
102
 
        self.w.textboxText(text)
103
 
 
104
 
    def __init__(self, width, height, text, scroll = 0, wrap = 0):
105
 
        self.w = _snack.textbox(width, height, text, scroll, wrap)
106
 
 
107
 
class TextboxReflowed(Textbox):
108
 
 
109
 
    def __init__(self, width, text, flexDown = 5, flexUp = 10, maxHeight = -1):
110
 
        (newtext, width, height) = reflow(text, width, flexDown, flexUp)
111
 
        if maxHeight != -1 and height > maxHeight:
112
 
            Textbox.__init__(self, width, maxHeight, newtext, 1)
113
 
        else:
114
 
            Textbox.__init__(self, width, height, newtext, 0)
115
 
 
116
 
class Label(Widget):
117
 
 
118
 
    def setText(self, text):
119
 
        self.w.labelText(text)
120
 
 
121
 
    def __init__(self, text):
122
 
        self.w = _snack.label(text)
123
 
 
124
 
class Scale(Widget):
125
 
 
126
 
    def set(self, amount):
127
 
        self.w.scaleSet(amount)
128
 
 
129
 
    def __init__(self, width, total):
130
 
        self.w = _snack.scale(width, total)
131
 
 
132
 
class Entry(Widget):
133
 
 
134
 
    def value(self):
135
 
        return self.w.entryValue
136
 
 
137
 
    def set(self, text):
138
 
        return self.w.entrySetValue(text)
139
 
 
140
 
    def setFlags (self, flag, sense):
141
 
        return self.w.entrySetFlags(flag, sense)
142
 
 
143
 
    def __init__(self, width, text = "", hidden = 0, password = 0, scroll = 1, 
144
 
                 returnExit = 0):
145
 
        self.w = _snack.entry(width, text, hidden, password, scroll, returnExit)
146
 
 
147
 
 
148
 
# Form uses hotkeys
149
 
hotkeys = { "F1" : _snack.KEY_F1, "F2" : _snack.KEY_F2, "F3" : _snack.KEY_F3, 
150
 
            "F4" : _snack.KEY_F4, "F5" : _snack.KEY_F5, "F6" : _snack.KEY_F6, 
151
 
            "F7" : _snack.KEY_F7, "F8" : _snack.KEY_F8, "F9" : _snack.KEY_F9, 
152
 
            "F10" : _snack.KEY_F10, "F11" : _snack.KEY_F11, 
153
 
            "F12" : _snack.KEY_F12, " " : ord(" ") }
154
 
 
155
 
for n in hotkeys.keys():
156
 
    hotkeys[hotkeys[n]] = n
157
 
 
158
 
class Form:
159
 
 
160
 
    def addHotKey(self, keyname):
161
 
        self.w.addhotkey(hotkeys[keyname])
162
 
 
163
 
    def add(self, widget):
164
 
        if widget.__dict__.has_key('hotkeys'):
165
 
            for key in widget.hotkeys.keys():
166
 
                self.addHotKey(key)
167
 
 
168
 
        if widget.__dict__.has_key('gridmembers'):
169
 
            for w in widget.gridmembers:
170
 
                self.add(w)
171
 
        elif widget.__dict__.has_key('w'):
172
 
            self.trans[widget.w.key] = widget
173
 
            return self.w.add(widget.w)
174
 
        return None
175
 
 
176
 
    def run(self):
177
 
        (what, which) = self.w.run()
178
 
        if (what == _snack.FORM_EXIT_WIDGET):
179
 
            return self.trans[which]
180
 
        elif (what == _snack.FORM_EXIT_TIMER):
181
 
            return "TIMER"
182
 
 
183
 
        return hotkeys[which]
184
 
 
185
 
    def draw(self):
186
 
        self.w.draw()
187
 
        return None
188
 
 
189
 
    def __init__(self, helpArg = None):
190
 
        self.trans = {}
191
 
        self.w = _snack.form(helpArg)
192
 
        # we do the reference count for the helpArg in python! gross
193
 
        self.helpArg = helpArg
194
 
 
195
 
    def setCurrent (self, co):
196
 
        self.w.setcurrent (co.w)
197
 
 
198
 
    def setTimer (self, timer):
199
 
        self.w.settimer (timer)
200
 
 
201
 
class Grid:
202
 
 
203
 
    def place(self, x, y):
204
 
        return self.g.place(x, y)
205
 
 
206
 
    def setField(self, what, col, row, padding = (0, 0, 0, 0),
207
 
                 anchorLeft = 0, anchorTop = 0, anchorRight = 0,
208
 
                 anchorBottom = 0, growx = 0, growy = 0):
209
 
        self.gridmembers.append(what)
210
 
        anchorFlags = 0
211
 
        if (anchorLeft):
212
 
            anchorFlags = _snack.ANCHOR_LEFT
213
 
        elif (anchorRight):
214
 
            anchorFlags = _snack.ANCHOR_RIGHT
215
 
 
216
 
        if (anchorTop):
217
 
            anchorFlags = anchorFlags | _snack.ANCHOR_TOP
218
 
        elif (anchorBottom):
219
 
            anchorFlags = anchorFlags | _snack.ANCHOR_BOTTOM
220
 
 
221
 
        gridFlags = 0
222
 
        if (growx):
223
 
            gridFlags = _snack.GRID_GROWX
224
 
        if (growy):
225
 
            gridFlags = gridFlags | _snack.GRID_GROWY
226
 
 
227
 
        if (what.__dict__.has_key('g')):
228
 
            return self.g.setfield(col, row, what.g, padding, anchorFlags,
229
 
                                   gridFlags)
230
 
        else:
231
 
            return self.g.setfield(col, row, what.w, padding, anchorFlags)
232
 
 
233
 
    def __init__(self, *args):
234
 
        self.g = apply(_snack.grid, args)
235
 
        self.gridmembers = []
236
 
 
237
 
class SnackScreen:
238
 
 
239
 
    def __init__(self):
240
 
        _snack.init()
241
 
        (self.width, self.height) = _snack.size()
242
 
        self.pushHelpLine(None)
243
 
 
244
 
    def finish(self):
245
 
        return _snack.finish()
246
 
 
247
 
    def resume(self):
248
 
        _snack.resume()
249
 
 
250
 
    def suspend(self):
251
 
        _snack.suspend()
252
 
 
253
 
    def doHelpCallback(self, arg):
254
 
        self.helpCb(self, arg)
255
 
 
256
 
    def helpCallback(self, cb):
257
 
        self.helpCb = cb
258
 
        return _snack.helpcallback(self.doHelpCallback)
259
 
 
260
 
    def suspendCallback(self, cb, data = None):
261
 
        if data:
262
 
            return _snack.suspendcallback(cb, data)
263
 
        return _snack.suspendcallback(cb)
264
 
 
265
 
    def openWindow(self, left, top, width, height, title):
266
 
        return _snack.openwindow(left, top, width, height, title)
267
 
 
268
 
    def pushHelpLine(self, text):
269
 
        if (not text):
270
 
            return _snack.pushhelpline("*default*")
271
 
        else:
272
 
            return _snack.pushhelpline(text)
273
 
 
274
 
    def popHelpLine(self):
275
 
        return _snack.pophelpline()
276
 
 
277
 
    def drawRootText(self, left, top, text):
278
 
        return _snack.drawroottext(left, top, text)
279
 
 
280
 
    def centeredWindow(self, width, height, title):
281
 
        return _snack.centeredwindow(width, height, title)
282
 
 
283
 
    def gridWrappedWindow(self, grid, title, x = None, y = None):
284
 
        if x and y:
285
 
            return _snack.gridwrappedwindow(grid.g, title, x, y)
286
 
 
287
 
        return _snack.gridwrappedwindow(grid.g, title)
288
 
 
289
 
    def popWindow(self):
290
 
        return _snack.popwindow()
291
 
 
292
 
    def refresh(self):
293
 
        return _snack.refresh()
294
 
 
295
 
# returns a tuple of the wrapped text, the actual width, and the actual height
296
 
def reflow(text, width, flexDown = 5, flexUp = 5):
297
 
    return _snack.reflow(text, width, flexDown, flexUp)
298
 
 
299
 
# combo widgets
300
 
 
301
 
class RadioGroup(Widget):
302
 
 
303
 
    def __init__(self):
304
 
        self.prev = None
305
 
        self.buttonlist = []
306
 
 
307
 
    def add(self, title, value, default = None):
308
 
        if not self.prev and default == None:
309
 
            # If the first element is not explicitly set to
310
 
            # not be the default, make it be the default
311
 
            default = 1
312
 
        b = SingleRadioButton(title, self.prev, default)
313
 
        self.prev = b
314
 
        self.buttonlist.append((b, value))
315
 
        return b
316
 
 
317
 
    def getSelection(self):
318
 
        for (b, value) in self.buttonlist:
319
 
            if b.selected(): return value
320
 
        return None
321
 
 
322
 
 
323
 
class RadioBar(Grid):
324
 
 
325
 
    def __init__(self, screen, buttonlist):
326
 
        self.list = []
327
 
        self.item = 0
328
 
        self.group = RadioGroup()
329
 
        Grid.__init__(self, 1, len(buttonlist))
330
 
        for (title, value, default) in buttonlist:
331
 
            b = self.group.add(title, value, default)
332
 
            self.list.append((b, value))
333
 
            self.setField(b, 0, self.item, anchorLeft = 1)
334
 
            self.item = self.item + 1
335
 
 
336
 
    def getSelection(self):
337
 
        return self.group.getSelection()
338
 
        
339
 
 
340
 
# you normally want to pack a ButtonBar with growx = 1
341
 
 
342
 
class ButtonBar(Grid):
343
 
 
344
 
    def __init__(self, screen, buttonlist):
345
 
        self.list = []
346
 
        self.hotkeys = {}
347
 
        self.item = 0
348
 
        Grid.__init__(self, len(buttonlist), 1)
349
 
        for blist in buttonlist:
350
 
            if (type(blist) == types.StringType):
351
 
                title = blist
352
 
                value = string.lower(blist)
353
 
            elif len(blist) == 2:
354
 
                (title, value) = blist
355
 
            else:
356
 
                (title, value, hotkey) = blist
357
 
                self.hotkeys[hotkey] = value
358
 
 
359
 
            b = Button(title)
360
 
            self.list.append((b, value))
361
 
            self.setField(b, self.item, 0, (1, 0, 1, 0))
362
 
            self.item = self.item + 1
363
 
 
364
 
    def buttonPressed(self, result):
365
 
        """Takes the widget returned by Form.run and looks to see
366
 
        if it was one of the widgets in the ButtonBar."""
367
 
 
368
 
        if self.hotkeys.has_key(result):
369
 
            return self.hotkeys[result]
370
 
 
371
 
        for (button, value) in self.list:
372
 
            if result == button:
373
 
                return value
374
 
        return None
375
 
 
376
 
 
377
 
class GridFormHelp(Grid):
378
 
 
379
 
    def __init__(self, screen, title, help, *args):
380
 
        self.screen = screen
381
 
        self.title = title
382
 
        self.form = Form(help)
383
 
        self.childList = []
384
 
        self.form_created = 0
385
 
        args = list(args)
386
 
        args[:0] = [self]
387
 
        apply(Grid.__init__, tuple(args))
388
 
 
389
 
    def add(self, widget, col, row, padding = (0, 0, 0, 0),
390
 
            anchorLeft = 0, anchorTop = 0, anchorRight = 0,
391
 
            anchorBottom = 0, growx = 0, growy = 0):
392
 
        self.setField(widget, col, row, padding, anchorLeft,
393
 
                      anchorTop, anchorRight, anchorBottom,
394
 
                      growx, growy);
395
 
        self.childList.append(widget)
396
 
 
397
 
    def runOnce(self, x = None, y = None):
398
 
        result = self.run(x, y)
399
 
        self.screen.popWindow()
400
 
        return result
401
 
 
402
 
    def addHotKey(self, keyname):
403
 
        self.form.addHotKey(keyname)
404
 
 
405
 
    def setTimer(self, keyname):
406
 
        self.form.setTimer(keyname)
407
 
 
408
 
    def create(self, x = None, y = None):
409
 
        if not self.form_created:
410
 
            self.place(1,1)
411
 
            for child in self.childList:
412
 
                self.form.add(child)
413
 
            self.screen.gridWrappedWindow(self, self.title, x, y)
414
 
            self.form_created = 1
415
 
 
416
 
    def run(self, x = None, y = None):
417
 
        self.create(x, y)
418
 
        return self.form.run()
419
 
 
420
 
    def draw(self):
421
 
        self.create()
422
 
        return self.form.draw()
423
 
        
424
 
    def runPopup(self):
425
 
        self.create()
426
 
        self.screen.gridWrappedWindow(self, self.title)
427
 
        result = self.form.run()
428
 
        self.screen.popWindow()
429
 
        return result
430
 
 
431
 
    def setCurrent (self, co):
432
 
        self.form.setCurrent (co)
433
 
 
434
 
class GridForm(GridFormHelp):
435
 
 
436
 
    def __init__(self, screen, title, *args):
437
 
        myargs = (self, screen, title, None) + args
438
 
        apply(GridFormHelp.__init__, myargs)
439
 
 
440
 
class CheckboxTree(Widget):
441
 
    def append(self, text, item = None, selected = 0):
442
 
        self.addItem(text, (snackArgs['append'], ), item, selected)
443
 
 
444
 
    def addItem(self, text, path, item = None, selected = 0):
445
 
        if (not item):
446
 
            item = text
447
 
        key = self.w.checkboxtreeAddItem(text, path, selected)
448
 
        self.key2item[key] = item
449
 
        self.item2key[item] = key
450
 
 
451
 
    def getCurrent(self):
452
 
        curr = self.w.checkboxtreeGetCurrent()
453
 
        return self.key2item[curr]
454
 
 
455
 
    def __init__(self, height, scroll = 0):
456
 
        self.w = _snack.checkboxtree(height, scroll)
457
 
        self.key2item = {}
458
 
        self.item2key = {}
459
 
 
460
 
    def getSelection(self):
461
 
        selection = []
462
 
        list = self.w.checkboxtreeGetSelection()
463
 
        for key in list:
464
 
            selection.append(self.key2item[key])
465
 
        return selection
466
 
 
467
 
    def setEntry(self, item, text):
468
 
        self.w.checkboxtreeSetEntry(self.item2key[item], text)
469
 
 
470
 
    def setEntryValue(self, item, selected = 1):
471
 
        self.w.checkboxtreeSetEntryValue(self.item2key[item], selected)
472
 
 
473
 
    def getEntryValue(self, item):
474
 
        return self.w.checkboxtreeGetEntryValue(self.item2key[item])
475
 
 
476
 
def ListboxChoiceWindow(screen, title, text, items, 
477
 
                        buttons = ('Ok', 'Cancel'), 
478
 
                        width = 40, scroll = 0, height = -1, default = None,
479
 
                        help = None):
480
 
    if (height == -1): height = len(items)
481
 
 
482
 
    bb = ButtonBar(screen, buttons)
483
 
    t = TextboxReflowed(width, text)
484
 
    l = Listbox(height, scroll = scroll, returnExit = 1)
485
 
    count = 0
486
 
    for item in items:
487
 
        if (type(item) == types.TupleType):
488
 
            (text, key) = item
489
 
        else:
490
 
            text = item
491
 
            key = count
492
 
 
493
 
        if (default == count):
494
 
            default = key
495
 
        elif (default == item):
496
 
            default = key
497
 
 
498
 
        l.append(text, key)
499
 
        count = count + 1
500
 
 
501
 
    if (default != None):
502
 
        l.setCurrent (default)
503
 
 
504
 
    g = GridFormHelp(screen, title, help, 1, 3)
505
 
    g.add(t, 0, 0)
506
 
    g.add(l, 0, 1, padding = (0, 1, 0, 1))
507
 
    g.add(bb, 0, 2, growx = 1)
508
 
 
509
 
    rc = g.runOnce()
510
 
 
511
 
    return (bb.buttonPressed(rc), l.current())
512
 
 
513
 
def ButtonChoiceWindow(screen, title, text, 
514
 
                       buttons = [ 'Ok', 'Cancel' ], 
515
 
                       width = 40, x = None, y = None, help = None):
516
 
    bb = ButtonBar(screen, buttons)
517
 
    t = TextboxReflowed(width, text, maxHeight = screen.height - 12)
518
 
 
519
 
    g = GridFormHelp(screen, title, help, 1, 2)
520
 
    g.add(t, 0, 0, padding = (0, 0, 0, 1))
521
 
    g.add(bb, 0, 1, growx = 1)
522
 
    return bb.buttonPressed(g.runOnce(x, y))
523
 
 
524
 
def EntryWindow(screen, title, text, prompts, allowCancel = 1, width = 40,
525
 
                entryWidth = 20, buttons = [ 'Ok', 'Cancel' ], help = None):
526
 
    bb = ButtonBar(screen, buttons);
527
 
    t = TextboxReflowed(width, text)
528
 
 
529
 
    count = 0
530
 
    for n in prompts:
531
 
        count = count + 1
532
 
 
533
 
    sg = Grid(2, count)
534
 
 
535
 
    count = 0
536
 
    entryList = []
537
 
    for n in prompts:
538
 
        if (type(n) == types.TupleType):
539
 
            (n, e) = n
540
 
        else:
541
 
            e = Entry(entryWidth)
542
 
 
543
 
        sg.setField(Label(n), 0, count, padding = (0, 0, 1, 0), anchorLeft = 1)
544
 
        sg.setField(e, 1, count, anchorLeft = 1)
545
 
        count = count + 1
546
 
        entryList.append(e)
547
 
 
548
 
    g = GridFormHelp(screen, title, help, 1, 3)
549
 
 
550
 
    g.add(t, 0, 0, padding = (0, 0, 0, 1))
551
 
    g.add(sg, 0, 1, padding = (0, 0, 0, 1))
552
 
    g.add(bb, 0, 2, growx = 1)
553
 
 
554
 
    result = g.runOnce()
555
 
 
556
 
    entryValues = []
557
 
    count = 0
558
 
    for n in prompts:
559
 
        entryValues.append(entryList[count].value())
560
 
        count = count + 1
561
 
 
562
 
    return (bb.buttonPressed(result), tuple(entryValues))