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