1# Tix.py -- Tix widget wrappers.
2#
3#       For Tix, see http://tix.sourceforge.net
4#
5#       - Sudhir Shenoy (sshenoy@gol.com), Dec. 1995.
6#         based on an idea of Jean-Marc Lugrin (lugrin@ms.com)
7#
8# NOTE: In order to minimize changes to Tkinter.py, some of the code here
9#       (TixWidget.__init__) has been taken from Tkinter (Widget.__init__)
10#       and will break if there are major changes in Tkinter.
11#
12# The Tix widgets are represented by a class hierarchy in python with proper
13# inheritance of base classes.
14#
15# As a result after creating a 'w = StdButtonBox', I can write
16#              w.ok['text'] = 'Who Cares'
17#    or              w.ok['bg'] = w['bg']
18# or even       w.ok.invoke()
19# etc.
20#
21# Compare the demo tixwidgets.py to the original Tcl program and you will
22# appreciate the advantages.
23#
24
25import os
26import Tkinter
27from Tkinter import *
28from Tkinter import _flatten, _cnfmerge
29
30# WARNING - TkVersion is a limited precision floating point number
31if TkVersion < 3.999:
32    raise ImportError, "This version of Tix.py requires Tk 4.0 or higher"
33
34import _tkinter # If this fails your Python may not be configured for Tk
35
36# Some more constants (for consistency with Tkinter)
37WINDOW = 'window'
38TEXT = 'text'
39STATUS = 'status'
40IMMEDIATE = 'immediate'
41IMAGE = 'image'
42IMAGETEXT = 'imagetext'
43BALLOON = 'balloon'
44AUTO = 'auto'
45ACROSSTOP = 'acrosstop'
46
47# A few useful constants for the Grid widget
48ASCII = 'ascii'
49CELL = 'cell'
50COLUMN = 'column'
51DECREASING = 'decreasing'
52INCREASING = 'increasing'
53INTEGER = 'integer'
54MAIN = 'main'
55MAX = 'max'
56REAL = 'real'
57ROW = 'row'
58S_REGION = 's-region'
59X_REGION = 'x-region'
60Y_REGION = 'y-region'
61
62# Some constants used by Tkinter dooneevent()
63TCL_DONT_WAIT     = 1 << 1
64TCL_WINDOW_EVENTS = 1 << 2
65TCL_FILE_EVENTS   = 1 << 3
66TCL_TIMER_EVENTS  = 1 << 4
67TCL_IDLE_EVENTS   = 1 << 5
68TCL_ALL_EVENTS    = 0
69
70# BEWARE - this is implemented by copying some code from the Widget class
71#          in Tkinter (to override Widget initialization) and is therefore
72#          liable to break.
73
74# Could probably add this to Tkinter.Misc
75class tixCommand:
76    """The tix commands provide access to miscellaneous  elements
77    of  Tix's  internal state and the Tix application context.
78    Most of the information manipulated by these  commands pertains
79    to  the  application  as a whole, or to a screen or
80    display, rather than to a particular window.
81
82    This is a mixin class, assumed to be mixed to Tkinter.Tk
83    that supports the self.tk.call method.
84    """
85
86    def tix_addbitmapdir(self, directory):
87        """Tix maintains a list of directories under which
88        the  tix_getimage  and tix_getbitmap commands will
89        search for image files. The standard bitmap  directory
90        is $TIX_LIBRARY/bitmaps. The addbitmapdir command
91        adds directory into this list. By  using  this
92        command, the  image  files  of an applications can
93        also be located using the tix_getimage or tix_getbitmap
94        command.
95        """
96        return self.tk.call('tix', 'addbitmapdir', directory)
97
98    def tix_cget(self, option):
99        """Returns  the  current  value  of the configuration
100        option given by option. Option may be  any  of  the
101        options described in the CONFIGURATION OPTIONS section.
102        """
103        return self.tk.call('tix', 'cget', option)
104
105    def tix_configure(self, cnf=None, **kw):
106        """Query or modify the configuration options of the Tix application
107        context. If no option is specified, returns a dictionary all of the
108        available options.  If option is specified with no value, then the
109        command returns a list describing the one named option (this list
110        will be identical to the corresponding sublist of the value
111        returned if no option is specified).  If one or more option-value
112        pairs are specified, then the command modifies the given option(s)
113        to have the given value(s); in this case the command returns an
114        empty string. Option may be any of the configuration options.
115        """
116        # Copied from Tkinter.py
117        if kw:
118            cnf = _cnfmerge((cnf, kw))
119        elif cnf:
120            cnf = _cnfmerge(cnf)
121        if cnf is None:
122            return self._getconfigure('tix', 'configure')
123        if isinstance(cnf, StringType):
124            return self._getconfigure1('tix', 'configure', '-'+cnf)
125        return self.tk.call(('tix', 'configure') + self._options(cnf))
126
127    def tix_filedialog(self, dlgclass=None):
128        """Returns the file selection dialog that may be shared among
129        different calls from this application.  This command will create a
130        file selection dialog widget when it is called the first time. This
131        dialog will be returned by all subsequent calls to tix_filedialog.
132        An optional dlgclass parameter can be passed to specified what type
133        of file selection dialog widget is desired. Possible options are
134        tix FileSelectDialog or tixExFileSelectDialog.
135        """
136        if dlgclass is not None:
137            return self.tk.call('tix', 'filedialog', dlgclass)
138        else:
139            return self.tk.call('tix', 'filedialog')
140
141    def tix_getbitmap(self, name):
142        """Locates a bitmap file of the name name.xpm or name in one of the
143        bitmap directories (see the tix_addbitmapdir command above).  By
144        using tix_getbitmap, you can avoid hard coding the pathnames of the
145        bitmap files in your application. When successful, it returns the
146        complete pathname of the bitmap file, prefixed with the character
147        '@'.  The returned value can be used to configure the -bitmap
148        option of the TK and Tix widgets.
149        """
150        return self.tk.call('tix', 'getbitmap', name)
151
152    def tix_getimage(self, name):
153        """Locates an image file of the name name.xpm, name.xbm or name.ppm
154        in one of the bitmap directories (see the addbitmapdir command
155        above). If more than one file with the same name (but different
156        extensions) exist, then the image type is chosen according to the
157        depth of the X display: xbm images are chosen on monochrome
158        displays and color images are chosen on color displays. By using
159        tix_ getimage, you can avoid hard coding the pathnames of the
160        image files in your application. When successful, this command
161        returns the name of the newly created image, which can be used to
162        configure the -image option of the Tk and Tix widgets.
163        """
164        return self.tk.call('tix', 'getimage', name)
165
166    def tix_option_get(self, name):
167        """Gets  the options  maintained  by  the  Tix
168        scheme mechanism. Available options include:
169
170            active_bg       active_fg      bg
171            bold_font       dark1_bg       dark1_fg
172            dark2_bg        dark2_fg       disabled_fg
173            fg              fixed_font     font
174            inactive_bg     inactive_fg    input1_bg
175            input2_bg       italic_font    light1_bg
176            light1_fg       light2_bg      light2_fg
177            menu_font       output1_bg     output2_bg
178            select_bg       select_fg      selector
179            """
180        # could use self.tk.globalgetvar('tixOption', name)
181        return self.tk.call('tix', 'option', 'get', name)
182
183    def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None):
184        """Resets the scheme and fontset of the Tix application to
185        newScheme and newFontSet, respectively.  This affects only those
186        widgets created after this call. Therefore, it is best to call the
187        resetoptions command before the creation of any widgets in a Tix
188        application.
189
190        The optional parameter newScmPrio can be given to reset the
191        priority level of the Tk options set by the Tix schemes.
192
193        Because of the way Tk handles the X option database, after Tix has
194        been has imported and inited, it is not possible to reset the color
195        schemes and font sets using the tix config command.  Instead, the
196        tix_resetoptions command must be used.
197        """
198        if newScmPrio is not None:
199            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio)
200        else:
201            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet)
202
203class Tk(Tkinter.Tk, tixCommand):
204    """Toplevel widget of Tix which represents mostly the main window
205    of an application. It has an associated Tcl interpreter."""
206    def __init__(self, screenName=None, baseName=None, className='Tix'):
207        Tkinter.Tk.__init__(self, screenName, baseName, className)
208        tixlib = os.environ.get('TIX_LIBRARY')
209        self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]')
210        if tixlib is not None:
211            self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib)
212            self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib)
213        # Load Tix - this should work dynamically or statically
214        # If it's static, tcl/tix8.1/pkgIndex.tcl should have
215        #               'load {} Tix'
216        # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have
217        #               'load libtix8.1.8.3.so Tix'
218        self.tk.eval('package require Tix')
219
220    def destroy(self):
221        # For safety, remove the delete_window binding before destroy
222        self.protocol("WM_DELETE_WINDOW", "")
223        Tkinter.Tk.destroy(self)
224
225# The Tix 'tixForm' geometry manager
226class Form:
227    """The Tix Form geometry manager
228
229    Widgets can be arranged by specifying attachments to other widgets.
230    See Tix documentation for complete details"""
231
232    def config(self, cnf={}, **kw):
233        self.tk.call('tixForm', self._w, *self._options(cnf, kw))
234
235    form = config
236
237    def __setitem__(self, key, value):
238        Form.form(self, {key: value})
239
240    def check(self):
241        return self.tk.call('tixForm', 'check', self._w)
242
243    def forget(self):
244        self.tk.call('tixForm', 'forget', self._w)
245
246    def grid(self, xsize=0, ysize=0):
247        if (not xsize) and (not ysize):
248            x = self.tk.call('tixForm', 'grid', self._w)
249            y = self.tk.splitlist(x)
250            z = ()
251            for x in y:
252                z = z + (self.tk.getint(x),)
253            return z
254        return self.tk.call('tixForm', 'grid', self._w, xsize, ysize)
255
256    def info(self, option=None):
257        if not option:
258            return self.tk.call('tixForm', 'info', self._w)
259        if option[0] != '-':
260            option = '-' + option
261        return self.tk.call('tixForm', 'info', self._w, option)
262
263    def slaves(self):
264        return map(self._nametowidget,
265                   self.tk.splitlist(
266                       self.tk.call(
267                       'tixForm', 'slaves', self._w)))
268
269
270
271Tkinter.Widget.__bases__ = Tkinter.Widget.__bases__ + (Form,)
272
273class TixWidget(Tkinter.Widget):
274    """A TixWidget class is used to package all (or most) Tix widgets.
275
276    Widget initialization is extended in two ways:
277       1) It is possible to give a list of options which must be part of
278       the creation command (so called Tix 'static' options). These cannot be
279       given as a 'config' command later.
280       2) It is possible to give the name of an existing TK widget. These are
281       child widgets created automatically by a Tix mega-widget. The Tk call
282       to create these widgets is therefore bypassed in TixWidget.__init__
283
284    Both options are for use by subclasses only.
285    """
286    def __init__ (self, master=None, widgetName=None,
287                static_options=None, cnf={}, kw={}):
288        # Merge keywords and dictionary arguments
289        if kw:
290            cnf = _cnfmerge((cnf, kw))
291        else:
292            cnf = _cnfmerge(cnf)
293
294        # Move static options into extra. static_options must be
295        # a list of keywords (or None).
296        extra=()
297
298        # 'options' is always a static option
299        if static_options:
300            static_options.append('options')
301        else:
302            static_options = ['options']
303
304        for k,v in cnf.items()[:]:
305            if k in static_options:
306                extra = extra + ('-' + k, v)
307                del cnf[k]
308
309        self.widgetName = widgetName
310        Widget._setup(self, master, cnf)
311
312        # If widgetName is None, this is a dummy creation call where the
313        # corresponding Tk widget has already been created by Tix
314        if widgetName:
315            self.tk.call(widgetName, self._w, *extra)
316
317        # Non-static options - to be done via a 'config' command
318        if cnf:
319            Widget.config(self, cnf)
320
321        # Dictionary to hold subwidget names for easier access. We can't
322        # use the children list because the public Tix names may not be the
323        # same as the pathname component
324        self.subwidget_list = {}
325
326    # We set up an attribute access function so that it is possible to
327    # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello'
328    # when w is a StdButtonBox.
329    # We can even do w.ok.invoke() because w.ok is subclassed from the
330    # Button class if you go through the proper constructors
331    def __getattr__(self, name):
332        if name in self.subwidget_list:
333            return self.subwidget_list[name]
334        raise AttributeError, name
335
336    def set_silent(self, value):
337        """Set a variable without calling its action routine"""
338        self.tk.call('tixSetSilent', self._w, value)
339
340    def subwidget(self, name):
341        """Return the named subwidget (which must have been created by
342        the sub-class)."""
343        n = self._subwidget_name(name)
344        if not n:
345            raise TclError, "Subwidget " + name + " not child of " + self._name
346        # Remove header of name and leading dot
347        n = n[len(self._w)+1:]
348        return self._nametowidget(n)
349
350    def subwidgets_all(self):
351        """Return all subwidgets."""
352        names = self._subwidget_names()
353        if not names:
354            return []
355        retlist = []
356        for name in names:
357            name = name[len(self._w)+1:]
358            try:
359                retlist.append(self._nametowidget(name))
360            except:
361                # some of the widgets are unknown e.g. border in LabelFrame
362                pass
363        return retlist
364
365    def _subwidget_name(self,name):
366        """Get a subwidget name (returns a String, not a Widget !)"""
367        try:
368            return self.tk.call(self._w, 'subwidget', name)
369        except TclError:
370            return None
371
372    def _subwidget_names(self):
373        """Return the name of all subwidgets."""
374        try:
375            x = self.tk.call(self._w, 'subwidgets', '-all')
376            return self.tk.splitlist(x)
377        except TclError:
378            return None
379
380    def config_all(self, option, value):
381        """Set configuration options for all subwidgets (and self)."""
382        if option == '':
383            return
384        elif not isinstance(option, StringType):
385            option = repr(option)
386        if not isinstance(value, StringType):
387            value = repr(value)
388        names = self._subwidget_names()
389        for name in names:
390            self.tk.call(name, 'configure', '-' + option, value)
391    # These are missing from Tkinter
392    def image_create(self, imgtype, cnf={}, master=None, **kw):
393        if not master:
394            master = Tkinter._default_root
395            if not master:
396                raise RuntimeError, 'Too early to create image'
397        if kw and cnf: cnf = _cnfmerge((cnf, kw))
398        elif kw: cnf = kw
399        options = ()
400        for k, v in cnf.items():
401            if hasattr(v, '__call__'):
402                v = self._register(v)
403            options = options + ('-'+k, v)
404        return master.tk.call(('image', 'create', imgtype,) + options)
405    def image_delete(self, imgname):
406        try:
407            self.tk.call('image', 'delete', imgname)
408        except TclError:
409            # May happen if the root was destroyed
410            pass
411
412# Subwidgets are child widgets created automatically by mega-widgets.
413# In python, we have to create these subwidgets manually to mirror their
414# existence in Tk/Tix.
415class TixSubWidget(TixWidget):
416    """Subwidget class.
417
418    This is used to mirror child widgets automatically created
419    by Tix/Tk as part of a mega-widget in Python (which is not informed
420    of this)"""
421
422    def __init__(self, master, name,
423               destroy_physically=1, check_intermediate=1):
424        if check_intermediate:
425            path = master._subwidget_name(name)
426            try:
427                path = path[len(master._w)+1:]
428                plist = path.split('.')
429            except:
430                plist = []
431
432        if not check_intermediate:
433            # immediate descendant
434            TixWidget.__init__(self, master, None, None, {'name' : name})
435        else:
436            # Ensure that the intermediate widgets exist
437            parent = master
438            for i in range(len(plist) - 1):
439                n = '.'.join(plist[:i+1])
440                try:
441                    w = master._nametowidget(n)
442                    parent = w
443                except KeyError:
444                    # Create the intermediate widget
445                    parent = TixSubWidget(parent, plist[i],
446                                          destroy_physically=0,
447                                          check_intermediate=0)
448            # The Tk widget name is in plist, not in name
449            if plist:
450                name = plist[-1]
451            TixWidget.__init__(self, parent, None, None, {'name' : name})
452        self.destroy_physically = destroy_physically
453
454    def destroy(self):
455        # For some widgets e.g., a NoteBook, when we call destructors,
456        # we must be careful not to destroy the frame widget since this
457        # also destroys the parent NoteBook thus leading to an exception
458        # in Tkinter when it finally calls Tcl to destroy the NoteBook
459        for c in self.children.values(): c.destroy()
460        if self._name in self.master.children:
461            del self.master.children[self._name]
462        if self._name in self.master.subwidget_list:
463            del self.master.subwidget_list[self._name]
464        if self.destroy_physically:
465            # This is bypassed only for a few widgets
466            self.tk.call('destroy', self._w)
467
468
469# Useful class to create a display style - later shared by many items.
470# Contributed by Steffen Kremser
471class DisplayStyle:
472    """DisplayStyle - handle configuration options shared by
473    (multiple) Display Items"""
474
475    def __init__(self, itemtype, cnf={}, **kw):
476        if 'refwindow' in kw:
477            master = kw['refwindow']
478        elif 'refwindow' in cnf:
479            master = cnf['refwindow']
480        else:
481            master = Tkinter._default_root
482            if not master:
483                raise RuntimeError("Too early to create display style: no root window")
484        self.tk = master.tk
485        self.stylename = self.tk.call('tixDisplayStyle', itemtype,
486                            *self._options(cnf,kw) )
487
488    def __str__(self):
489        return self.stylename
490
491    def _options(self, cnf, kw):
492        if kw and cnf:
493            cnf = _cnfmerge((cnf, kw))
494        elif kw:
495            cnf = kw
496        opts = ()
497        for k, v in cnf.items():
498            opts = opts + ('-'+k, v)
499        return opts
500
501    def delete(self):
502        self.tk.call(self.stylename, 'delete')
503
504    def __setitem__(self,key,value):
505        self.tk.call(self.stylename, 'configure', '-%s'%key, value)
506
507    def config(self, cnf={}, **kw):
508        return self._getconfigure(
509            self.stylename, 'configure', *self._options(cnf,kw))
510
511    def __getitem__(self,key):
512        return self.tk.call(self.stylename, 'cget', '-%s'%key)
513
514
515######################################################
516### The Tix Widget classes - in alphabetical order ###
517######################################################
518
519class Balloon(TixWidget):
520    """Balloon help widget.
521
522    Subwidget       Class
523    ---------       -----
524    label           Label
525    message         Message"""
526
527    # FIXME: It should inherit -superclass tixShell
528    def __init__(self, master=None, cnf={}, **kw):
529        # static seem to be -installcolormap -initwait -statusbar -cursor
530        static = ['options', 'installcolormap', 'initwait', 'statusbar',
531                  'cursor']
532        TixWidget.__init__(self, master, 'tixBalloon', static, cnf, kw)
533        self.subwidget_list['label'] = _dummyLabel(self, 'label',
534                                                   destroy_physically=0)
535        self.subwidget_list['message'] = _dummyLabel(self, 'message',
536                                                     destroy_physically=0)
537
538    def bind_widget(self, widget, cnf={}, **kw):
539        """Bind balloon widget to another.
540        One balloon widget may be bound to several widgets at the same time"""
541        self.tk.call(self._w, 'bind', widget._w, *self._options(cnf, kw))
542
543    def unbind_widget(self, widget):
544        self.tk.call(self._w, 'unbind', widget._w)
545
546class ButtonBox(TixWidget):
547    """ButtonBox - A container for pushbuttons.
548    Subwidgets are the buttons added with the add method.
549    """
550    def __init__(self, master=None, cnf={}, **kw):
551        TixWidget.__init__(self, master, 'tixButtonBox',
552                           ['orientation', 'options'], cnf, kw)
553
554    def add(self, name, cnf={}, **kw):
555        """Add a button with given name to box."""
556
557        btn = self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
558        self.subwidget_list[name] = _dummyButton(self, name)
559        return btn
560
561    def invoke(self, name):
562        if name in self.subwidget_list:
563            self.tk.call(self._w, 'invoke', name)
564
565class ComboBox(TixWidget):
566    """ComboBox - an Entry field with a dropdown menu. The user can select a
567    choice by either typing in the entry subwidget or selecting from the
568    listbox subwidget.
569
570    Subwidget       Class
571    ---------       -----
572    entry       Entry
573    arrow       Button
574    slistbox    ScrolledListBox
575    tick        Button
576    cross       Button : present if created with the fancy option"""
577
578    # FIXME: It should inherit -superclass tixLabelWidget
579    def __init__ (self, master=None, cnf={}, **kw):
580        TixWidget.__init__(self, master, 'tixComboBox',
581                           ['editable', 'dropdown', 'fancy', 'options'],
582                           cnf, kw)
583        self.subwidget_list['label'] = _dummyLabel(self, 'label')
584        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
585        self.subwidget_list['arrow'] = _dummyButton(self, 'arrow')
586        self.subwidget_list['slistbox'] = _dummyScrolledListBox(self,
587                                                                'slistbox')
588        try:
589            self.subwidget_list['tick'] = _dummyButton(self, 'tick')
590            self.subwidget_list['cross'] = _dummyButton(self, 'cross')
591        except TypeError:
592            # unavailable when -fancy not specified
593            pass
594
595    # align
596
597    def add_history(self, str):
598        self.tk.call(self._w, 'addhistory', str)
599
600    def append_history(self, str):
601        self.tk.call(self._w, 'appendhistory', str)
602
603    def insert(self, index, str):
604        self.tk.call(self._w, 'insert', index, str)
605
606    def pick(self, index):
607        self.tk.call(self._w, 'pick', index)
608
609class Control(TixWidget):
610    """Control - An entry field with value change arrows.  The user can
611    adjust the value by pressing the two arrow buttons or by entering
612    the value directly into the entry. The new value will be checked
613    against the user-defined upper and lower limits.
614
615    Subwidget       Class
616    ---------       -----
617    incr       Button
618    decr       Button
619    entry       Entry
620    label       Label"""
621
622    # FIXME: It should inherit -superclass tixLabelWidget
623    def __init__ (self, master=None, cnf={}, **kw):
624        TixWidget.__init__(self, master, 'tixControl', ['options'], cnf, kw)
625        self.subwidget_list['incr'] = _dummyButton(self, 'incr')
626        self.subwidget_list['decr'] = _dummyButton(self, 'decr')
627        self.subwidget_list['label'] = _dummyLabel(self, 'label')
628        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
629
630    def decrement(self):
631        self.tk.call(self._w, 'decr')
632
633    def increment(self):
634        self.tk.call(self._w, 'incr')
635
636    def invoke(self):
637        self.tk.call(self._w, 'invoke')
638
639    def update(self):
640        self.tk.call(self._w, 'update')
641
642class DirList(TixWidget):
643    """DirList - displays a list view of a directory, its previous
644    directories and its sub-directories. The user can choose one of
645    the directories displayed in the list or change to another directory.
646
647    Subwidget       Class
648    ---------       -----
649    hlist       HList
650    hsb              Scrollbar
651    vsb              Scrollbar"""
652
653    # FIXME: It should inherit -superclass tixScrolledHList
654    def __init__(self, master, cnf={}, **kw):
655        TixWidget.__init__(self, master, 'tixDirList', ['options'], cnf, kw)
656        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
657        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
658        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
659
660    def chdir(self, dir):
661        self.tk.call(self._w, 'chdir', dir)
662
663class DirTree(TixWidget):
664    """DirTree - Directory Listing in a hierarchical view.
665    Displays a tree view of a directory, its previous directories and its
666    sub-directories. The user can choose one of the directories displayed
667    in the list or change to another directory.
668
669    Subwidget       Class
670    ---------       -----
671    hlist           HList
672    hsb             Scrollbar
673    vsb             Scrollbar"""
674
675    # FIXME: It should inherit -superclass tixScrolledHList
676    def __init__(self, master, cnf={}, **kw):
677        TixWidget.__init__(self, master, 'tixDirTree', ['options'], cnf, kw)
678        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
679        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
680        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
681
682    def chdir(self, dir):
683        self.tk.call(self._w, 'chdir', dir)
684
685class DirSelectBox(TixWidget):
686    """DirSelectBox - Motif style file select box.
687    It is generally used for
688    the user to choose a file. FileSelectBox stores the files mostly
689    recently selected into a ComboBox widget so that they can be quickly
690    selected again.
691
692    Subwidget       Class
693    ---------       -----
694    selection       ComboBox
695    filter          ComboBox
696    dirlist         ScrolledListBox
697    filelist        ScrolledListBox"""
698
699    def __init__(self, master, cnf={}, **kw):
700        TixWidget.__init__(self, master, 'tixDirSelectBox', ['options'], cnf, kw)
701        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
702        self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx')
703
704class ExFileSelectBox(TixWidget):
705    """ExFileSelectBox - MS Windows style file select box.
706    It provides a convenient method for the user to select files.
707
708    Subwidget       Class
709    ---------       -----
710    cancel       Button
711    ok              Button
712    hidden       Checkbutton
713    types       ComboBox
714    dir              ComboBox
715    file       ComboBox
716    dirlist       ScrolledListBox
717    filelist       ScrolledListBox"""
718
719    def __init__(self, master, cnf={}, **kw):
720        TixWidget.__init__(self, master, 'tixExFileSelectBox', ['options'], cnf, kw)
721        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
722        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
723        self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden')
724        self.subwidget_list['types'] = _dummyComboBox(self, 'types')
725        self.subwidget_list['dir'] = _dummyComboBox(self, 'dir')
726        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
727        self.subwidget_list['file'] = _dummyComboBox(self, 'file')
728        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
729
730    def filter(self):
731        self.tk.call(self._w, 'filter')
732
733    def invoke(self):
734        self.tk.call(self._w, 'invoke')
735
736
737# Should inherit from a Dialog class
738class DirSelectDialog(TixWidget):
739    """The DirSelectDialog widget presents the directories in the file
740    system in a dialog window. The user can use this dialog window to
741    navigate through the file system to select the desired directory.
742
743    Subwidgets       Class
744    ----------       -----
745    dirbox       DirSelectDialog"""
746
747    # FIXME: It should inherit -superclass tixDialogShell
748    def __init__(self, master, cnf={}, **kw):
749        TixWidget.__init__(self, master, 'tixDirSelectDialog',
750                           ['options'], cnf, kw)
751        self.subwidget_list['dirbox'] = _dummyDirSelectBox(self, 'dirbox')
752        # cancel and ok buttons are missing
753
754    def popup(self):
755        self.tk.call(self._w, 'popup')
756
757    def popdown(self):
758        self.tk.call(self._w, 'popdown')
759
760
761# Should inherit from a Dialog class
762class ExFileSelectDialog(TixWidget):
763    """ExFileSelectDialog - MS Windows style file select dialog.
764    It provides a convenient method for the user to select files.
765
766    Subwidgets       Class
767    ----------       -----
768    fsbox       ExFileSelectBox"""
769
770    # FIXME: It should inherit -superclass tixDialogShell
771    def __init__(self, master, cnf={}, **kw):
772        TixWidget.__init__(self, master, 'tixExFileSelectDialog',
773                           ['options'], cnf, kw)
774        self.subwidget_list['fsbox'] = _dummyExFileSelectBox(self, 'fsbox')
775
776    def popup(self):
777        self.tk.call(self._w, 'popup')
778
779    def popdown(self):
780        self.tk.call(self._w, 'popdown')
781
782class FileSelectBox(TixWidget):
783    """ExFileSelectBox - Motif style file select box.
784    It is generally used for
785    the user to choose a file. FileSelectBox stores the files mostly
786    recently selected into a ComboBox widget so that they can be quickly
787    selected again.
788
789    Subwidget       Class
790    ---------       -----
791    selection       ComboBox
792    filter          ComboBox
793    dirlist         ScrolledListBox
794    filelist        ScrolledListBox"""
795
796    def __init__(self, master, cnf={}, **kw):
797        TixWidget.__init__(self, master, 'tixFileSelectBox', ['options'], cnf, kw)
798        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
799        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
800        self.subwidget_list['filter'] = _dummyComboBox(self, 'filter')
801        self.subwidget_list['selection'] = _dummyComboBox(self, 'selection')
802
803    def apply_filter(self):              # name of subwidget is same as command
804        self.tk.call(self._w, 'filter')
805
806    def invoke(self):
807        self.tk.call(self._w, 'invoke')
808
809# Should inherit from a Dialog class
810class FileSelectDialog(TixWidget):
811    """FileSelectDialog - Motif style file select dialog.
812
813    Subwidgets       Class
814    ----------       -----
815    btns       StdButtonBox
816    fsbox       FileSelectBox"""
817
818    # FIXME: It should inherit -superclass tixStdDialogShell
819    def __init__(self, master, cnf={}, **kw):
820        TixWidget.__init__(self, master, 'tixFileSelectDialog',
821                           ['options'], cnf, kw)
822        self.subwidget_list['btns'] = _dummyStdButtonBox(self, 'btns')
823        self.subwidget_list['fsbox'] = _dummyFileSelectBox(self, 'fsbox')
824
825    def popup(self):
826        self.tk.call(self._w, 'popup')
827
828    def popdown(self):
829        self.tk.call(self._w, 'popdown')
830
831class FileEntry(TixWidget):
832    """FileEntry - Entry field with button that invokes a FileSelectDialog.
833    The user can type in the filename manually. Alternatively, the user can
834    press the button widget that sits next to the entry, which will bring
835    up a file selection dialog.
836
837    Subwidgets       Class
838    ----------       -----
839    button       Button
840    entry       Entry"""
841
842    # FIXME: It should inherit -superclass tixLabelWidget
843    def __init__(self, master, cnf={}, **kw):
844        TixWidget.__init__(self, master, 'tixFileEntry',
845                           ['dialogtype', 'options'], cnf, kw)
846        self.subwidget_list['button'] = _dummyButton(self, 'button')
847        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
848
849    def invoke(self):
850        self.tk.call(self._w, 'invoke')
851
852    def file_dialog(self):
853        # FIXME: return python object
854        pass
855
856class HList(TixWidget, XView, YView):
857    """HList - Hierarchy display  widget can be used to display any data
858    that have a hierarchical structure, for example, file system directory
859    trees. The list entries are indented and connected by branch lines
860    according to their places in the hierarchy.
861
862    Subwidgets - None"""
863
864    def __init__ (self,master=None,cnf={}, **kw):
865        TixWidget.__init__(self, master, 'tixHList',
866                           ['columns', 'options'], cnf, kw)
867
868    def add(self, entry, cnf={}, **kw):
869        return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw))
870
871    def add_child(self, parent=None, cnf={}, **kw):
872        if not parent:
873            parent = ''
874        return self.tk.call(
875                     self._w, 'addchild', parent, *self._options(cnf, kw))
876
877    def anchor_set(self, entry):
878        self.tk.call(self._w, 'anchor', 'set', entry)
879
880    def anchor_clear(self):
881        self.tk.call(self._w, 'anchor', 'clear')
882
883    def column_width(self, col=0, width=None, chars=None):
884        if not chars:
885            return self.tk.call(self._w, 'column', 'width', col, width)
886        else:
887            return self.tk.call(self._w, 'column', 'width', col,
888                                '-char', chars)
889
890    def delete_all(self):
891        self.tk.call(self._w, 'delete', 'all')
892
893    def delete_entry(self, entry):
894        self.tk.call(self._w, 'delete', 'entry', entry)
895
896    def delete_offsprings(self, entry):
897        self.tk.call(self._w, 'delete', 'offsprings', entry)
898
899    def delete_siblings(self, entry):
900        self.tk.call(self._w, 'delete', 'siblings', entry)
901
902    def dragsite_set(self, index):
903        self.tk.call(self._w, 'dragsite', 'set', index)
904
905    def dragsite_clear(self):
906        self.tk.call(self._w, 'dragsite', 'clear')
907
908    def dropsite_set(self, index):
909        self.tk.call(self._w, 'dropsite', 'set', index)
910
911    def dropsite_clear(self):
912        self.tk.call(self._w, 'dropsite', 'clear')
913
914    def header_create(self, col, cnf={}, **kw):
915        self.tk.call(self._w, 'header', 'create', col, *self._options(cnf, kw))
916
917    def header_configure(self, col, cnf={}, **kw):
918        if cnf is None:
919            return self._getconfigure(self._w, 'header', 'configure', col)
920        self.tk.call(self._w, 'header', 'configure', col,
921                     *self._options(cnf, kw))
922
923    def header_cget(self,  col, opt):
924        return self.tk.call(self._w, 'header', 'cget', col, opt)
925
926    def header_exists(self,  col):
927        # A workaround to Tix library bug (issue #25464).
928        # The documented command is "exists", but only erroneous "exist" is
929        # accepted.
930        return self.tk.getboolean(self.tk.call(self._w, 'header', 'exist', col))
931    header_exist = header_exists
932
933    def header_delete(self, col):
934        self.tk.call(self._w, 'header', 'delete', col)
935
936    def header_size(self, col):
937        return self.tk.call(self._w, 'header', 'size', col)
938
939    def hide_entry(self, entry):
940        self.tk.call(self._w, 'hide', 'entry', entry)
941
942    def indicator_create(self, entry, cnf={}, **kw):
943        self.tk.call(
944              self._w, 'indicator', 'create', entry, *self._options(cnf, kw))
945
946    def indicator_configure(self, entry, cnf={}, **kw):
947        if cnf is None:
948            return self._getconfigure(
949                self._w, 'indicator', 'configure', entry)
950        self.tk.call(
951              self._w, 'indicator', 'configure', entry, *self._options(cnf, kw))
952
953    def indicator_cget(self,  entry, opt):
954        return self.tk.call(self._w, 'indicator', 'cget', entry, opt)
955
956    def indicator_exists(self,  entry):
957        return self.tk.call (self._w, 'indicator', 'exists', entry)
958
959    def indicator_delete(self, entry):
960        self.tk.call(self._w, 'indicator', 'delete', entry)
961
962    def indicator_size(self, entry):
963        return self.tk.call(self._w, 'indicator', 'size', entry)
964
965    def info_anchor(self):
966        return self.tk.call(self._w, 'info', 'anchor')
967
968    def info_bbox(self, entry):
969        return self._getints(
970                self.tk.call(self._w, 'info', 'bbox', entry)) or None
971
972    def info_children(self, entry=None):
973        c = self.tk.call(self._w, 'info', 'children', entry)
974        return self.tk.splitlist(c)
975
976    def info_data(self, entry):
977        return self.tk.call(self._w, 'info', 'data', entry)
978
979    def info_dragsite(self):
980        return self.tk.call(self._w, 'info', 'dragsite')
981
982    def info_dropsite(self):
983        return self.tk.call(self._w, 'info', 'dropsite')
984
985    def info_exists(self, entry):
986        return self.tk.call(self._w, 'info', 'exists', entry)
987
988    def info_hidden(self, entry):
989        return self.tk.call(self._w, 'info', 'hidden', entry)
990
991    def info_next(self, entry):
992        return self.tk.call(self._w, 'info', 'next', entry)
993
994    def info_parent(self, entry):
995        return self.tk.call(self._w, 'info', 'parent', entry)
996
997    def info_prev(self, entry):
998        return self.tk.call(self._w, 'info', 'prev', entry)
999
1000    def info_selection(self):
1001        c = self.tk.call(self._w, 'info', 'selection')
1002        return self.tk.splitlist(c)
1003
1004    def item_cget(self, entry, col, opt):
1005        return self.tk.call(self._w, 'item', 'cget', entry, col, opt)
1006
1007    def item_configure(self, entry, col, cnf={}, **kw):
1008        if cnf is None:
1009            return self._getconfigure(self._w, 'item', 'configure', entry, col)
1010        self.tk.call(self._w, 'item', 'configure', entry, col,
1011              *self._options(cnf, kw))
1012
1013    def item_create(self, entry, col, cnf={}, **kw):
1014        self.tk.call(
1015              self._w, 'item', 'create', entry, col, *self._options(cnf, kw))
1016
1017    def item_exists(self, entry, col):
1018        return self.tk.call(self._w, 'item', 'exists', entry, col)
1019
1020    def item_delete(self, entry, col):
1021        self.tk.call(self._w, 'item', 'delete', entry, col)
1022
1023    def entrycget(self, entry, opt):
1024        return self.tk.call(self._w, 'entrycget', entry, opt)
1025
1026    def entryconfigure(self, entry, cnf={}, **kw):
1027        if cnf is None:
1028            return self._getconfigure(self._w, 'entryconfigure', entry)
1029        self.tk.call(self._w, 'entryconfigure', entry,
1030              *self._options(cnf, kw))
1031
1032    def nearest(self, y):
1033        return self.tk.call(self._w, 'nearest', y)
1034
1035    def see(self, entry):
1036        self.tk.call(self._w, 'see', entry)
1037
1038    def selection_clear(self, cnf={}, **kw):
1039        self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw))
1040
1041    def selection_includes(self, entry):
1042        return self.tk.call(self._w, 'selection', 'includes', entry)
1043
1044    def selection_set(self, first, last=None):
1045        self.tk.call(self._w, 'selection', 'set', first, last)
1046
1047    def show_entry(self, entry):
1048        return self.tk.call(self._w, 'show', 'entry', entry)
1049
1050class InputOnly(TixWidget):
1051    """InputOnly - Invisible widget. Unix only.
1052
1053    Subwidgets - None"""
1054
1055    def __init__ (self,master=None,cnf={}, **kw):
1056        TixWidget.__init__(self, master, 'tixInputOnly', None, cnf, kw)
1057
1058class LabelEntry(TixWidget):
1059    """LabelEntry - Entry field with label. Packages an entry widget
1060    and a label into one mega widget. It can be used to simplify the creation
1061    of ``entry-form'' type of interface.
1062
1063    Subwidgets       Class
1064    ----------       -----
1065    label       Label
1066    entry       Entry"""
1067
1068    def __init__ (self,master=None,cnf={}, **kw):
1069        TixWidget.__init__(self, master, 'tixLabelEntry',
1070                           ['labelside','options'], cnf, kw)
1071        self.subwidget_list['label'] = _dummyLabel(self, 'label')
1072        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
1073
1074class LabelFrame(TixWidget):
1075    """LabelFrame - Labelled Frame container. Packages a frame widget
1076    and a label into one mega widget. To create widgets inside a
1077    LabelFrame widget, one creates the new widgets relative to the
1078    frame subwidget and manage them inside the frame subwidget.
1079
1080    Subwidgets       Class
1081    ----------       -----
1082    label       Label
1083    frame       Frame"""
1084
1085    def __init__ (self,master=None,cnf={}, **kw):
1086        TixWidget.__init__(self, master, 'tixLabelFrame',
1087                           ['labelside','options'], cnf, kw)
1088        self.subwidget_list['label'] = _dummyLabel(self, 'label')
1089        self.subwidget_list['frame'] = _dummyFrame(self, 'frame')
1090
1091
1092class ListNoteBook(TixWidget):
1093    """A ListNoteBook widget is very similar to the TixNoteBook widget:
1094    it can be used to display many windows in a limited space using a
1095    notebook metaphor. The notebook is divided into a stack of pages
1096    (windows). At one time only one of these pages can be shown.
1097    The user can navigate through these pages by
1098    choosing the name of the desired page in the hlist subwidget."""
1099
1100    def __init__(self, master, cnf={}, **kw):
1101        TixWidget.__init__(self, master, 'tixListNoteBook', ['options'], cnf, kw)
1102        # Is this necessary? It's not an exposed subwidget in Tix.
1103        self.subwidget_list['pane'] = _dummyPanedWindow(self, 'pane',
1104                                                        destroy_physically=0)
1105        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1106        self.subwidget_list['shlist'] = _dummyScrolledHList(self, 'shlist')
1107
1108    def add(self, name, cnf={}, **kw):
1109        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
1110        self.subwidget_list[name] = TixSubWidget(self, name)
1111        return self.subwidget_list[name]
1112
1113    def page(self, name):
1114        return self.subwidget(name)
1115
1116    def pages(self):
1117        # Can't call subwidgets_all directly because we don't want .nbframe
1118        names = self.tk.split(self.tk.call(self._w, 'pages'))
1119        ret = []
1120        for x in names:
1121            ret.append(self.subwidget(x))
1122        return ret
1123
1124    def raise_page(self, name):              # raise is a python keyword
1125        self.tk.call(self._w, 'raise', name)
1126
1127class Meter(TixWidget):
1128    """The Meter widget can be used to show the progress of a background
1129    job which may take a long time to execute.
1130    """
1131
1132    def __init__(self, master=None, cnf={}, **kw):
1133        TixWidget.__init__(self, master, 'tixMeter',
1134                           ['options'], cnf, kw)
1135
1136class NoteBook(TixWidget):
1137    """NoteBook - Multi-page container widget (tabbed notebook metaphor).
1138
1139    Subwidgets       Class
1140    ----------       -----
1141    nbframe       NoteBookFrame
1142    <pages>       page widgets added dynamically with the add method"""
1143
1144    def __init__ (self,master=None,cnf={}, **kw):
1145        TixWidget.__init__(self,master,'tixNoteBook', ['options'], cnf, kw)
1146        self.subwidget_list['nbframe'] = TixSubWidget(self, 'nbframe',
1147                                                      destroy_physically=0)
1148
1149    def add(self, name, cnf={}, **kw):
1150        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
1151        self.subwidget_list[name] = TixSubWidget(self, name)
1152        return self.subwidget_list[name]
1153
1154    def delete(self, name):
1155        self.tk.call(self._w, 'delete', name)
1156        self.subwidget_list[name].destroy()
1157        del self.subwidget_list[name]
1158
1159    def page(self, name):
1160        return self.subwidget(name)
1161
1162    def pages(self):
1163        # Can't call subwidgets_all directly because we don't want .nbframe
1164        names = self.tk.split(self.tk.call(self._w, 'pages'))
1165        ret = []
1166        for x in names:
1167            ret.append(self.subwidget(x))
1168        return ret
1169
1170    def raise_page(self, name):              # raise is a python keyword
1171        self.tk.call(self._w, 'raise', name)
1172
1173    def raised(self):
1174        return self.tk.call(self._w, 'raised')
1175
1176class NoteBookFrame(TixWidget):
1177    # FIXME: This is dangerous to expose to be called on its own.
1178    pass
1179
1180class OptionMenu(TixWidget):
1181    """OptionMenu - creates a menu button of options.
1182
1183    Subwidget       Class
1184    ---------       -----
1185    menubutton      Menubutton
1186    menu            Menu"""
1187
1188    def __init__(self, master, cnf={}, **kw):
1189        TixWidget.__init__(self, master, 'tixOptionMenu',
1190                ['labelside', 'options'], cnf, kw)
1191        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
1192        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
1193
1194    def add_command(self, name, cnf={}, **kw):
1195        self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw))
1196
1197    def add_separator(self, name, cnf={}, **kw):
1198        self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw))
1199
1200    def delete(self, name):
1201        self.tk.call(self._w, 'delete', name)
1202
1203    def disable(self, name):
1204        self.tk.call(self._w, 'disable', name)
1205
1206    def enable(self, name):
1207        self.tk.call(self._w, 'enable', name)
1208
1209class PanedWindow(TixWidget):
1210    """PanedWindow - Multi-pane container widget
1211    allows the user to interactively manipulate the sizes of several
1212    panes. The panes can be arranged either vertically or horizontally.The
1213    user changes the sizes of the panes by dragging the resize handle
1214    between two panes.
1215
1216    Subwidgets       Class
1217    ----------       -----
1218    <panes>       g/p widgets added dynamically with the add method."""
1219
1220    def __init__(self, master, cnf={}, **kw):
1221        TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw)
1222
1223    # add delete forget panecget paneconfigure panes setsize
1224    def add(self, name, cnf={}, **kw):
1225        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
1226        self.subwidget_list[name] = TixSubWidget(self, name,
1227                                                 check_intermediate=0)
1228        return self.subwidget_list[name]
1229
1230    def delete(self, name):
1231        self.tk.call(self._w, 'delete', name)
1232        self.subwidget_list[name].destroy()
1233        del self.subwidget_list[name]
1234
1235    def forget(self, name):
1236        self.tk.call(self._w, 'forget', name)
1237
1238    def panecget(self,  entry, opt):
1239        return self.tk.call(self._w, 'panecget', entry, opt)
1240
1241    def paneconfigure(self, entry, cnf={}, **kw):
1242        if cnf is None:
1243            return self._getconfigure(self._w, 'paneconfigure', entry)
1244        self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw))
1245
1246    def panes(self):
1247        names = self.tk.splitlist(self.tk.call(self._w, 'panes'))
1248        return [self.subwidget(x) for x in names]
1249
1250class PopupMenu(TixWidget):
1251    """PopupMenu widget can be used as a replacement of the tk_popup command.
1252    The advantage of the Tix PopupMenu widget is it requires less application
1253    code to manipulate.
1254
1255
1256    Subwidgets       Class
1257    ----------       -----
1258    menubutton       Menubutton
1259    menu       Menu"""
1260
1261    # FIXME: It should inherit -superclass tixShell
1262    def __init__(self, master, cnf={}, **kw):
1263        TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw)
1264        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
1265        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
1266
1267    def bind_widget(self, widget):
1268        self.tk.call(self._w, 'bind', widget._w)
1269
1270    def unbind_widget(self, widget):
1271        self.tk.call(self._w, 'unbind', widget._w)
1272
1273    def post_widget(self, widget, x, y):
1274        self.tk.call(self._w, 'post', widget._w, x, y)
1275
1276class ResizeHandle(TixWidget):
1277    """Internal widget to draw resize handles on Scrolled widgets."""
1278    def __init__(self, master, cnf={}, **kw):
1279        # There seems to be a Tix bug rejecting the configure method
1280        # Let's try making the flags -static
1281        flags = ['options', 'command', 'cursorfg', 'cursorbg',
1282                 'handlesize', 'hintcolor', 'hintwidth',
1283                 'x', 'y']
1284        # In fact, x y height width are configurable
1285        TixWidget.__init__(self, master, 'tixResizeHandle',
1286                           flags, cnf, kw)
1287
1288    def attach_widget(self, widget):
1289        self.tk.call(self._w, 'attachwidget', widget._w)
1290
1291    def detach_widget(self, widget):
1292        self.tk.call(self._w, 'detachwidget', widget._w)
1293
1294    def hide(self, widget):
1295        self.tk.call(self._w, 'hide', widget._w)
1296
1297    def show(self, widget):
1298        self.tk.call(self._w, 'show', widget._w)
1299
1300class ScrolledHList(TixWidget):
1301    """ScrolledHList - HList with automatic scrollbars."""
1302
1303    # FIXME: It should inherit -superclass tixScrolledWidget
1304    def __init__(self, master, cnf={}, **kw):
1305        TixWidget.__init__(self, master, 'tixScrolledHList', ['options'],
1306                           cnf, kw)
1307        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1308        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1309        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1310
1311class ScrolledListBox(TixWidget):
1312    """ScrolledListBox - Listbox with automatic scrollbars."""
1313
1314    # FIXME: It should inherit -superclass tixScrolledWidget
1315    def __init__(self, master, cnf={}, **kw):
1316        TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw)
1317        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
1318        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1319        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1320
1321class ScrolledText(TixWidget):
1322    """ScrolledText - Text with automatic scrollbars."""
1323
1324    # FIXME: It should inherit -superclass tixScrolledWidget
1325    def __init__(self, master, cnf={}, **kw):
1326        TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw)
1327        self.subwidget_list['text'] = _dummyText(self, 'text')
1328        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1329        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1330
1331class ScrolledTList(TixWidget):
1332    """ScrolledTList - TList with automatic scrollbars."""
1333
1334    # FIXME: It should inherit -superclass tixScrolledWidget
1335    def __init__(self, master, cnf={}, **kw):
1336        TixWidget.__init__(self, master, 'tixScrolledTList', ['options'],
1337                           cnf, kw)
1338        self.subwidget_list['tlist'] = _dummyTList(self, 'tlist')
1339        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1340        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1341
1342class ScrolledWindow(TixWidget):
1343    """ScrolledWindow - Window with automatic scrollbars."""
1344
1345    # FIXME: It should inherit -superclass tixScrolledWidget
1346    def __init__(self, master, cnf={}, **kw):
1347        TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw)
1348        self.subwidget_list['window'] = _dummyFrame(self, 'window')
1349        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1350        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1351
1352class Select(TixWidget):
1353    """Select - Container of button subwidgets. It can be used to provide
1354    radio-box or check-box style of selection options for the user.
1355
1356    Subwidgets are buttons added dynamically using the add method."""
1357
1358    # FIXME: It should inherit -superclass tixLabelWidget
1359    def __init__(self, master, cnf={}, **kw):
1360        TixWidget.__init__(self, master, 'tixSelect',
1361                           ['allowzero', 'radio', 'orientation', 'labelside',
1362                            'options'],
1363                           cnf, kw)
1364        self.subwidget_list['label'] = _dummyLabel(self, 'label')
1365
1366    def add(self, name, cnf={}, **kw):
1367        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
1368        self.subwidget_list[name] = _dummyButton(self, name)
1369        return self.subwidget_list[name]
1370
1371    def invoke(self, name):
1372        self.tk.call(self._w, 'invoke', name)
1373
1374class Shell(TixWidget):
1375    """Toplevel window.
1376
1377    Subwidgets - None"""
1378
1379    def __init__ (self,master=None,cnf={}, **kw):
1380        TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw)
1381
1382class DialogShell(TixWidget):
1383    """Toplevel window, with popup popdown and center methods.
1384    It tells the window manager that it is a dialog window and should be
1385    treated specially. The exact treatment depends on the treatment of
1386    the window manager.
1387
1388    Subwidgets - None"""
1389
1390    # FIXME: It should inherit from  Shell
1391    def __init__ (self,master=None,cnf={}, **kw):
1392        TixWidget.__init__(self, master,
1393                           'tixDialogShell',
1394                           ['options', 'title', 'mapped',
1395                            'minheight', 'minwidth',
1396                            'parent', 'transient'], cnf, kw)
1397
1398    def popdown(self):
1399        self.tk.call(self._w, 'popdown')
1400
1401    def popup(self):
1402        self.tk.call(self._w, 'popup')
1403
1404    def center(self):
1405        self.tk.call(self._w, 'center')
1406
1407class StdButtonBox(TixWidget):
1408    """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """
1409
1410    def __init__(self, master=None, cnf={}, **kw):
1411        TixWidget.__init__(self, master, 'tixStdButtonBox',
1412                           ['orientation', 'options'], cnf, kw)
1413        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
1414        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
1415        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
1416        self.subwidget_list['help'] = _dummyButton(self, 'help')
1417
1418    def invoke(self, name):
1419        if name in self.subwidget_list:
1420            self.tk.call(self._w, 'invoke', name)
1421
1422class TList(TixWidget, XView, YView):
1423    """TList - Hierarchy display widget which can be
1424    used to display data in a tabular format. The list entries of a TList
1425    widget are similar to the entries in the Tk listbox widget. The main
1426    differences are (1) the TList widget can display the list entries in a
1427    two dimensional format and (2) you can use graphical images as well as
1428    multiple colors and fonts for the list entries.
1429
1430    Subwidgets - None"""
1431
1432    def __init__ (self,master=None,cnf={}, **kw):
1433        TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw)
1434
1435    def active_set(self, index):
1436        self.tk.call(self._w, 'active', 'set', index)
1437
1438    def active_clear(self):
1439        self.tk.call(self._w, 'active', 'clear')
1440
1441    def anchor_set(self, index):
1442        self.tk.call(self._w, 'anchor', 'set', index)
1443
1444    def anchor_clear(self):
1445        self.tk.call(self._w, 'anchor', 'clear')
1446
1447    def delete(self, from_, to=None):
1448        self.tk.call(self._w, 'delete', from_, to)
1449
1450    def dragsite_set(self, index):
1451        self.tk.call(self._w, 'dragsite', 'set', index)
1452
1453    def dragsite_clear(self):
1454        self.tk.call(self._w, 'dragsite', 'clear')
1455
1456    def dropsite_set(self, index):
1457        self.tk.call(self._w, 'dropsite', 'set', index)
1458
1459    def dropsite_clear(self):
1460        self.tk.call(self._w, 'dropsite', 'clear')
1461
1462    def insert(self, index, cnf={}, **kw):
1463        self.tk.call(self._w, 'insert', index, *self._options(cnf, kw))
1464
1465    def info_active(self):
1466        return self.tk.call(self._w, 'info', 'active')
1467
1468    def info_anchor(self):
1469        return self.tk.call(self._w, 'info', 'anchor')
1470
1471    def info_down(self, index):
1472        return self.tk.call(self._w, 'info', 'down', index)
1473
1474    def info_left(self, index):
1475        return self.tk.call(self._w, 'info', 'left', index)
1476
1477    def info_right(self, index):
1478        return self.tk.call(self._w, 'info', 'right', index)
1479
1480    def info_selection(self):
1481        c = self.tk.call(self._w, 'info', 'selection')
1482        return self.tk.splitlist(c)
1483
1484    def info_size(self):
1485        return self.tk.call(self._w, 'info', 'size')
1486
1487    def info_up(self, index):
1488        return self.tk.call(self._w, 'info', 'up', index)
1489
1490    def nearest(self, x, y):
1491        return self.tk.call(self._w, 'nearest', x, y)
1492
1493    def see(self, index):
1494        self.tk.call(self._w, 'see', index)
1495
1496    def selection_clear(self, cnf={}, **kw):
1497        self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw))
1498
1499    def selection_includes(self, index):
1500        return self.tk.call(self._w, 'selection', 'includes', index)
1501
1502    def selection_set(self, first, last=None):
1503        self.tk.call(self._w, 'selection', 'set', first, last)
1504
1505class Tree(TixWidget):
1506    """Tree - The tixTree widget can be used to display hierarchical
1507    data in a tree form. The user can adjust
1508    the view of the tree by opening or closing parts of the tree."""
1509
1510    # FIXME: It should inherit -superclass tixScrolledWidget
1511    def __init__(self, master=None, cnf={}, **kw):
1512        TixWidget.__init__(self, master, 'tixTree',
1513                           ['options'], cnf, kw)
1514        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1515        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1516        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1517
1518    def autosetmode(self):
1519        '''This command calls the setmode method for all the entries in this
1520     Tree widget: if an entry has no child entries, its mode is set to
1521     none. Otherwise, if the entry has any hidden child entries, its mode is
1522     set to open; otherwise its mode is set to close.'''
1523        self.tk.call(self._w, 'autosetmode')
1524
1525    def close(self, entrypath):
1526        '''Close the entry given by entryPath if its mode is close.'''
1527        self.tk.call(self._w, 'close', entrypath)
1528
1529    def getmode(self, entrypath):
1530        '''Returns the current mode of the entry given by entryPath.'''
1531        return self.tk.call(self._w, 'getmode', entrypath)
1532
1533    def open(self, entrypath):
1534        '''Open the entry given by entryPath if its mode is open.'''
1535        self.tk.call(self._w, 'open', entrypath)
1536
1537    def setmode(self, entrypath, mode='none'):
1538        '''This command is used to indicate whether the entry given by
1539     entryPath has children entries and whether the children are visible. mode
1540     must be one of open, close or none. If mode is set to open, a (+)
1541     indicator is drawn next to the entry. If mode is set to close, a (-)
1542     indicator is drawn next to the entry. If mode is set to none, no
1543     indicators will be drawn for this entry. The default mode is none. The
1544     open mode indicates the entry has hidden children and this entry can be
1545     opened by the user. The close mode indicates that all the children of the
1546     entry are now visible and the entry can be closed by the user.'''
1547        self.tk.call(self._w, 'setmode', entrypath, mode)
1548
1549
1550# Could try subclassing Tree for CheckList - would need another arg to init
1551class CheckList(TixWidget):
1552    """The CheckList widget
1553    displays a list of items to be selected by the user. CheckList acts
1554    similarly to the Tk checkbutton or radiobutton widgets, except it is
1555    capable of handling many more items than checkbuttons or radiobuttons.
1556    """
1557    # FIXME: It should inherit -superclass tixTree
1558    def __init__(self, master=None, cnf={}, **kw):
1559        TixWidget.__init__(self, master, 'tixCheckList',
1560                           ['options', 'radio'], cnf, kw)
1561        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1562        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1563        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1564
1565    def autosetmode(self):
1566        '''This command calls the setmode method for all the entries in this
1567     Tree widget: if an entry has no child entries, its mode is set to
1568     none. Otherwise, if the entry has any hidden child entries, its mode is
1569     set to open; otherwise its mode is set to close.'''
1570        self.tk.call(self._w, 'autosetmode')
1571
1572    def close(self, entrypath):
1573        '''Close the entry given by entryPath if its mode is close.'''
1574        self.tk.call(self._w, 'close', entrypath)
1575
1576    def getmode(self, entrypath):
1577        '''Returns the current mode of the entry given by entryPath.'''
1578        return self.tk.call(self._w, 'getmode', entrypath)
1579
1580    def open(self, entrypath):
1581        '''Open the entry given by entryPath if its mode is open.'''
1582        self.tk.call(self._w, 'open', entrypath)
1583
1584    def getselection(self, mode='on'):
1585        '''Returns a list of items whose status matches status. If status is
1586     not specified, the list of items in the "on" status will be returned.
1587     Mode can be on, off, default'''
1588        c = self.tk.split(self.tk.call(self._w, 'getselection', mode))
1589        return self.tk.splitlist(c)
1590
1591    def getstatus(self, entrypath):
1592        '''Returns the current status of entryPath.'''
1593        return self.tk.call(self._w, 'getstatus', entrypath)
1594
1595    def setstatus(self, entrypath, mode='on'):
1596        '''Sets the status of entryPath to be status. A bitmap will be
1597     displayed next to the entry its status is on, off or default.'''
1598        self.tk.call(self._w, 'setstatus', entrypath, mode)
1599
1600
1601###########################################################################
1602### The subclassing below is used to instantiate the subwidgets in each ###
1603### mega widget. This allows us to access their methods directly.       ###
1604###########################################################################
1605
1606class _dummyButton(Button, TixSubWidget):
1607    def __init__(self, master, name, destroy_physically=1):
1608        TixSubWidget.__init__(self, master, name, destroy_physically)
1609
1610class _dummyCheckbutton(Checkbutton, TixSubWidget):
1611    def __init__(self, master, name, destroy_physically=1):
1612        TixSubWidget.__init__(self, master, name, destroy_physically)
1613
1614class _dummyEntry(Entry, TixSubWidget):
1615    def __init__(self, master, name, destroy_physically=1):
1616        TixSubWidget.__init__(self, master, name, destroy_physically)
1617
1618class _dummyFrame(Frame, TixSubWidget):
1619    def __init__(self, master, name, destroy_physically=1):
1620        TixSubWidget.__init__(self, master, name, destroy_physically)
1621
1622class _dummyLabel(Label, TixSubWidget):
1623    def __init__(self, master, name, destroy_physically=1):
1624        TixSubWidget.__init__(self, master, name, destroy_physically)
1625
1626class _dummyListbox(Listbox, TixSubWidget):
1627    def __init__(self, master, name, destroy_physically=1):
1628        TixSubWidget.__init__(self, master, name, destroy_physically)
1629
1630class _dummyMenu(Menu, TixSubWidget):
1631    def __init__(self, master, name, destroy_physically=1):
1632        TixSubWidget.__init__(self, master, name, destroy_physically)
1633
1634class _dummyMenubutton(Menubutton, TixSubWidget):
1635    def __init__(self, master, name, destroy_physically=1):
1636        TixSubWidget.__init__(self, master, name, destroy_physically)
1637
1638class _dummyScrollbar(Scrollbar, TixSubWidget):
1639    def __init__(self, master, name, destroy_physically=1):
1640        TixSubWidget.__init__(self, master, name, destroy_physically)
1641
1642class _dummyText(Text, TixSubWidget):
1643    def __init__(self, master, name, destroy_physically=1):
1644        TixSubWidget.__init__(self, master, name, destroy_physically)
1645
1646class _dummyScrolledListBox(ScrolledListBox, TixSubWidget):
1647    def __init__(self, master, name, destroy_physically=1):
1648        TixSubWidget.__init__(self, master, name, destroy_physically)
1649        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
1650        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1651        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1652
1653class _dummyHList(HList, TixSubWidget):
1654    def __init__(self, master, name, destroy_physically=1):
1655        TixSubWidget.__init__(self, master, name, destroy_physically)
1656
1657class _dummyScrolledHList(ScrolledHList, TixSubWidget):
1658    def __init__(self, master, name, destroy_physically=1):
1659        TixSubWidget.__init__(self, master, name, destroy_physically)
1660        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1661        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1662        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1663
1664class _dummyTList(TList, TixSubWidget):
1665    def __init__(self, master, name, destroy_physically=1):
1666        TixSubWidget.__init__(self, master, name, destroy_physically)
1667
1668class _dummyComboBox(ComboBox, TixSubWidget):
1669    def __init__(self, master, name, destroy_physically=1):
1670        TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically])
1671        self.subwidget_list['label'] = _dummyLabel(self, 'label')
1672        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
1673        self.subwidget_list['arrow'] = _dummyButton(self, 'arrow')
1674
1675        self.subwidget_list['slistbox'] = _dummyScrolledListBox(self,
1676                                                                'slistbox')
1677        try:
1678            self.subwidget_list['tick'] = _dummyButton(self, 'tick')
1679            #cross Button : present if created with the fancy option
1680            self.subwidget_list['cross'] = _dummyButton(self, 'cross')
1681        except TypeError:
1682            # unavailable when -fancy not specified
1683            pass
1684
1685class _dummyDirList(DirList, TixSubWidget):
1686    def __init__(self, master, name, destroy_physically=1):
1687        TixSubWidget.__init__(self, master, name, destroy_physically)
1688        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1689        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1690        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1691
1692class _dummyDirSelectBox(DirSelectBox, TixSubWidget):
1693    def __init__(self, master, name, destroy_physically=1):
1694        TixSubWidget.__init__(self, master, name, destroy_physically)
1695        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
1696        self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx')
1697
1698class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget):
1699    def __init__(self, master, name, destroy_physically=1):
1700        TixSubWidget.__init__(self, master, name, destroy_physically)
1701        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
1702        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
1703        self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden')
1704        self.subwidget_list['types'] = _dummyComboBox(self, 'types')
1705        self.subwidget_list['dir'] = _dummyComboBox(self, 'dir')
1706        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
1707        self.subwidget_list['file'] = _dummyComboBox(self, 'file')
1708        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
1709
1710class _dummyFileSelectBox(FileSelectBox, TixSubWidget):
1711    def __init__(self, master, name, destroy_physically=1):
1712        TixSubWidget.__init__(self, master, name, destroy_physically)
1713        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
1714        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
1715        self.subwidget_list['filter'] = _dummyComboBox(self, 'filter')
1716        self.subwidget_list['selection'] = _dummyComboBox(self, 'selection')
1717
1718class _dummyFileComboBox(ComboBox, TixSubWidget):
1719    def __init__(self, master, name, destroy_physically=1):
1720        TixSubWidget.__init__(self, master, name, destroy_physically)
1721        self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx')
1722
1723class _dummyStdButtonBox(StdButtonBox, TixSubWidget):
1724    def __init__(self, master, name, destroy_physically=1):
1725        TixSubWidget.__init__(self, master, name, destroy_physically)
1726        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
1727        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
1728        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
1729        self.subwidget_list['help'] = _dummyButton(self, 'help')
1730
1731class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget):
1732    def __init__(self, master, name, destroy_physically=0):
1733        TixSubWidget.__init__(self, master, name, destroy_physically)
1734
1735class _dummyPanedWindow(PanedWindow, TixSubWidget):
1736    def __init__(self, master, name, destroy_physically=1):
1737        TixSubWidget.__init__(self, master, name, destroy_physically)
1738
1739########################
1740### Utility Routines ###
1741########################
1742
1743#mike Should tixDestroy be exposed as a wrapper? - but not for widgets.
1744
1745def OptionName(widget):
1746    '''Returns the qualified path name for the widget. Normally used to set
1747    default options for subwidgets. See tixwidgets.py'''
1748    return widget.tk.call('tixOptionName', widget._w)
1749
1750# Called with a dictionary argument of the form
1751# {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'}
1752# returns a string which can be used to configure the fsbox file types
1753# in an ExFileSelectBox. i.e.,
1754# '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}'
1755def FileTypeList(dict):
1756    s = ''
1757    for type in dict.keys():
1758        s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} '
1759    return s
1760
1761# Still to be done:
1762# tixIconView
1763class CObjView(TixWidget):
1764    """This file implements the Canvas Object View widget. This is a base
1765    class of IconView. It implements automatic placement/adjustment of the
1766    scrollbars according to the canvas objects inside the canvas subwidget.
1767    The scrollbars are adjusted so that the canvas is just large enough
1768    to see all the objects.
1769    """
1770    # FIXME: It should inherit -superclass tixScrolledWidget
1771    pass
1772
1773
1774class Grid(TixWidget, XView, YView):
1775    '''The Tix Grid command creates a new window  and makes it into a
1776    tixGrid widget. Additional options, may be specified on the command
1777    line or in the option database to configure aspects such as its cursor
1778    and relief.
1779
1780    A Grid widget displays its contents in a two dimensional grid of cells.
1781    Each cell may contain one Tix display item, which may be in text,
1782    graphics or other formats. See the DisplayStyle class for more information
1783    about Tix display items. Individual cells, or groups of cells, can be
1784    formatted with a wide range of attributes, such as its color, relief and
1785    border.
1786
1787    Subwidgets - None'''
1788    # valid specific resources as of Tk 8.4
1789    # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd,
1790    # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode,
1791    # selectunit, topmargin,
1792    def __init__(self, master=None, cnf={}, **kw):
1793        static= []
1794        self.cnf= cnf
1795        TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw)
1796
1797    # valid options as of Tk 8.4
1798    # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget,
1799    # edit, entryconfigure, format, geometryinfo, info, index, move, nearest,
1800    # selection, set, size, unset, xview, yview
1801    def anchor_clear(self):
1802        """Removes the selection anchor."""
1803        self.tk.call(self, 'anchor', 'clear')
1804
1805    def anchor_get(self):
1806        "Get the (x,y) coordinate of the current anchor cell"
1807        return self._getints(self.tk.call(self, 'anchor', 'get'))
1808
1809    def anchor_set(self, x, y):
1810        """Set the selection anchor to the cell at (x, y)."""
1811        self.tk.call(self, 'anchor', 'set', x, y)
1812
1813    def delete_row(self, from_, to=None):
1814        """Delete rows between from_ and to inclusive.
1815        If to is not provided,  delete only row at from_"""
1816        if to is None:
1817            self.tk.call(self, 'delete', 'row', from_)
1818        else:
1819            self.tk.call(self, 'delete', 'row', from_, to)
1820
1821    def delete_column(self, from_, to=None):
1822        """Delete columns between from_ and to inclusive.
1823        If to is not provided,  delete only column at from_"""
1824        if to is None:
1825            self.tk.call(self, 'delete', 'column', from_)
1826        else:
1827            self.tk.call(self, 'delete', 'column', from_, to)
1828
1829    def edit_apply(self):
1830        """If any cell is being edited, de-highlight the cell  and  applies
1831        the changes."""
1832        self.tk.call(self, 'edit', 'apply')
1833
1834    def edit_set(self, x, y):
1835        """Highlights  the  cell  at  (x, y) for editing, if the -editnotify
1836        command returns True for this cell."""
1837        self.tk.call(self, 'edit', 'set', x, y)
1838
1839    def entrycget(self, x, y, option):
1840        "Get the option value for cell at (x,y)"
1841        if option and option[0] != '-':
1842            option = '-' + option
1843        return self.tk.call(self, 'entrycget', x, y, option)
1844
1845    def entryconfigure(self, x, y, cnf=None, **kw):
1846        return self._configure(('entryconfigure', x, y), cnf, kw)
1847
1848    # def format
1849    # def index
1850
1851    def info_exists(self, x, y):
1852        "Return True if display item exists at (x,y)"
1853        return self._getboolean(self.tk.call(self, 'info', 'exists', x, y))
1854
1855    def info_bbox(self, x, y):
1856        # This seems to always return '', at least for 'text' displayitems
1857        return self.tk.call(self, 'info', 'bbox', x, y)
1858
1859    def move_column(self, from_, to, offset):
1860        """Moves the range of columns from position FROM through TO by
1861        the distance indicated by OFFSET. For example, move_column(2, 4, 1)
1862        moves the columns 2,3,4 to columns 3,4,5."""
1863        self.tk.call(self, 'move', 'column', from_, to, offset)
1864
1865    def move_row(self, from_, to, offset):
1866        """Moves the range of rows from position FROM through TO by
1867        the distance indicated by OFFSET.
1868        For example, move_row(2, 4, 1) moves the rows 2,3,4 to rows 3,4,5."""
1869        self.tk.call(self, 'move', 'row', from_, to, offset)
1870
1871    def nearest(self, x, y):
1872        "Return coordinate of cell nearest pixel coordinate (x,y)"
1873        return self._getints(self.tk.call(self, 'nearest', x, y))
1874
1875    # def selection adjust
1876    # def selection clear
1877    # def selection includes
1878    # def selection set
1879    # def selection toggle
1880
1881    def set(self, x, y, itemtype=None, **kw):
1882        args= self._options(self.cnf, kw)
1883        if itemtype is not None:
1884            args= ('-itemtype', itemtype) + args
1885        self.tk.call(self, 'set', x, y, *args)
1886
1887    def size_column(self, index, **kw):
1888        """Queries or sets the size of the column given by
1889        INDEX.  INDEX may be any non-negative
1890        integer that gives the position of a given column.
1891        INDEX can also be the string "default"; in this case, this command
1892        queries or sets the default size of all columns.
1893        When no option-value pair is given, this command returns a tuple
1894        containing the current size setting of the given column.  When
1895        option-value pairs are given, the corresponding options of the
1896        size setting of the given column are changed. Options may be one
1897        of the follwing:
1898              pad0 pixels
1899                     Specifies the paddings to the left of a column.
1900              pad1 pixels
1901                     Specifies the paddings to the right of a column.
1902              size val
1903                     Specifies the width of a column.  Val may be:
1904                     "auto" -- the width of the column is set to the
1905                     width of the widest cell in the column;
1906                     a valid Tk screen distance unit;
1907                     or a real number following by the word chars
1908                     (e.g. 3.4chars) that sets the width of the column to the
1909                     given number of characters."""
1910        return self.tk.split(self.tk.call(self._w, 'size', 'column', index,
1911                             *self._options({}, kw)))
1912
1913    def size_row(self, index, **kw):
1914        """Queries or sets the size of the row given by
1915        INDEX. INDEX may be any non-negative
1916        integer that gives the position of a given row .
1917        INDEX can also be the string "default"; in this case, this command
1918        queries or sets the default size of all rows.
1919        When no option-value pair is given, this command returns a list con-
1920        taining the current size setting of the given row . When option-value
1921        pairs are given, the corresponding options of the size setting of the
1922        given row are changed. Options may be one of the follwing:
1923              pad0 pixels
1924                     Specifies the paddings to the top of a row.
1925              pad1 pixels
1926                     Specifies the paddings to the bottom of a row.
1927              size val
1928                     Specifies the height of a row.  Val may be:
1929                     "auto" -- the height of the row is set to the
1930                     height of the highest cell in the row;
1931                     a valid Tk screen distance unit;
1932                     or a real number following by the word chars
1933                     (e.g. 3.4chars) that sets the height of the row to the
1934                     given number of characters."""
1935        return self.tk.split(self.tk.call(
1936                    self, 'size', 'row', index, *self._options({}, kw)))
1937
1938    def unset(self, x, y):
1939        """Clears the cell at (x, y) by removing its display item."""
1940        self.tk.call(self._w, 'unset', x, y)
1941
1942
1943class ScrolledGrid(Grid):
1944    '''Scrolled Grid widgets'''
1945
1946    # FIXME: It should inherit -superclass tixScrolledWidget
1947    def __init__(self, master=None, cnf={}, **kw):
1948        static= []
1949        self.cnf= cnf
1950        TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw)
1951