• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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# NOTE: This module is deprecated since Python 3.6.
25
26import os
27import warnings
28import tkinter
29from tkinter import *
30from tkinter import _cnfmerge
31
32warnings.warn(
33    'The Tix Tk extension is unmaintained, and the tkinter.tix wrapper module'
34    ' is deprecated in favor of tkinter.ttk',
35    DeprecationWarning,
36    stacklevel=2,
37    )
38
39# Some more constants (for consistency with Tkinter)
40WINDOW = 'window'
41TEXT = 'text'
42STATUS = 'status'
43IMMEDIATE = 'immediate'
44IMAGE = 'image'
45IMAGETEXT = 'imagetext'
46BALLOON = 'balloon'
47AUTO = 'auto'
48ACROSSTOP = 'acrosstop'
49
50# A few useful constants for the Grid widget
51ASCII = 'ascii'
52CELL = 'cell'
53COLUMN = 'column'
54DECREASING = 'decreasing'
55INCREASING = 'increasing'
56INTEGER = 'integer'
57MAIN = 'main'
58MAX = 'max'
59REAL = 'real'
60ROW = 'row'
61S_REGION = 's-region'
62X_REGION = 'x-region'
63Y_REGION = 'y-region'
64
65# Some constants used by Tkinter dooneevent()
66TCL_DONT_WAIT     = 1 << 1
67TCL_WINDOW_EVENTS = 1 << 2
68TCL_FILE_EVENTS   = 1 << 3
69TCL_TIMER_EVENTS  = 1 << 4
70TCL_IDLE_EVENTS   = 1 << 5
71TCL_ALL_EVENTS    = 0
72
73# BEWARE - this is implemented by copying some code from the Widget class
74#          in Tkinter (to override Widget initialization) and is therefore
75#          liable to break.
76
77# Could probably add this to Tkinter.Misc
78class tixCommand:
79    """The tix commands provide access to miscellaneous  elements
80    of  Tix's  internal state and the Tix application context.
81    Most of the information manipulated by these  commands pertains
82    to  the  application  as a whole, or to a screen or
83    display, rather than to a particular window.
84
85    This is a mixin class, assumed to be mixed to Tkinter.Tk
86    that supports the self.tk.call method.
87    """
88
89    def tix_addbitmapdir(self, directory):
90        """Tix maintains a list of directories under which
91        the  tix_getimage  and tix_getbitmap commands will
92        search for image files. The standard bitmap  directory
93        is $TIX_LIBRARY/bitmaps. The addbitmapdir command
94        adds directory into this list. By  using  this
95        command, the  image  files  of an applications can
96        also be located using the tix_getimage or tix_getbitmap
97        command.
98        """
99        return self.tk.call('tix', 'addbitmapdir', directory)
100
101    def tix_cget(self, option):
102        """Returns  the  current  value  of the configuration
103        option given by option. Option may be  any  of  the
104        options described in the CONFIGURATION OPTIONS section.
105        """
106        return self.tk.call('tix', 'cget', option)
107
108    def tix_configure(self, cnf=None, **kw):
109        """Query or modify the configuration options of the Tix application
110        context. If no option is specified, returns a dictionary all of the
111        available options.  If option is specified with no value, then the
112        command returns a list describing the one named option (this list
113        will be identical to the corresponding sublist of the value
114        returned if no option is specified).  If one or more option-value
115        pairs are specified, then the command modifies the given option(s)
116        to have the given value(s); in this case the command returns an
117        empty string. Option may be any of the configuration options.
118        """
119        # Copied from Tkinter.py
120        if kw:
121            cnf = _cnfmerge((cnf, kw))
122        elif cnf:
123            cnf = _cnfmerge(cnf)
124        if cnf is None:
125            return self._getconfigure('tix', 'configure')
126        if isinstance(cnf, str):
127            return self._getconfigure1('tix', 'configure', '-'+cnf)
128        return self.tk.call(('tix', 'configure') + self._options(cnf))
129
130    def tix_filedialog(self, dlgclass=None):
131        """Returns the file selection dialog that may be shared among
132        different calls from this application.  This command will create a
133        file selection dialog widget when it is called the first time. This
134        dialog will be returned by all subsequent calls to tix_filedialog.
135        An optional dlgclass parameter can be passed to specified what type
136        of file selection dialog widget is desired. Possible options are
137        tix FileSelectDialog or tixExFileSelectDialog.
138        """
139        if dlgclass is not None:
140            return self.tk.call('tix', 'filedialog', dlgclass)
141        else:
142            return self.tk.call('tix', 'filedialog')
143
144    def tix_getbitmap(self, name):
145        """Locates a bitmap file of the name name.xpm or name in one of the
146        bitmap directories (see the tix_addbitmapdir command above).  By
147        using tix_getbitmap, you can avoid hard coding the pathnames of the
148        bitmap files in your application. When successful, it returns the
149        complete pathname of the bitmap file, prefixed with the character
150        '@'.  The returned value can be used to configure the -bitmap
151        option of the TK and Tix widgets.
152        """
153        return self.tk.call('tix', 'getbitmap', name)
154
155    def tix_getimage(self, name):
156        """Locates an image file of the name name.xpm, name.xbm or name.ppm
157        in one of the bitmap directories (see the addbitmapdir command
158        above). If more than one file with the same name (but different
159        extensions) exist, then the image type is chosen according to the
160        depth of the X display: xbm images are chosen on monochrome
161        displays and color images are chosen on color displays. By using
162        tix_ getimage, you can avoid hard coding the pathnames of the
163        image files in your application. When successful, this command
164        returns the name of the newly created image, which can be used to
165        configure the -image option of the Tk and Tix widgets.
166        """
167        return self.tk.call('tix', 'getimage', name)
168
169    def tix_option_get(self, name):
170        """Gets  the options  maintained  by  the  Tix
171        scheme mechanism. Available options include:
172
173            active_bg       active_fg      bg
174            bold_font       dark1_bg       dark1_fg
175            dark2_bg        dark2_fg       disabled_fg
176            fg              fixed_font     font
177            inactive_bg     inactive_fg    input1_bg
178            input2_bg       italic_font    light1_bg
179            light1_fg       light2_bg      light2_fg
180            menu_font       output1_bg     output2_bg
181            select_bg       select_fg      selector
182            """
183        # could use self.tk.globalgetvar('tixOption', name)
184        return self.tk.call('tix', 'option', 'get', name)
185
186    def tix_resetoptions(self, newScheme, newFontSet, newScmPrio=None):
187        """Resets the scheme and fontset of the Tix application to
188        newScheme and newFontSet, respectively.  This affects only those
189        widgets created after this call. Therefore, it is best to call the
190        resetoptions command before the creation of any widgets in a Tix
191        application.
192
193        The optional parameter newScmPrio can be given to reset the
194        priority level of the Tk options set by the Tix schemes.
195
196        Because of the way Tk handles the X option database, after Tix has
197        been has imported and inited, it is not possible to reset the color
198        schemes and font sets using the tix config command.  Instead, the
199        tix_resetoptions command must be used.
200        """
201        if newScmPrio is not None:
202            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet, newScmPrio)
203        else:
204            return self.tk.call('tix', 'resetoptions', newScheme, newFontSet)
205
206class Tk(tkinter.Tk, tixCommand):
207    """Toplevel widget of Tix which represents mostly the main window
208    of an application. It has an associated Tcl interpreter."""
209    def __init__(self, screenName=None, baseName=None, className='Tix'):
210        tkinter.Tk.__init__(self, screenName, baseName, className)
211        tixlib = os.environ.get('TIX_LIBRARY')
212        self.tk.eval('global auto_path; lappend auto_path [file dir [info nameof]]')
213        if tixlib is not None:
214            self.tk.eval('global auto_path; lappend auto_path {%s}' % tixlib)
215            self.tk.eval('global tcl_pkgPath; lappend tcl_pkgPath {%s}' % tixlib)
216        # Load Tix - this should work dynamically or statically
217        # If it's static, tcl/tix8.1/pkgIndex.tcl should have
218        #               'load {} Tix'
219        # If it's dynamic under Unix, tcl/tix8.1/pkgIndex.tcl should have
220        #               'load libtix8.1.8.3.so Tix'
221        self.tk.eval('package require Tix')
222
223    def destroy(self):
224        # For safety, remove the delete_window binding before destroy
225        self.protocol("WM_DELETE_WINDOW", "")
226        tkinter.Tk.destroy(self)
227
228# The Tix 'tixForm' geometry manager
229class Form:
230    """The Tix Form geometry manager
231
232    Widgets can be arranged by specifying attachments to other widgets.
233    See Tix documentation for complete details"""
234
235    def config(self, cnf={}, **kw):
236        self.tk.call('tixForm', self._w, *self._options(cnf, kw))
237
238    form = config
239
240    def __setitem__(self, key, value):
241        Form.form(self, {key: value})
242
243    def check(self):
244        return self.tk.call('tixForm', 'check', self._w)
245
246    def forget(self):
247        self.tk.call('tixForm', 'forget', self._w)
248
249    def grid(self, xsize=0, ysize=0):
250        if (not xsize) and (not ysize):
251            x = self.tk.call('tixForm', 'grid', self._w)
252            y = self.tk.splitlist(x)
253            z = ()
254            for x in y:
255                z = z + (self.tk.getint(x),)
256            return z
257        return self.tk.call('tixForm', 'grid', self._w, xsize, ysize)
258
259    def info(self, option=None):
260        if not option:
261            return self.tk.call('tixForm', 'info', self._w)
262        if option[0] != '-':
263            option = '-' + option
264        return self.tk.call('tixForm', 'info', self._w, option)
265
266    def slaves(self):
267        return [self._nametowidget(x) for x in
268                self.tk.splitlist(
269                       self.tk.call(
270                       'tixForm', 'slaves', self._w))]
271
272
273
274tkinter.Widget.__bases__ = tkinter.Widget.__bases__ + (Form,)
275
276class TixWidget(tkinter.Widget):
277    """A TixWidget class is used to package all (or most) Tix widgets.
278
279    Widget initialization is extended in two ways:
280       1) It is possible to give a list of options which must be part of
281       the creation command (so called Tix 'static' options). These cannot be
282       given as a 'config' command later.
283       2) It is possible to give the name of an existing TK widget. These are
284       child widgets created automatically by a Tix mega-widget. The Tk call
285       to create these widgets is therefore bypassed in TixWidget.__init__
286
287    Both options are for use by subclasses only.
288    """
289    def __init__ (self, master=None, widgetName=None,
290                static_options=None, cnf={}, kw={}):
291        # Merge keywords and dictionary arguments
292        if kw:
293            cnf = _cnfmerge((cnf, kw))
294        else:
295            cnf = _cnfmerge(cnf)
296
297        # Move static options into extra. static_options must be
298        # a list of keywords (or None).
299        extra=()
300
301        # 'options' is always a static option
302        if static_options:
303            static_options.append('options')
304        else:
305            static_options = ['options']
306
307        for k,v in list(cnf.items()):
308            if k in static_options:
309                extra = extra + ('-' + k, v)
310                del cnf[k]
311
312        self.widgetName = widgetName
313        Widget._setup(self, master, cnf)
314
315        # If widgetName is None, this is a dummy creation call where the
316        # corresponding Tk widget has already been created by Tix
317        if widgetName:
318            self.tk.call(widgetName, self._w, *extra)
319
320        # Non-static options - to be done via a 'config' command
321        if cnf:
322            Widget.config(self, cnf)
323
324        # Dictionary to hold subwidget names for easier access. We can't
325        # use the children list because the public Tix names may not be the
326        # same as the pathname component
327        self.subwidget_list = {}
328
329    # We set up an attribute access function so that it is possible to
330    # do w.ok['text'] = 'Hello' rather than w.subwidget('ok')['text'] = 'Hello'
331    # when w is a StdButtonBox.
332    # We can even do w.ok.invoke() because w.ok is subclassed from the
333    # Button class if you go through the proper constructors
334    def __getattr__(self, name):
335        if name in self.subwidget_list:
336            return self.subwidget_list[name]
337        raise AttributeError(name)
338
339    def set_silent(self, value):
340        """Set a variable without calling its action routine"""
341        self.tk.call('tixSetSilent', self._w, value)
342
343    def subwidget(self, name):
344        """Return the named subwidget (which must have been created by
345        the sub-class)."""
346        n = self._subwidget_name(name)
347        if not n:
348            raise TclError("Subwidget " + name + " not child of " + self._name)
349        # Remove header of name and leading dot
350        n = n[len(self._w)+1:]
351        return self._nametowidget(n)
352
353    def subwidgets_all(self):
354        """Return all subwidgets."""
355        names = self._subwidget_names()
356        if not names:
357            return []
358        retlist = []
359        for name in names:
360            name = name[len(self._w)+1:]
361            try:
362                retlist.append(self._nametowidget(name))
363            except:
364                # some of the widgets are unknown e.g. border in LabelFrame
365                pass
366        return retlist
367
368    def _subwidget_name(self,name):
369        """Get a subwidget name (returns a String, not a Widget !)"""
370        try:
371            return self.tk.call(self._w, 'subwidget', name)
372        except TclError:
373            return None
374
375    def _subwidget_names(self):
376        """Return the name of all subwidgets."""
377        try:
378            x = self.tk.call(self._w, 'subwidgets', '-all')
379            return self.tk.splitlist(x)
380        except TclError:
381            return None
382
383    def config_all(self, option, value):
384        """Set configuration options for all subwidgets (and self)."""
385        if option == '':
386            return
387        elif not isinstance(option, str):
388            option = repr(option)
389        if not isinstance(value, str):
390            value = repr(value)
391        names = self._subwidget_names()
392        for name in names:
393            self.tk.call(name, 'configure', '-' + option, value)
394    # These are missing from Tkinter
395    def image_create(self, imgtype, cnf={}, master=None, **kw):
396        if master is None:
397            master = self
398        if kw and cnf: cnf = _cnfmerge((cnf, kw))
399        elif kw: cnf = kw
400        options = ()
401        for k, v in cnf.items():
402            if callable(v):
403                v = self._register(v)
404            options = options + ('-'+k, v)
405        return master.tk.call(('image', 'create', imgtype,) + options)
406    def image_delete(self, imgname):
407        try:
408            self.tk.call('image', 'delete', imgname)
409        except TclError:
410            # May happen if the root was destroyed
411            pass
412
413# Subwidgets are child widgets created automatically by mega-widgets.
414# In python, we have to create these subwidgets manually to mirror their
415# existence in Tk/Tix.
416class TixSubWidget(TixWidget):
417    """Subwidget class.
418
419    This is used to mirror child widgets automatically created
420    by Tix/Tk as part of a mega-widget in Python (which is not informed
421    of this)"""
422
423    def __init__(self, master, name,
424               destroy_physically=1, check_intermediate=1):
425        if check_intermediate:
426            path = master._subwidget_name(name)
427            try:
428                path = path[len(master._w)+1:]
429                plist = path.split('.')
430            except:
431                plist = []
432
433        if not check_intermediate:
434            # immediate descendant
435            TixWidget.__init__(self, master, None, None, {'name' : name})
436        else:
437            # Ensure that the intermediate widgets exist
438            parent = master
439            for i in range(len(plist) - 1):
440                n = '.'.join(plist[:i+1])
441                try:
442                    w = master._nametowidget(n)
443                    parent = w
444                except KeyError:
445                    # Create the intermediate widget
446                    parent = TixSubWidget(parent, plist[i],
447                                          destroy_physically=0,
448                                          check_intermediate=0)
449            # The Tk widget name is in plist, not in name
450            if plist:
451                name = plist[-1]
452            TixWidget.__init__(self, parent, None, None, {'name' : name})
453        self.destroy_physically = destroy_physically
454
455    def destroy(self):
456        # For some widgets e.g., a NoteBook, when we call destructors,
457        # we must be careful not to destroy the frame widget since this
458        # also destroys the parent NoteBook thus leading to an exception
459        # in Tkinter when it finally calls Tcl to destroy the NoteBook
460        for c in list(self.children.values()): c.destroy()
461        if self._name in self.master.children:
462            del self.master.children[self._name]
463        if self._name in self.master.subwidget_list:
464            del self.master.subwidget_list[self._name]
465        if self.destroy_physically:
466            # This is bypassed only for a few widgets
467            self.tk.call('destroy', self._w)
468
469
470# Useful class to create a display style - later shared by many items.
471# Contributed by Steffen Kremser
472class DisplayStyle:
473    """DisplayStyle - handle configuration options shared by
474    (multiple) Display Items"""
475
476    def __init__(self, itemtype, cnf={}, *, master=None, **kw):
477        if master is None:
478            if 'refwindow' in kw:
479                master = kw['refwindow']
480            elif 'refwindow' in cnf:
481                master = cnf['refwindow']
482            else:
483                master = tkinter._get_default_root('create display style')
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 parent is None:
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.splitlist(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.splitlist(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', ['options'], cnf, kw)
1190        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
1191        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
1192
1193    def add_command(self, name, cnf={}, **kw):
1194        self.tk.call(self._w, 'add', 'command', name, *self._options(cnf, kw))
1195
1196    def add_separator(self, name, cnf={}, **kw):
1197        self.tk.call(self._w, 'add', 'separator', name, *self._options(cnf, kw))
1198
1199    def delete(self, name):
1200        self.tk.call(self._w, 'delete', name)
1201
1202    def disable(self, name):
1203        self.tk.call(self._w, 'disable', name)
1204
1205    def enable(self, name):
1206        self.tk.call(self._w, 'enable', name)
1207
1208class PanedWindow(TixWidget):
1209    """PanedWindow - Multi-pane container widget
1210    allows the user to interactively manipulate the sizes of several
1211    panes. The panes can be arranged either vertically or horizontally.The
1212    user changes the sizes of the panes by dragging the resize handle
1213    between two panes.
1214
1215    Subwidgets       Class
1216    ----------       -----
1217    <panes>       g/p widgets added dynamically with the add method."""
1218
1219    def __init__(self, master, cnf={}, **kw):
1220        TixWidget.__init__(self, master, 'tixPanedWindow', ['orientation', 'options'], cnf, kw)
1221
1222    # add delete forget panecget paneconfigure panes setsize
1223    def add(self, name, cnf={}, **kw):
1224        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
1225        self.subwidget_list[name] = TixSubWidget(self, name,
1226                                                 check_intermediate=0)
1227        return self.subwidget_list[name]
1228
1229    def delete(self, name):
1230        self.tk.call(self._w, 'delete', name)
1231        self.subwidget_list[name].destroy()
1232        del self.subwidget_list[name]
1233
1234    def forget(self, name):
1235        self.tk.call(self._w, 'forget', name)
1236
1237    def panecget(self,  entry, opt):
1238        return self.tk.call(self._w, 'panecget', entry, opt)
1239
1240    def paneconfigure(self, entry, cnf={}, **kw):
1241        if cnf is None:
1242            return self._getconfigure(self._w, 'paneconfigure', entry)
1243        self.tk.call(self._w, 'paneconfigure', entry, *self._options(cnf, kw))
1244
1245    def panes(self):
1246        names = self.tk.splitlist(self.tk.call(self._w, 'panes'))
1247        return [self.subwidget(x) for x in names]
1248
1249class PopupMenu(TixWidget):
1250    """PopupMenu widget can be used as a replacement of the tk_popup command.
1251    The advantage of the Tix PopupMenu widget is it requires less application
1252    code to manipulate.
1253
1254
1255    Subwidgets       Class
1256    ----------       -----
1257    menubutton       Menubutton
1258    menu       Menu"""
1259
1260    # FIXME: It should inherit -superclass tixShell
1261    def __init__(self, master, cnf={}, **kw):
1262        TixWidget.__init__(self, master, 'tixPopupMenu', ['options'], cnf, kw)
1263        self.subwidget_list['menubutton'] = _dummyMenubutton(self, 'menubutton')
1264        self.subwidget_list['menu'] = _dummyMenu(self, 'menu')
1265
1266    def bind_widget(self, widget):
1267        self.tk.call(self._w, 'bind', widget._w)
1268
1269    def unbind_widget(self, widget):
1270        self.tk.call(self._w, 'unbind', widget._w)
1271
1272    def post_widget(self, widget, x, y):
1273        self.tk.call(self._w, 'post', widget._w, x, y)
1274
1275class ResizeHandle(TixWidget):
1276    """Internal widget to draw resize handles on Scrolled widgets."""
1277    def __init__(self, master, cnf={}, **kw):
1278        # There seems to be a Tix bug rejecting the configure method
1279        # Let's try making the flags -static
1280        flags = ['options', 'command', 'cursorfg', 'cursorbg',
1281                 'handlesize', 'hintcolor', 'hintwidth',
1282                 'x', 'y']
1283        # In fact, x y height width are configurable
1284        TixWidget.__init__(self, master, 'tixResizeHandle',
1285                           flags, cnf, kw)
1286
1287    def attach_widget(self, widget):
1288        self.tk.call(self._w, 'attachwidget', widget._w)
1289
1290    def detach_widget(self, widget):
1291        self.tk.call(self._w, 'detachwidget', widget._w)
1292
1293    def hide(self, widget):
1294        self.tk.call(self._w, 'hide', widget._w)
1295
1296    def show(self, widget):
1297        self.tk.call(self._w, 'show', widget._w)
1298
1299class ScrolledHList(TixWidget):
1300    """ScrolledHList - HList with automatic scrollbars."""
1301
1302    # FIXME: It should inherit -superclass tixScrolledWidget
1303    def __init__(self, master, cnf={}, **kw):
1304        TixWidget.__init__(self, master, 'tixScrolledHList', ['options'],
1305                           cnf, kw)
1306        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1307        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1308        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1309
1310class ScrolledListBox(TixWidget):
1311    """ScrolledListBox - Listbox with automatic scrollbars."""
1312
1313    # FIXME: It should inherit -superclass tixScrolledWidget
1314    def __init__(self, master, cnf={}, **kw):
1315        TixWidget.__init__(self, master, 'tixScrolledListBox', ['options'], cnf, kw)
1316        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
1317        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1318        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1319
1320class ScrolledText(TixWidget):
1321    """ScrolledText - Text with automatic scrollbars."""
1322
1323    # FIXME: It should inherit -superclass tixScrolledWidget
1324    def __init__(self, master, cnf={}, **kw):
1325        TixWidget.__init__(self, master, 'tixScrolledText', ['options'], cnf, kw)
1326        self.subwidget_list['text'] = _dummyText(self, 'text')
1327        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1328        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1329
1330class ScrolledTList(TixWidget):
1331    """ScrolledTList - TList with automatic scrollbars."""
1332
1333    # FIXME: It should inherit -superclass tixScrolledWidget
1334    def __init__(self, master, cnf={}, **kw):
1335        TixWidget.__init__(self, master, 'tixScrolledTList', ['options'],
1336                           cnf, kw)
1337        self.subwidget_list['tlist'] = _dummyTList(self, 'tlist')
1338        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1339        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1340
1341class ScrolledWindow(TixWidget):
1342    """ScrolledWindow - Window with automatic scrollbars."""
1343
1344    # FIXME: It should inherit -superclass tixScrolledWidget
1345    def __init__(self, master, cnf={}, **kw):
1346        TixWidget.__init__(self, master, 'tixScrolledWindow', ['options'], cnf, kw)
1347        self.subwidget_list['window'] = _dummyFrame(self, 'window')
1348        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1349        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1350
1351class Select(TixWidget):
1352    """Select - Container of button subwidgets. It can be used to provide
1353    radio-box or check-box style of selection options for the user.
1354
1355    Subwidgets are buttons added dynamically using the add method."""
1356
1357    # FIXME: It should inherit -superclass tixLabelWidget
1358    def __init__(self, master, cnf={}, **kw):
1359        TixWidget.__init__(self, master, 'tixSelect',
1360                           ['allowzero', 'radio', 'orientation', 'labelside',
1361                            'options'],
1362                           cnf, kw)
1363        self.subwidget_list['label'] = _dummyLabel(self, 'label')
1364
1365    def add(self, name, cnf={}, **kw):
1366        self.tk.call(self._w, 'add', name, *self._options(cnf, kw))
1367        self.subwidget_list[name] = _dummyButton(self, name)
1368        return self.subwidget_list[name]
1369
1370    def invoke(self, name):
1371        self.tk.call(self._w, 'invoke', name)
1372
1373class Shell(TixWidget):
1374    """Toplevel window.
1375
1376    Subwidgets - None"""
1377
1378    def __init__ (self,master=None,cnf={}, **kw):
1379        TixWidget.__init__(self, master, 'tixShell', ['options', 'title'], cnf, kw)
1380
1381class DialogShell(TixWidget):
1382    """Toplevel window, with popup popdown and center methods.
1383    It tells the window manager that it is a dialog window and should be
1384    treated specially. The exact treatment depends on the treatment of
1385    the window manager.
1386
1387    Subwidgets - None"""
1388
1389    # FIXME: It should inherit from  Shell
1390    def __init__ (self,master=None,cnf={}, **kw):
1391        TixWidget.__init__(self, master,
1392                           'tixDialogShell',
1393                           ['options', 'title', 'mapped',
1394                            'minheight', 'minwidth',
1395                            'parent', 'transient'], cnf, kw)
1396
1397    def popdown(self):
1398        self.tk.call(self._w, 'popdown')
1399
1400    def popup(self):
1401        self.tk.call(self._w, 'popup')
1402
1403    def center(self):
1404        self.tk.call(self._w, 'center')
1405
1406class StdButtonBox(TixWidget):
1407    """StdButtonBox - Standard Button Box (OK, Apply, Cancel and Help) """
1408
1409    def __init__(self, master=None, cnf={}, **kw):
1410        TixWidget.__init__(self, master, 'tixStdButtonBox',
1411                           ['orientation', 'options'], cnf, kw)
1412        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
1413        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
1414        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
1415        self.subwidget_list['help'] = _dummyButton(self, 'help')
1416
1417    def invoke(self, name):
1418        if name in self.subwidget_list:
1419            self.tk.call(self._w, 'invoke', name)
1420
1421class TList(TixWidget, XView, YView):
1422    """TList - Hierarchy display widget which can be
1423    used to display data in a tabular format. The list entries of a TList
1424    widget are similar to the entries in the Tk listbox widget. The main
1425    differences are (1) the TList widget can display the list entries in a
1426    two dimensional format and (2) you can use graphical images as well as
1427    multiple colors and fonts for the list entries.
1428
1429    Subwidgets - None"""
1430
1431    def __init__ (self,master=None,cnf={}, **kw):
1432        TixWidget.__init__(self, master, 'tixTList', ['options'], cnf, kw)
1433
1434    def active_set(self, index):
1435        self.tk.call(self._w, 'active', 'set', index)
1436
1437    def active_clear(self):
1438        self.tk.call(self._w, 'active', 'clear')
1439
1440    def anchor_set(self, index):
1441        self.tk.call(self._w, 'anchor', 'set', index)
1442
1443    def anchor_clear(self):
1444        self.tk.call(self._w, 'anchor', 'clear')
1445
1446    def delete(self, from_, to=None):
1447        self.tk.call(self._w, 'delete', from_, to)
1448
1449    def dragsite_set(self, index):
1450        self.tk.call(self._w, 'dragsite', 'set', index)
1451
1452    def dragsite_clear(self):
1453        self.tk.call(self._w, 'dragsite', 'clear')
1454
1455    def dropsite_set(self, index):
1456        self.tk.call(self._w, 'dropsite', 'set', index)
1457
1458    def dropsite_clear(self):
1459        self.tk.call(self._w, 'dropsite', 'clear')
1460
1461    def insert(self, index, cnf={}, **kw):
1462        self.tk.call(self._w, 'insert', index, *self._options(cnf, kw))
1463
1464    def info_active(self):
1465        return self.tk.call(self._w, 'info', 'active')
1466
1467    def info_anchor(self):
1468        return self.tk.call(self._w, 'info', 'anchor')
1469
1470    def info_down(self, index):
1471        return self.tk.call(self._w, 'info', 'down', index)
1472
1473    def info_left(self, index):
1474        return self.tk.call(self._w, 'info', 'left', index)
1475
1476    def info_right(self, index):
1477        return self.tk.call(self._w, 'info', 'right', index)
1478
1479    def info_selection(self):
1480        c = self.tk.call(self._w, 'info', 'selection')
1481        return self.tk.splitlist(c)
1482
1483    def info_size(self):
1484        return self.tk.call(self._w, 'info', 'size')
1485
1486    def info_up(self, index):
1487        return self.tk.call(self._w, 'info', 'up', index)
1488
1489    def nearest(self, x, y):
1490        return self.tk.call(self._w, 'nearest', x, y)
1491
1492    def see(self, index):
1493        self.tk.call(self._w, 'see', index)
1494
1495    def selection_clear(self, cnf={}, **kw):
1496        self.tk.call(self._w, 'selection', 'clear', *self._options(cnf, kw))
1497
1498    def selection_includes(self, index):
1499        return self.tk.call(self._w, 'selection', 'includes', index)
1500
1501    def selection_set(self, first, last=None):
1502        self.tk.call(self._w, 'selection', 'set', first, last)
1503
1504class Tree(TixWidget):
1505    """Tree - The tixTree widget can be used to display hierarchical
1506    data in a tree form. The user can adjust
1507    the view of the tree by opening or closing parts of the tree."""
1508
1509    # FIXME: It should inherit -superclass tixScrolledWidget
1510    def __init__(self, master=None, cnf={}, **kw):
1511        TixWidget.__init__(self, master, 'tixTree',
1512                           ['options'], cnf, kw)
1513        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1514        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1515        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1516
1517    def autosetmode(self):
1518        '''This command calls the setmode method for all the entries in this
1519     Tree widget: if an entry has no child entries, its mode is set to
1520     none. Otherwise, if the entry has any hidden child entries, its mode is
1521     set to open; otherwise its mode is set to close.'''
1522        self.tk.call(self._w, 'autosetmode')
1523
1524    def close(self, entrypath):
1525        '''Close the entry given by entryPath if its mode is close.'''
1526        self.tk.call(self._w, 'close', entrypath)
1527
1528    def getmode(self, entrypath):
1529        '''Returns the current mode of the entry given by entryPath.'''
1530        return self.tk.call(self._w, 'getmode', entrypath)
1531
1532    def open(self, entrypath):
1533        '''Open the entry given by entryPath if its mode is open.'''
1534        self.tk.call(self._w, 'open', entrypath)
1535
1536    def setmode(self, entrypath, mode='none'):
1537        '''This command is used to indicate whether the entry given by
1538     entryPath has children entries and whether the children are visible. mode
1539     must be one of open, close or none. If mode is set to open, a (+)
1540     indicator is drawn next the entry. If mode is set to close, a (-)
1541     indicator is drawn next the entry. If mode is set to none, no
1542     indicators will be drawn for this entry. The default mode is none. The
1543     open mode indicates the entry has hidden children and this entry can be
1544     opened by the user. The close mode indicates that all the children of the
1545     entry are now visible and the entry can be closed by the user.'''
1546        self.tk.call(self._w, 'setmode', entrypath, mode)
1547
1548
1549# Could try subclassing Tree for CheckList - would need another arg to init
1550class CheckList(TixWidget):
1551    """The CheckList widget
1552    displays a list of items to be selected by the user. CheckList acts
1553    similarly to the Tk checkbutton or radiobutton widgets, except it is
1554    capable of handling many more items than checkbuttons or radiobuttons.
1555    """
1556    # FIXME: It should inherit -superclass tixTree
1557    def __init__(self, master=None, cnf={}, **kw):
1558        TixWidget.__init__(self, master, 'tixCheckList',
1559                           ['options', 'radio'], cnf, kw)
1560        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1561        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1562        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1563
1564    def autosetmode(self):
1565        '''This command calls the setmode method for all the entries in this
1566     Tree widget: if an entry has no child entries, its mode is set to
1567     none. Otherwise, if the entry has any hidden child entries, its mode is
1568     set to open; otherwise its mode is set to close.'''
1569        self.tk.call(self._w, 'autosetmode')
1570
1571    def close(self, entrypath):
1572        '''Close the entry given by entryPath if its mode is close.'''
1573        self.tk.call(self._w, 'close', entrypath)
1574
1575    def getmode(self, entrypath):
1576        '''Returns the current mode of the entry given by entryPath.'''
1577        return self.tk.call(self._w, 'getmode', entrypath)
1578
1579    def open(self, entrypath):
1580        '''Open the entry given by entryPath if its mode is open.'''
1581        self.tk.call(self._w, 'open', entrypath)
1582
1583    def getselection(self, mode='on'):
1584        '''Returns a list of items whose status matches status. If status is
1585     not specified, the list of items in the "on" status will be returned.
1586     Mode can be on, off, default'''
1587        return self.tk.splitlist(self.tk.call(self._w, 'getselection', mode))
1588
1589    def getstatus(self, entrypath):
1590        '''Returns the current status of entryPath.'''
1591        return self.tk.call(self._w, 'getstatus', entrypath)
1592
1593    def setstatus(self, entrypath, mode='on'):
1594        '''Sets the status of entryPath to be status. A bitmap will be
1595     displayed next to the entry its status is on, off or default.'''
1596        self.tk.call(self._w, 'setstatus', entrypath, mode)
1597
1598
1599###########################################################################
1600### The subclassing below is used to instantiate the subwidgets in each ###
1601### mega widget. This allows us to access their methods directly.       ###
1602###########################################################################
1603
1604class _dummyButton(Button, TixSubWidget):
1605    def __init__(self, master, name, destroy_physically=1):
1606        TixSubWidget.__init__(self, master, name, destroy_physically)
1607
1608class _dummyCheckbutton(Checkbutton, TixSubWidget):
1609    def __init__(self, master, name, destroy_physically=1):
1610        TixSubWidget.__init__(self, master, name, destroy_physically)
1611
1612class _dummyEntry(Entry, TixSubWidget):
1613    def __init__(self, master, name, destroy_physically=1):
1614        TixSubWidget.__init__(self, master, name, destroy_physically)
1615
1616class _dummyFrame(Frame, TixSubWidget):
1617    def __init__(self, master, name, destroy_physically=1):
1618        TixSubWidget.__init__(self, master, name, destroy_physically)
1619
1620class _dummyLabel(Label, TixSubWidget):
1621    def __init__(self, master, name, destroy_physically=1):
1622        TixSubWidget.__init__(self, master, name, destroy_physically)
1623
1624class _dummyListbox(Listbox, TixSubWidget):
1625    def __init__(self, master, name, destroy_physically=1):
1626        TixSubWidget.__init__(self, master, name, destroy_physically)
1627
1628class _dummyMenu(Menu, TixSubWidget):
1629    def __init__(self, master, name, destroy_physically=1):
1630        TixSubWidget.__init__(self, master, name, destroy_physically)
1631
1632class _dummyMenubutton(Menubutton, TixSubWidget):
1633    def __init__(self, master, name, destroy_physically=1):
1634        TixSubWidget.__init__(self, master, name, destroy_physically)
1635
1636class _dummyScrollbar(Scrollbar, TixSubWidget):
1637    def __init__(self, master, name, destroy_physically=1):
1638        TixSubWidget.__init__(self, master, name, destroy_physically)
1639
1640class _dummyText(Text, TixSubWidget):
1641    def __init__(self, master, name, destroy_physically=1):
1642        TixSubWidget.__init__(self, master, name, destroy_physically)
1643
1644class _dummyScrolledListBox(ScrolledListBox, TixSubWidget):
1645    def __init__(self, master, name, destroy_physically=1):
1646        TixSubWidget.__init__(self, master, name, destroy_physically)
1647        self.subwidget_list['listbox'] = _dummyListbox(self, 'listbox')
1648        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1649        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1650
1651class _dummyHList(HList, TixSubWidget):
1652    def __init__(self, master, name, destroy_physically=1):
1653        TixSubWidget.__init__(self, master, name, destroy_physically)
1654
1655class _dummyScrolledHList(ScrolledHList, TixSubWidget):
1656    def __init__(self, master, name, destroy_physically=1):
1657        TixSubWidget.__init__(self, master, name, destroy_physically)
1658        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1659        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1660        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1661
1662class _dummyTList(TList, TixSubWidget):
1663    def __init__(self, master, name, destroy_physically=1):
1664        TixSubWidget.__init__(self, master, name, destroy_physically)
1665
1666class _dummyComboBox(ComboBox, TixSubWidget):
1667    def __init__(self, master, name, destroy_physically=1):
1668        TixSubWidget.__init__(self, master, name, ['fancy',destroy_physically])
1669        self.subwidget_list['label'] = _dummyLabel(self, 'label')
1670        self.subwidget_list['entry'] = _dummyEntry(self, 'entry')
1671        self.subwidget_list['arrow'] = _dummyButton(self, 'arrow')
1672
1673        self.subwidget_list['slistbox'] = _dummyScrolledListBox(self,
1674                                                                'slistbox')
1675        try:
1676            self.subwidget_list['tick'] = _dummyButton(self, 'tick')
1677            #cross Button : present if created with the fancy option
1678            self.subwidget_list['cross'] = _dummyButton(self, 'cross')
1679        except TypeError:
1680            # unavailable when -fancy not specified
1681            pass
1682
1683class _dummyDirList(DirList, TixSubWidget):
1684    def __init__(self, master, name, destroy_physically=1):
1685        TixSubWidget.__init__(self, master, name, destroy_physically)
1686        self.subwidget_list['hlist'] = _dummyHList(self, 'hlist')
1687        self.subwidget_list['vsb'] = _dummyScrollbar(self, 'vsb')
1688        self.subwidget_list['hsb'] = _dummyScrollbar(self, 'hsb')
1689
1690class _dummyDirSelectBox(DirSelectBox, TixSubWidget):
1691    def __init__(self, master, name, destroy_physically=1):
1692        TixSubWidget.__init__(self, master, name, destroy_physically)
1693        self.subwidget_list['dirlist'] = _dummyDirList(self, 'dirlist')
1694        self.subwidget_list['dircbx'] = _dummyFileComboBox(self, 'dircbx')
1695
1696class _dummyExFileSelectBox(ExFileSelectBox, TixSubWidget):
1697    def __init__(self, master, name, destroy_physically=1):
1698        TixSubWidget.__init__(self, master, name, destroy_physically)
1699        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
1700        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
1701        self.subwidget_list['hidden'] = _dummyCheckbutton(self, 'hidden')
1702        self.subwidget_list['types'] = _dummyComboBox(self, 'types')
1703        self.subwidget_list['dir'] = _dummyComboBox(self, 'dir')
1704        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
1705        self.subwidget_list['file'] = _dummyComboBox(self, 'file')
1706        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
1707
1708class _dummyFileSelectBox(FileSelectBox, TixSubWidget):
1709    def __init__(self, master, name, destroy_physically=1):
1710        TixSubWidget.__init__(self, master, name, destroy_physically)
1711        self.subwidget_list['dirlist'] = _dummyScrolledListBox(self, 'dirlist')
1712        self.subwidget_list['filelist'] = _dummyScrolledListBox(self, 'filelist')
1713        self.subwidget_list['filter'] = _dummyComboBox(self, 'filter')
1714        self.subwidget_list['selection'] = _dummyComboBox(self, 'selection')
1715
1716class _dummyFileComboBox(ComboBox, TixSubWidget):
1717    def __init__(self, master, name, destroy_physically=1):
1718        TixSubWidget.__init__(self, master, name, destroy_physically)
1719        self.subwidget_list['dircbx'] = _dummyComboBox(self, 'dircbx')
1720
1721class _dummyStdButtonBox(StdButtonBox, TixSubWidget):
1722    def __init__(self, master, name, destroy_physically=1):
1723        TixSubWidget.__init__(self, master, name, destroy_physically)
1724        self.subwidget_list['ok'] = _dummyButton(self, 'ok')
1725        self.subwidget_list['apply'] = _dummyButton(self, 'apply')
1726        self.subwidget_list['cancel'] = _dummyButton(self, 'cancel')
1727        self.subwidget_list['help'] = _dummyButton(self, 'help')
1728
1729class _dummyNoteBookFrame(NoteBookFrame, TixSubWidget):
1730    def __init__(self, master, name, destroy_physically=0):
1731        TixSubWidget.__init__(self, master, name, destroy_physically)
1732
1733class _dummyPanedWindow(PanedWindow, TixSubWidget):
1734    def __init__(self, master, name, destroy_physically=1):
1735        TixSubWidget.__init__(self, master, name, destroy_physically)
1736
1737########################
1738### Utility Routines ###
1739########################
1740
1741#mike Should tixDestroy be exposed as a wrapper? - but not for widgets.
1742
1743def OptionName(widget):
1744    '''Returns the qualified path name for the widget. Normally used to set
1745    default options for subwidgets. See tixwidgets.py'''
1746    return widget.tk.call('tixOptionName', widget._w)
1747
1748# Called with a dictionary argument of the form
1749# {'*.c':'C source files', '*.txt':'Text Files', '*':'All files'}
1750# returns a string which can be used to configure the fsbox file types
1751# in an ExFileSelectBox. i.e.,
1752# '{{*} {* - All files}} {{*.c} {*.c - C source files}} {{*.txt} {*.txt - Text Files}}'
1753def FileTypeList(dict):
1754    s = ''
1755    for type in dict.keys():
1756        s = s + '{{' + type + '} {' + type + ' - ' + dict[type] + '}} '
1757    return s
1758
1759# Still to be done:
1760# tixIconView
1761class CObjView(TixWidget):
1762    """This file implements the Canvas Object View widget. This is a base
1763    class of IconView. It implements automatic placement/adjustment of the
1764    scrollbars according to the canvas objects inside the canvas subwidget.
1765    The scrollbars are adjusted so that the canvas is just large enough
1766    to see all the objects.
1767    """
1768    # FIXME: It should inherit -superclass tixScrolledWidget
1769    pass
1770
1771
1772class Grid(TixWidget, XView, YView):
1773    '''The Tix Grid command creates a new window  and makes it into a
1774    tixGrid widget. Additional options, may be specified on the command
1775    line or in the option database to configure aspects such as its cursor
1776    and relief.
1777
1778    A Grid widget displays its contents in a two dimensional grid of cells.
1779    Each cell may contain one Tix display item, which may be in text,
1780    graphics or other formats. See the DisplayStyle class for more information
1781    about Tix display items. Individual cells, or groups of cells, can be
1782    formatted with a wide range of attributes, such as its color, relief and
1783    border.
1784
1785    Subwidgets - None'''
1786    # valid specific resources as of Tk 8.4
1787    # editdonecmd, editnotifycmd, floatingcols, floatingrows, formatcmd,
1788    # highlightbackground, highlightcolor, leftmargin, itemtype, selectmode,
1789    # selectunit, topmargin,
1790    def __init__(self, master=None, cnf={}, **kw):
1791        static= []
1792        self.cnf= cnf
1793        TixWidget.__init__(self, master, 'tixGrid', static, cnf, kw)
1794
1795    # valid options as of Tk 8.4
1796    # anchor, bdtype, cget, configure, delete, dragsite, dropsite, entrycget,
1797    # edit, entryconfigure, format, geometryinfo, info, index, move, nearest,
1798    # selection, set, size, unset, xview, yview
1799    def anchor_clear(self):
1800        """Removes the selection anchor."""
1801        self.tk.call(self, 'anchor', 'clear')
1802
1803    def anchor_get(self):
1804        "Get the (x,y) coordinate of the current anchor cell"
1805        return self._getints(self.tk.call(self, 'anchor', 'get'))
1806
1807    def anchor_set(self, x, y):
1808        """Set the selection anchor to the cell at (x, y)."""
1809        self.tk.call(self, 'anchor', 'set', x, y)
1810
1811    def delete_row(self, from_, to=None):
1812        """Delete rows between from_ and to inclusive.
1813        If to is not provided,  delete only row at from_"""
1814        if to is None:
1815            self.tk.call(self, 'delete', 'row', from_)
1816        else:
1817            self.tk.call(self, 'delete', 'row', from_, to)
1818
1819    def delete_column(self, from_, to=None):
1820        """Delete columns between from_ and to inclusive.
1821        If to is not provided,  delete only column at from_"""
1822        if to is None:
1823            self.tk.call(self, 'delete', 'column', from_)
1824        else:
1825            self.tk.call(self, 'delete', 'column', from_, to)
1826
1827    def edit_apply(self):
1828        """If any cell is being edited, de-highlight the cell  and  applies
1829        the changes."""
1830        self.tk.call(self, 'edit', 'apply')
1831
1832    def edit_set(self, x, y):
1833        """Highlights  the  cell  at  (x, y) for editing, if the -editnotify
1834        command returns True for this cell."""
1835        self.tk.call(self, 'edit', 'set', x, y)
1836
1837    def entrycget(self, x, y, option):
1838        "Get the option value for cell at (x,y)"
1839        if option and option[0] != '-':
1840            option = '-' + option
1841        return self.tk.call(self, 'entrycget', x, y, option)
1842
1843    def entryconfigure(self, x, y, cnf=None, **kw):
1844        return self._configure(('entryconfigure', x, y), cnf, kw)
1845
1846    # def format
1847    # def index
1848
1849    def info_exists(self, x, y):
1850        "Return True if display item exists at (x,y)"
1851        return self._getboolean(self.tk.call(self, 'info', 'exists', x, y))
1852
1853    def info_bbox(self, x, y):
1854        # This seems to always return '', at least for 'text' displayitems
1855        return self.tk.call(self, 'info', 'bbox', x, y)
1856
1857    def move_column(self, from_, to, offset):
1858        """Moves the range of columns from position FROM through TO by
1859        the distance indicated by OFFSET. For example, move_column(2, 4, 1)
1860        moves the columns 2,3,4 to columns 3,4,5."""
1861        self.tk.call(self, 'move', 'column', from_, to, offset)
1862
1863    def move_row(self, from_, to, offset):
1864        """Moves the range of rows from position FROM through TO by
1865        the distance indicated by OFFSET.
1866        For example, move_row(2, 4, 1) moves the rows 2,3,4 to rows 3,4,5."""
1867        self.tk.call(self, 'move', 'row', from_, to, offset)
1868
1869    def nearest(self, x, y):
1870        "Return coordinate of cell nearest pixel coordinate (x,y)"
1871        return self._getints(self.tk.call(self, 'nearest', x, y))
1872
1873    # def selection adjust
1874    # def selection clear
1875    # def selection includes
1876    # def selection set
1877    # def selection toggle
1878
1879    def set(self, x, y, itemtype=None, **kw):
1880        args= self._options(self.cnf, kw)
1881        if itemtype is not None:
1882            args= ('-itemtype', itemtype) + args
1883        self.tk.call(self, 'set', x, y, *args)
1884
1885    def size_column(self, index, **kw):
1886        """Queries or sets the size of the column given by
1887        INDEX.  INDEX may be any non-negative
1888        integer that gives the position of a given column.
1889        INDEX can also be the string "default"; in this case, this command
1890        queries or sets the default size of all columns.
1891        When no option-value pair is given, this command returns a tuple
1892        containing the current size setting of the given column.  When
1893        option-value pairs are given, the corresponding options of the
1894        size setting of the given column are changed. Options may be one
1895        of the following:
1896              pad0 pixels
1897                     Specifies the paddings to the left of a column.
1898              pad1 pixels
1899                     Specifies the paddings to the right of a column.
1900              size val
1901                     Specifies the width of a column.  Val may be:
1902                     "auto" -- the width of the column is set to the
1903                     width of the widest cell in the column;
1904                     a valid Tk screen distance unit;
1905                     or a real number following by the word chars
1906                     (e.g. 3.4chars) that sets the width of the column to the
1907                     given number of characters."""
1908        return self.tk.splitlist(self.tk.call(self._w, 'size', 'column', index,
1909                             *self._options({}, kw)))
1910
1911    def size_row(self, index, **kw):
1912        """Queries or sets the size of the row given by
1913        INDEX. INDEX may be any non-negative
1914        integer that gives the position of a given row .
1915        INDEX can also be the string "default"; in this case, this command
1916        queries or sets the default size of all rows.
1917        When no option-value pair is given, this command returns a list con-
1918        taining the current size setting of the given row . When option-value
1919        pairs are given, the corresponding options of the size setting of the
1920        given row are changed. Options may be one of the following:
1921              pad0 pixels
1922                     Specifies the paddings to the top of a row.
1923              pad1 pixels
1924                     Specifies the paddings to the bottom of a row.
1925              size val
1926                     Specifies the height of a row.  Val may be:
1927                     "auto" -- the height of the row is set to the
1928                     height of the highest cell in the row;
1929                     a valid Tk screen distance unit;
1930                     or a real number following by the word chars
1931                     (e.g. 3.4chars) that sets the height of the row to the
1932                     given number of characters."""
1933        return self.tk.splitlist(self.tk.call(
1934                    self, 'size', 'row', index, *self._options({}, kw)))
1935
1936    def unset(self, x, y):
1937        """Clears the cell at (x, y) by removing its display item."""
1938        self.tk.call(self._w, 'unset', x, y)
1939
1940
1941class ScrolledGrid(Grid):
1942    '''Scrolled Grid widgets'''
1943
1944    # FIXME: It should inherit -superclass tixScrolledWidget
1945    def __init__(self, master=None, cnf={}, **kw):
1946        static= []
1947        self.cnf= cnf
1948        TixWidget.__init__(self, master, 'tixScrolledGrid', static, cnf, kw)
1949