
    Ng                         d Z ddlZddlmZmZmZmZmZ  G d de          Z G d d          Z	d Z
ed	k    r e
             dS dS )
zC
Tkinter widgets for displaying multi-column listboxes and tables.
    N)FrameLabelListbox	ScrollbarTkc            	          e Zd ZdZ eddd          Z eddddd	
          Z eddddddd          Zdi fdZd Z	d Z
d Zed             Zed             Zed             Zd Zd Zd Zd9dZi fdZd Zi fdZi fdZd:dZd  Zd:d!Zd" Zd# Zd$ Zd;d%Zd;d&Zd;d'Z d( Z!d) Z"d* Z#d+ Z$d, Z%d- Z&d. Z'd/ Z(d0 Z)d1 Z*d2 Z+d3 Z,d4 Z-d5 Z.d6 Z/d7 Z0d8 Z1eZ2eZ3eZ4e,Z5e-Z6e"Z7e.Z8dS )<MultiListboxa  
    A multi-column listbox, where the current selection applies to an
    entire row.  Based on the MultiListbox Tkinter widget
    recipe from the Python Cookbook (https://code.activestate.com/recipes/52266/)

    For the most part, ``MultiListbox`` methods delegate to its
    contained listboxes.  For any methods that do not have docstrings,
    see ``Tkinter.Listbox`` for a description of what that method does.
    z#888T   )
background	takefocushighlightthicknessraisedzhelvetica -16 boldz#444white)borderwidthrelieffontr   
foregroundr   Fnone)r   selectborderwidthr   exportselectionselectbackgroundactivestyler   Nc                     t          |t                    rt          t          |                    }d}nd}t	          |          dk    rt          d          t          |           _        g  _        g  _	        |dgt	          |          z  }n/t	          |          t	          |          k    rt          d          | _
        t          j         |fi  j                              dd           t           j                  D ]\  }}                     |||                    |rOt#           fd	|i j        }	 j	                            |	           |	                    |dd
dd           ||	_        t-           fi  j        }
 j                            |
           |
                    |dd
dd           ||
_        |
                    d j                   |
                    d j                   |
                    d fd           |
                    d fd           |
                    d fd           |
                    d fd           |
                    d fd           |
                    dd            |
                    d j                                        d j                                        d fd                                d fd                                d fd                                d  fd!             j        |fi | dS )"a  
        Construct a new multi-column listbox widget.

        :param master: The widget that should contain the new
            multi-column listbox.

        :param columns: Specifies what columns should be included in
            the new multi-column listbox.  If ``columns`` is an integer,
            then it is the number of columns to include.  If it is
            a list, then its length indicates the number of columns
            to include; and each element of the list will be used as
            a label for the corresponding column.

        :param cnf, kw: Configuration parameters for this widget.
            Use ``label_*`` to configure all labels; and ``listbox_*``
            to configure all listboxes.  E.g.:
                >>> root = Tk()  # doctest: +SKIP
                >>> MultiListbox(root, ["Subject", "Sender", "Date"], label_foreground='red').pack()  # doctest: +SKIP
        FTr   zExpected at least one columnNr
   z*Expected one column_weight for each columnweighttextnewscolumnrowstickypadxpady
<Button-1>z<B1-Motion>z
<Button-4>c                 .                         d          S )N_scrolleselfs    K/var/www/html/ai-engine/env/lib/python3.11/site-packages/nltk/draw/table.py<lambda>z'MultiListbox.__init__.<locals>.<lambda>       DLL,<,<     z
<Button-5>c                 .                         d          S )Nr
   r'   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   r.   r/   z<MouseWheel>c                 8                         | j                  S N)r(   deltar)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    dll17.C.C r/   z
<Button-2>c                 D                         | j        | j                  S r2   )	scan_markxyr)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    DNN13,D,D r/   z<B2-Motion>c                 D                         | j        | j                  S r2   )scan_dragtor6   r7   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    T-=-=ac13-G-G r/   z
<B1-Leave>c                     dS )Nbreak )r*   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    G r/   z<Up>c                 0                         d          S )Nr&   r3   selectr)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    DKKbK$9$9 r/   z<Down>c                 0                         d          S )Nr
   r>   r?   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    dkkk&:&: r/   z<Prior>c                 V                                                                    S Nr>   r@   	_pagesizer)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s"    t{{$..:J:J9J{'K'K r/   z<Next>c                 T                                                                   S rC   rD   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    dkk8H8Hk&I&I r/   )
isinstanceintlistrangelen
ValueErrortuple_column_names
_listboxes_labels_column_weightsr   __init__FRAME_CONFIGgrid_rowconfigure	enumerategrid_columnconfigurer   LABEL_CONFIGappendgridcolumn_indexr   LISTBOX_CONFIGbind_select_resize_column	configure)r+   mastercolumnscolumn_weightscnfkwinclude_labelsilabelllbs   `          r,   rR   zMultiListbox.__init__>   s   * gs## 	"5>>**G"NN!Nw<<1;<<< #7^^ !S3w<</NN  CLL00IJJJ- 	tV99t'8999q+++!$"455 	7 	7HAu%%aq0A%BBB  #$@@U@d.?@@##A&&&aQvAAFFF!" 55!455BO""2&&&GG1!FGCCCBO GGL$,///GGM4<000GGL"<"<"<"<===GGL"<"<"<"<===GGN$C$C$C$CDDDGGL"D"D"D"DEEEGGM#G#G#G#GHHH GGL"3"3444GGL$"56666 			, 3444 			&9999:::		(::::;;;		)KKKKLLL		(IIIIJJJ 	s!!b!!!!!r/   c                    |j                             d          rdS d| _        |j         | u rdt          | j                  D ]N\  }}t          |j        |                                |                                z   z
            dk     r|| _        Onf|j        |j                                         dz
  k    r|j         j	        | _        n/|j        dk     r$|j         j	        dk    r|j         j	        dz
  | _        | j        J|j                             d| j
                   |j                             d	|j        z  | j                   d
S dS )z
        Callback used to resize a column of the table.  Return ``True``
        if the column is actually getting resized (if the user clicked
        on the far left or far right 5 pixels of a label); and
        ``False`` otherwies.
        z<ButtonRelease>FN
      r   r
   <Motion><ButtonRelease-%d>T)widgetr\   _resize_column_indexrU   rO   absr6   winfo_xwinfo_widthrZ   _resize_column_motion_cbnum_resize_column_buttonrelease_cb)r+   eventrf   ri   s       r,   r^   zMultiListbox._resize_column   sN    <.// 	5 %)!<4"4?33 2 22uw"**,,1A1A"ABCCbHH01D-2 W0022Q677(-(AD%%Wq[[U\6!;;(-(AA(ED% $0Lj$*GHHHL$uy0$2V   45r/   c                 V   | j         | j                 }|                                |d         z  }|j        |j                                        z   }|                                |                                z   }t          dt          |d         ||z
  |z  z                       |d<   d S )Nwidth   )rO   rp   rs   r6   ro   rr   maxrH   )r+   rw   ri   	charwidthx1x2s         r,   rt   z%MultiListbox._resize_column_motion_cb   s    _T67NN$$r'{2	Wu|++---ZZ\\BNN,,,!SGRI/E!EFFGG7r/   c                 ~    |j                             d|j        z             |j                             d           d S )Nrn   rm   )ro   unbindru   )r+   rw   s     r,   rv   z,MultiListbox._resize_column_buttonrelease_cb   s<    059<===J'''''r/   c                     | j         S )zh
        A tuple containing the names of the columns used by this
        multi-column listbox.
        )rN   r+   s    r,   column_nameszMultiListbox.column_names   s     !!r/   c                 *    t          | j                  S )a  
        A tuple containing the ``Tkinter.Label`` widgets used to
        display the label of each column.  If this multi-column
        listbox was created without labels, then this will be an empty
        tuple.  These widgets will all be augmented with a
        ``column_index`` attribute, which can be used to determine
        which column they correspond to.  This can be convenient,
        e.g., when defining callbacks for bound events.
        )rM   rP   r   s    r,   column_labelszMultiListbox.column_labels   s     T\"""r/   c                 *    t          | j                  S )aY  
        A tuple containing the ``Tkinter.Listbox`` widgets used to
        display individual columns.  These widgets will all be
        augmented with a ``column_index`` attribute, which can be used
        to determine which column they correspond to.  This can be
        convenient, e.g., when defining callbacks for bound events.
        )rM   rO   r   s    r,   	listboxeszMultiListbox.listboxes   s     T_%%%r/   c                     |j                             |j                  }|                     dd           |                     |           |                     |           |                                  d S )Nr   end)ro   nearestr7   selection_clearselection_setactivatefocus)r+   r*   rf   s      r,   r]   zMultiListbox._select   sf    HQS!!Q&&&1a

r/   c                 F    | j         D ]}|                    |d           dS )Nunitr;   rO   yview_scroll)r+   r3   ri   s      r,   r(   zMultiListbox._scroll   s/    / 	+ 	+BOOE6****wr/   c                     t          |                     d                    t          |                     d                    z
  S )z2:return: The number of rows that makes up one pagez
@0,1000000z@0,0)rH   indexr   s    r,   rE   zMultiListbox._pagesize   s5    4::l++,,s4::f3E3E/F/FFFr/   c                    ||t          d          |Ut          |                                           dk    rd|z   }n*t          |                                 d                   |z   }|                     dd           |at          t          |d          |                                 dz
            }|                     |           |r| 	                    |           dS dS dS )a  
        Set the selected row.  If ``index`` is specified, then select
        row ``index``.  Otherwise, if ``delta`` is specified, then move
        the current selection by ``delta`` (negative numbers for up,
        positive numbers for down).  This will not move the selection
        past the top or the bottom of the list.

        :param see: If true, then call ``self.see()`` with the newly
            selected index, to ensure that it is visible.
        Nz$specify index or delta, but not bothr   r&   r   r
   )
rL   rK   curselectionrH   r   minr{   sizer   seer+   r   r3   r   s       r,   r@   zMultiListbox.select  s     E$5CDDD 4$$&&''1,,U
D--//233e; 	Q&&& E1tyy{{Q77Eu%%%      r/   c                 r   t          t          |                                          t          |                                          z             }t          |                                          D ]\  }}|                    d          s|                    d          r*| j        D ]!}|                    |dd         |i           "Y|                    d          s|                    d          r*| j        D ]!}|                    |dd         |i           "t          j        | ||i           dS )a  
        Configure this widget.  Use ``label_*`` to configure all
        labels; and ``listbox_*`` to configure all listboxes.  E.g.:

                >>> master = Tk()  # doctest: +SKIP
                >>> mlb = MultiListbox(master, 5)  # doctest: +SKIP
                >>> mlb.configure(label_foreground='red')  # doctest: +SKIP
                >>> mlb.configure(listbox_foreground='red')  # doctest: +SKIP
        label_zlabel-   Nlistbox_zlistbox-   )dictrI   items
startswithrP   r_   rO   r   )r+   rc   rd   keyvalrg   listboxs          r,   r_   zMultiListbox.configure*  s<    4		$$tBHHJJ'7'7788SYY[[)) 	2 	2HC~~h'' 23>>(+C+C 2!\ 4 4EOOSWcN33334
++ 2s~~j/I/I 2# 6 6G%%s122wn55556 sCj1111	2 	2r/   c                 4    |                      ||i           dS )z|
        Configure this widget.  This is equivalent to
        ``self.configure({key,val``)}.  See ``configure()``.
        N)r_   )r+   r   r   s      r,   __setitem__zMultiListbox.__setitem__?  s     
 	Sz"""""r/   c                 8    | j         D ]} |j        ||fi | dS )z
        Configure all table cells in the given row.  Valid keyword
        arguments are: ``background``, ``bg``, ``foreground``, ``fg``,
        ``selectbackground``, ``selectforeground``.
        NrO   itemconfigure)r+   	row_indexrc   rd   ri   s        r,   rowconfigurezMultiListbox.rowconfigureF  s?     / 	3 	3BBY22r2222	3 	3r/   c                    | j         |         }t          t          |                                          t          |                                          z             }t          |                                          D ]]\  }}|dv r=t	          |                                          D ]}|                    |||i           F|                    ||i           ^dS )z
        Configure all table cells in the given column.  Valid keyword
        arguments are: ``background``, ``bg``, ``foreground``, ``fg``,
        ``selectbackground``, ``selectforeground``.
        )r   bgr   fgr   selectforegroundN)rO   r   rI   r   rJ   r   r   r_   )r+   	col_indexrc   rd   ri   r   r   rf   s           r,   columnconfigurezMultiListbox.columnconfigureO  s     _Y'4		$$tBHHJJ'7'7788SYY[[)) 	) 	)HC    rwwyy)) 4 4A$$Qc
33334 c3Z((((	) 	)r/   c                 :    | j         |         } |j        ||fi |S )z
        Configure the table cell at the given row and column.  Valid
        keyword arguments are: ``background``, ``bg``, ``foreground``,
        ``fg``, ``selectbackground``, ``selectforeground``.
        r   )r+   r   r   rc   rd   ri   s         r,   r   zMultiListbox.itemconfiguref  s-     _Y'r	355"555r/   c                     |D ]6}t          |          t          | j                  k    rt          d          7t          | j        t          t          |                     D ]\  }} |j        |g|R   dS )a0  
        Insert the given row or rows into the table, at the given
        index.  Each row value should be a tuple of cell values, one
        for each column in the row.  Index may be an integer or any of
        the special strings (such as ``'end'``) accepted by
        ``Tkinter.Listbox``.
        zDrows should be tuples whose length is equal to the number of columnsN)rK   rN   rL   ziprO   rI   insert)r+   r   rowseltri   eltss         r,   r   zMultiListbox.inserts  s      	 	C3xx3t12222 8   3
 DOT#t*-=-=>> 	$ 	$HBBIe#d#####	$ 	$r/   c                 v    fd| j         D             }rd t          | D             S t          |          S )a  
        Return the value(s) of the specified row(s).  If ``last`` is
        not specified, then return a single row value; otherwise,
        return a list of row values.  Each row value is a tuple of
        cell values, one for each column in the row.
        c                 <    g | ]}|                               S r<   )get).0ri   firstlasts     r,   
<listcomp>z$MultiListbox.get.<locals>.<listcomp>  s'    @@@""&&%%@@@r/   c                 ,    g | ]}t          |          S r<   )rM   r   r    s     r,   r   z$MultiListbox.get.<locals>.<listcomp>  s    7773E#JJ777r/   )rO   r   rM   )r+   r   r   valuess    `` r,   r   zMultiListbox.get  sQ     A@@@@@@@ 	!77#v,7777== r/   c                 8   |                      d|          \  }}}}| j        |                             |          \  }}}}	t          |          t          |          z   t          |          t          |          z   t          |          t          |	          fS )z
        Return the bounding box for the given table cell, relative to
        this widget's top-left corner.  The bounding box is a tuple
        of integers ``(left, top, width, height)``.
        r   )r    r   )	grid_bboxrO   bboxrH   )
r+   r    coldxdy_r6   r7   whs
             r,   r   zMultiListbox.bbox  s     ~~!C~88B1_S)..s33
1a1vvBQ#b''!13q663q66AAr/   c                     | j         r| j         |                                          | j        |                                          |                     |d           dS )a1  
        Hide the given column.  The column's state is still
        maintained: its values will still be returned by ``get()``, and
        you must supply its values when calling ``insert()``.  It is
        safe to call this on a column that is already hidden.

        :see: ``show_column()``
        r   r   N)rP   grid_forgetr   rV   )r+   r   s     r,   hide_columnzMultiListbox.hide_column  s_     < 	2L#//111y!--///!!)A!66666r/   c                     | j         |         }| j        r%| j        |                             |dddd           | j        |                             |dddd           |                     ||           dS )z
        Display a column that has been hidden using ``hide_column()``.
        It is safe to call this on a column that is not hidden.
        r   r   r   r
   r   N)rQ   rP   rY   rO   rV   )r+   r   r   s      r,   show_columnzMultiListbox.show_column  s    
 %i0< 	L#(( aQQ )    		"''!F 	( 	
 	
 	
 	!!)F!;;;;;r/   c                 2    fd| j         D             S )aK  
        Add a binding to each ``Tkinter.Label`` widget in this
        mult-column listbox that will call ``func`` in response to the
        event sequence.

        :return: A list of the identifiers of replaced binding
            functions (if any), allowing for their deletion (to
            prevent a memory leak).
        c                 >    g | ]}|                               S r<   )r\   )r   rg   addfuncsequences     r,   r   z/MultiListbox.bind_to_labels.<locals>.<listcomp>  s)    PPPE

8T3//PPPr/   )r   r+   r   r   r   s    ```r,   bind_to_labelszMultiListbox.bind_to_labels  s+     QPPPPPT=OPPPPr/   c                 H    | j         D ]}|                    |||           dS )aM  
        Add a binding to each ``Tkinter.Listbox`` widget in this
        mult-column listbox that will call ``func`` in response to the
        event sequence.

        :return: A list of the identifiers of replaced binding
            functions (if any), allowing for their deletion (to
            prevent a memory leak).
        N)r   r\   )r+   r   r   r   r   s        r,   bind_to_listboxeszMultiListbox.bind_to_listboxes  s8     ~ 	. 	.GLL4----	. 	.r/   c                 `    |                      |||          |                     |||          z   S )ac  
        Add a binding to each ``Tkinter.Label`` and ``Tkinter.Listbox``
        widget in this mult-column listbox that will call ``func`` in
        response to the event sequence.

        :return: A list of the identifiers of replaced binding
            functions (if any), allowing for their deletion (to
            prevent a memory leak).
        )r   r   r   s       r,   bind_to_columnszMultiListbox.bind_to_columns  s<     ""8T377$:P:PdC;
 ;
 
 	
r/   c                 2     | j         d         j        |i |S Nr   )rO   r   r+   argskwargss      r,   r   zMultiListbox.curselection  s!    .tq!.????r/   c                 2     | j         d         j        |i |S r   )rO   selection_includesr   s      r,   r   zMultiListbox.selection_includes  s!    4tq!4dEfEEEr/   c                 2     | j         d         j        |i |S r   )rO   itemcgetr   s      r,   r   zMultiListbox.itemcget  s!    *tq!*D;F;;;r/   c                 2     | j         d         j        |i |S r   )rO   r   r   s      r,   r   zMultiListbox.size  s!    &tq!&7777r/   c                 2     | j         d         j        |i |S r   )rO   r   r   s      r,   r   zMultiListbox.index  s!    'tq!'8888r/   c                 2     | j         d         j        |i |S r   )rO   r   r   s      r,   r   zMultiListbox.nearest  s!    )tq!)4:6:::r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   r   r+   r   r   ri   s       r,   r   zMultiListbox.activate  s7    / 	) 	)BBK(((((	) 	)r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   deleter   s       r,   r   zMultiListbox.delete  s7    / 	' 	'BBIt&v&&&&	' 	'r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   r5   r   s       r,   r5   zMultiListbox.scan_mark  s7    / 	* 	*BBL$)&))))	* 	*r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   r9   r   s       r,   r9   zMultiListbox.scan_dragto  s7    / 	, 	,BBND+F++++	, 	,r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   r   r   s       r,   r   zMultiListbox.see  s7    / 	$ 	$BBFD#F####	$ 	$r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   selection_anchorr   s       r,   r   zMultiListbox.selection_anchor  s8    / 	1 	1BB00000	1 	1r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   r   r   s       r,   r   zMultiListbox.selection_clear  s8    / 	0 	0BB/////	0 	0r/   c                 4    | j         D ]} |j        |i | d S r2   )rO   r   r   s       r,   r   zMultiListbox.selection_set  s8    / 	. 	.BBd-f----	. 	.r/   c                 4    | j         D ]} |j        |i |}|S r2   )rO   yview)r+   r   r   ri   vs        r,   r   zMultiListbox.yview  s0    / 	* 	*B$)&))AAr/   c                 4    | j         D ]} |j        |i | d S r2   )rO   yview_movetor   s       r,   r   zMultiListbox.yview_moveto$  7    / 	- 	-BBOT,V,,,,	- 	-r/   c                 4    | j         D ]} |j        |i | d S r2   r   r   s       r,   r   zMultiListbox.yview_scroll(  r   r/   NNTr2   NNN)9__name__
__module____qualname____doc__r   rS   rW   r[   rR   r^   rt   rv   propertyr   r   r   r]   r(   rE   r@   r_   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r5   r9   r   r   r   r   r   r   r   
itemconfig	rowconfigcolumnconfigselect_anchorselect_clearselect_includes
select_setr<   r/   r,   r	   r	      s         46TaPPPL 4!  L T  N 8< X" X" X" X"|  BH H H( ( ( " " X" 
# 
# X
# & & X&    
G G G       H  2 2 2 2*# # # +- 3 3 3 3 .0 ) ) ) ).6 6 6 6$ $ $"! ! ! !B B B7 7 7< < <&
Q 
Q 
Q 
Q. . . .
 
 
 
&@ @ @F F F< < <8 8 89 9 9; ; ;) ) )' ' '* * *, , ,$ $ $1 1 10 0 0. . .  
- - -- - - JI"L$M"L(OJJJr/   r	   c                   $   e Zd ZdZdddddi fdZd Zd Zd Zd'dZi fd	Z	i fd
Z
d(dZd'dZd'dZd'dZe	Ze
ZeZd Zd Zd Zd Zd Zd Zd Zd Zd Zed             Zd Zd Zd Zd Z d)dZ!d*dZ"d  Z#d+d!Z$d" Z%d,d$Z&d-d%Z'd#Z(	 d& Z)dS ).Tablea  
    A display widget for a table of values, based on a ``MultiListbox``
    widget.  For many purposes, ``Table`` can be treated as a
    list-of-lists.  E.g., table[i] is a list of the values for row i;
    and table.append(row) adds a new row with the given list of
    values.  Individual cells can be accessed using table[i,j], which
    refers to the j-th column of the i-th row.  This can be used to
    both read and write values from the table.  E.g.:

        >>> table[i,j] = 'hello'  # doctest: +SKIP

    The column (j) can be given either as an index number, or as a
    column name.  E.g., the following prints the value in the 3rd row
    for the 'First Name' column:

        >>> print(table[3, 'First Name'])  # doctest: +SKIP
        John

    You can configure the colors for individual rows, columns, or
    cells using ``rowconfig()``, ``columnconfig()``, and ``itemconfig()``.
    The color configuration for each row will be preserved if the
    table is modified; however, when new rows are added, any color
    configurations that have been made for *columns* will not be
    applied to the new row.

    Note: Although ``Table`` acts like a widget in some ways (e.g., it
    defines ``grid()``, ``pack()``, and ``bind()``), it is not itself a
    widget; it just contains one.  This is because widgets need to
    define ``__getitem__()``, ``__setitem__()``, and ``__nonzero__()`` in
    a way that's incompatible with the fact that ``Table`` behaves as a
    list-of-lists.

    :ivar _mlb: The multi-column listbox used to display this table's data.
    :ivar _rows: A list-of-lists used to hold the cell values of this
        table.  Each element of _rows is a row value, i.e., a list of
        cell values, one for each column in the row.
    NTc	                    t          |          | _        || _        t          |          | _        d t          |          D             | _        |g | _        nd |D             | _        | j        D ]}
|                     |
           t          | j        |||fi |	| _
        | j
                            ddd           |rYt          | j        d| j
        j        	          }|j        | j
        j        d
         d<   |                    dd           || _        d| _        |r:t          | j
        j                  D ] \  }}|                    d| j                   !|                                  dS )a  
        Construct a new Table widget.

        :type master: Tkinter.Widget
        :param master: The widget that should contain the new table.
        :type column_names: list(str)
        :param column_names: A list of names for the columns; these
            names will be used to create labels for each column;
            and can be used as an index when reading or writing
            cell values from the table.
        :type rows: list(list)
        :param rows: A list of row values used to initialize the table.
            Each row value should be a tuple of cell values, one for
            each column in the row.
        :type scrollbar: bool
        :param scrollbar: If true, then create a scrollbar for the
            new table widget.
        :type click_to_sort: bool
        :param click_to_sort: If true, then create bindings that will
            sort the table's rows by a given column's values if the
            user clicks on that colum's label.
        :type reprfunc: function
        :param reprfunc: If specified, then use this function to
            convert each table cell value to a string suitable for
            display.  ``reprfunc`` has the following signature:
            reprfunc(row_index, col_index, cell_value) -> str
            (Note that the column is specified by index, not by name.)
        :param cnf, kw: Configuration parameters for this widget's
            contained ``MultiListbox``.  See ``MultiListbox.__init__()``
            for details.
        c                     i | ]\  }}||	S r<   r<   )r   rf   cs      r,   
<dictcomp>z"Table.__init__.<locals>.<dictcomp>  s    %Q%Q%Qv1a%Q%Q%Qr/   Nc                 &    g | ]}d  |D             S )c                     g | ]}|S r<   r<   )r   r   s     r,   r   z-Table.__init__.<locals>.<listcomp>.<listcomp>  s    ***1***r/   r<   r   s     r,   r   z"Table.__init__.<locals>.<listcomp>  s'    ;;;s**c***;;;r/   leftTboth)sideexpandfillvertical)orientcommandr   yscrollcommandrightr7   )r  r  r$   )rK   _num_columns	_reprfuncr   _framerU   _column_name_to_index_rows	_checkrowr	   _mlbpackr   r   setr   
_scrollbar_sortkeyr   r\   _sort_fill_table)r+   r`   r   r   rb   	scrollbarclick_to_sortreprfuncrc   rd   r    sbrf   rh   s                 r,   rR   zTable.__init__l  s   V  --!Fmm%Q%Q<9P9P%Q%Q%Q" <DJJ;;d;;;DJ: 	  	 CNN3 !lNCVVSUVV		F4f===  	!4;z49?SSSB79vDI"#34 GGsG+++ DO  	1!$)"9:: 1 11|TZ0000 	r/   c                 *     | j         j        |i | dS )zrPosition this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.pack()`` for more info.N)r  r"  r   s      r,   r"  z
Table.pack  $     	$)&)))))r/   c                 *     | j         j        |i | dS )zrPosition this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.grid()`` for more info.N)r  rY   r   s      r,   rY   z
Table.grid  r-  r/   c                 8    | j                                          dS )z-Direct (keyboard) input foxus to this widget.N)r!  r   r   s    r,   r   zTable.focus  s    	r/   c                 >    | j                             |||           dS )zkAdd a binding to this table's main frame that will call
        ``func`` in response to the event sequence.N)r!  r\   r   s       r,   r\   z
Table.bind  s"     		xs+++++r/   c                 .     | j         j        ||fi | dS )z%:see: ``MultiListbox.rowconfigure()``N)r!  r   )r+   r   rc   rd   s       r,   r   zTable.rowconfigure  s'    	y#4444444r/   c                 X    |                      |          } | j        j        ||fi | dS )z(:see: ``MultiListbox.columnconfigure()``N)rZ   r!  r   )r+   r   rc   rd   s       r,   r   zTable.columnconfigure  s:    %%i00	!	!)S77B77777r/   c                 V    |                      |          } | j        j        |||fi |S )z&:see: ``MultiListbox.itemconfigure()``)rZ   r!  r   )r+   r   r   rc   rd   s        r,   r   zTable.itemconfigure  s6    %%i00	&ty&y)SGGBGGGr/   c                 :    | j                             |||          S )z':see: ``MultiListbox.bind_to_labels()``)r!  r   r   s       r,   r   zTable.bind_to_labels  s    y''$<<<r/   c                 :    | j                             |||          S )z*:see: ``MultiListbox.bind_to_listboxes()``)r!  r   r   s       r,   r   zTable.bind_to_listboxes  s    y**8T3???r/   c                 :    | j                             |||          S )z(:see: ``MultiListbox.bind_to_columns()``)r!  r   r   s       r,   r   zTable.bind_to_columns  s    y((4===r/   c                                            |            j                            |            j         fdt	          |          D             } j                            |            j        r                                  dS dS )aT  
        Insert a new row into the table, so that its row index will be
        ``row_index``.  If the table contains any rows whose row index
        is greater than or equal to ``row_index``, then they will be
        shifted down.

        :param rowvalue: A tuple of cell values, one for each column
            in the new row.
        Nc                 D    g | ]\  }}                     ||          S r<   r  )r   jr   r   r+   s      r,   r   z Table.insert.<locals>.<listcomp>  s:       4:Qy!Q//  r/   )r   r  r   r  rU   r!  _DEBUG_check_table_vs_mlb)r+   r   rowvalues   `` r,   r   zTable.insert  s     	x   
)X...>%    >G>Q>Q  H 		H---; 	'$$&&&&&	' 	'r/   c                 t    |D ]}|                      |           | j        r|                                  dS dS )z
        Add new rows at the end of the table.

        :param rowvalues: A list of row values used to initialize the
            table.  Each row value should be a tuple of cell values,
            one for each column in the row.
        N)rX   r;  r<  )r+   	rowvaluesr=  s      r,   extendzTable.extend	  sT     " 	" 	"HKK!!!!; 	'$$&&&&&	' 	'r/   c                     |                      t          | j                  |           | j        r|                                  dS dS )z
        Add a new row to the end of the table.

        :param rowvalue: A tuple of cell values, one for each column
            in the new row.
        N)r   rK   r  r;  r<  r+   r=  s     r,   rX   zTable.append  sL     	C
OOX...; 	'$$&&&&&	' 	'r/   c                     g | _         | j                            dd           | j        r|                                  dS dS )z0
        Delete all rows in this table.
        r   r   N)r  r!  r   r;  r<  r   s    r,   clearzTable.clear!  sO     
	E"""; 	'$$&&&&&	' 	'r/   c                 2   t          |t                    rt          d          t          |t                    rEt	          |          dk    r2| j        |d                  |                     |d                            S t          | j        |                   S )a  
        Return the value of a row or a cell in this table.  If
        ``index`` is an integer, then the row value for the ``index``th
        row.  This row value consists of a tuple of cell values, one
        for each column in the row.  If ``index`` is a tuple of two
        integers, ``(i,j)``, then return the value of the cell in the
        ``i``th row and the ``j``th column.
        Slicing not supported   r   r
   )rG   slicerL   rM   rK   r  rZ   )r+   r   s     r,   __getitem__zTable.__getitem__*  s     eU## 	,4555u%% 	,#e**//:eAh'(9(9%((C(CDDE*+++r/   c                     t          t                    rt          d          t          t                    rt	                    dk    r̉d                              d                   }}                     |g          }| j        |         |<    j                             |||          } j	        j
        |                             ||            j	        j
        |                             |dz                                   |           dS                      g          }                     |           t          |           j        <    j         fdt!          |          D             } j	                            |            j	                            dz                                   |           dS )a  
        Replace the value of a row or a cell in this table with
        ``val``.

        If ``index`` is an integer, then ``val`` should be a row value
        (i.e., a tuple of cell values, one for each column).  In this
        case, the values of the ``index``th row of the table will be
        replaced with the values in ``val``.

        If ``index`` is a tuple of integers, ``(i,j)``, then replace the
        value of the cell in the ``i``th row and ``j``th column with
        ``val``.
        rF  rG  r   r
   Nc                 D    g | ]\  }}                     ||          S r<   r9  )r   r:  r   r   r+   s      r,   r   z%Table.__setitem__.<locals>.<listcomp>\  s-    PPPv1t~~eQ22PPPr/   )rG   rH  rL   rM   rK   rZ   _save_config_infor  r  r!  r   r   r   _restore_config_infor   rI   rU   )r+   r   r   rf   r:  config_cookies   ``    r,   r   zTable.__setitem__:  s    eU## 	54555 u%% 	5#e**//8T..uQx88qA 22A377M"DJqM!~)nnQ3//I"))!S111I"))!a%000%%m44444 !22E7;;MNN3 $S		DJu~)PPPPP3PPPIUC(((IUQY'''%%m44444r/   c                 :   t          |t                    rt          d          t          |t                    r"t	          |          dk    rt          d          | j        |= | j                            |           | j        r| 	                                 dS dS )zA
        Delete the ``row_index``th row from this table.
        rF  rG  zCannot delete a single cell!N)
rG   rH  rL   rM   rK   r  r!  r   r;  r<  )r+   r   s     r,   __delitem__zTable.__delitem__a  s     i'' 	64555i'' 	=C	NNa,?,?;<<<Jy!	###; 	'$$&&&&&	' 	'r/   c                 *    t          | j                  S )z<
        :return: the number of rows in this table.
        )rK   r  r   s    r,   __len__zTable.__len__n  s     4:r/   c                     t          |          | j        k    r't          d|t          |          | j        fz            dS )z
        Helper function: check that a given row value has the correct
        number of elements; and if not, raise an exception.
        z"Row %r has %d columns; expected %dN)rK   r  rL   rB  s     r,   r   zTable._checkrowt  sM    
 x==D---4S]]D,=>?   .-r/   c                     | j         j        S )z1A list of the names of the columns in this table.)r!  r   r   s    r,   r   zTable.column_names  s     y%%r/   c                 t    t          |t                    rd|cxk    r| j        k     rn n|S | j        |         S )z
        If ``i`` is a valid column index integer, then return it as is.
        Otherwise, check if ``i`` is used as the name for any column;
        if so, return that column's index.  Otherwise, raise a
        ``KeyError`` exception.
        r   )rG   rH   r  r  )r+   rf   s     r,   rZ   zTable.column_index  sO     a 	1!q"<"<"<"<4+<"<"<"<"<"<H -a00r/   c                 `    | j                             |                     |                     dS )z$:see: ``MultiListbox.hide_column()``N)r!  r   rZ   r+   rZ   s     r,   r   zTable.hide_column  ,    	d//==>>>>>r/   c                 `    | j                             |                     |                     dS )z$:see: ``MultiListbox.show_column()``N)r!  r   rZ   rW  s     r,   r   zTable.show_column  rX  r/   c                 f    | j                                         }|rt          |d                   S dS )z
        Return the index of the currently selected row, or None if
        no row is selected.  To get the row value itself, use
        ``table[table.selected_row()]``.
        r   N)r!  r   rH   )r+   sels     r,   selected_rowzTable.selected_row  s4     i$$&& 	s1v;;4r/   c                 >    | j                             |||           dS )z:see: ``MultiListbox.select()``N)r!  r@   r   s       r,   r@   zTable.select  s"    	s+++++r/   togglec                    |dvrt          d          |                     |          }|                     d          }|dk    r%|| j        k    r| j                                         n9| j                            t          j        |          |dk               || _        | 	                                 | 
                    |dd           | j        r|                                  d	S d	S )
a  
        Sort the rows in this table, using the specified column's
        values as a sort key.

        :param column_index: Specifies which column to sort, using
            either a column index (int) or a column's label name
            (str).

        :param order: Specifies whether to sort the values in
            ascending or descending order:

              - ``'ascending'``: Sort from least to greatest.
              - ``'descending'``: Sort from greatest to least.
              - ``'toggle'``: If the most recent call to ``sort_by()``
                sorted the table by the same column (``column_index``),
                then reverse the rows; otherwise sort in ascending
                order.
        )	ascending
descendingr^  zBsort_by(): order should be "ascending", "descending", or "toggle".T)index_by_idr^  ra  )r   reverse)rb  r   N)rL   rZ   rL  r%  r  rc  sortoperator
itemgetterr'  rM  r;  r<  )r+   rZ   orderrN  s       r,   sort_byzTable.sort_by  s   & ===W   ((66..4.@@ H!>!>J    JOO'55@U     )DM 	!!-Tt!LLL; 	'$$&&&&&	' 	'r/   c                     |j         j        }| j                            |          rdS |                     |           dS )zLEvent handler for clicking on a column label -- sort by
        that column.continue)ro   rZ   r!  r^   rh  )r+   rw   rZ   s      r,   r&  zTable._sort  sF     |0 9##E** 	: LL&&&:r/   c                       j                             dd           t           j                  D ]C\  } j         fdt          |          D             } j                             d|           DdS )a  
        Re-draw the table from scratch, by clearing out the table's
        multi-column listbox; and then filling it in with values from
        ``self._rows``.  Note that any cell-, row-, or column-specific
        color configuration that has been done will be lost.  The
        selection will also be lost -- i.e., no row will be selected
        after this call completes.
        r   r   Nc                 D    g | ]\  }}                     ||          S r<   r9  )r   r:  r   rf   r+   s      r,   r   z%Table._fill_table.<locals>.<listcomp>  s-    LLL6Aqt~~aA..LLLr/   )r!  r   rU   r  r  r   )r+   save_configr    rf   s   `  @r,   r'  zTable._fill_table  s     		E"""
++ 	) 	)FAs~)LLLLLYs^^LLLIUC((((	) 	)r/   c                 (      fddD             S )Nc                 V    i | ]%}|j                             |          d          &S )r&   )r!  r  )r   kr  rr+   s     r,   r  z)Table._get_itemconfig.<locals>.<dictcomp>  sD     
 
 
 ty##Aq!,,R0
 
 
r/   )r   r   r   r   r<   )r+   rq  r  s   ```r,   _get_itemconfigzTable._get_itemconfig   s<    
 
 
 
 
 

 
 
 	
r/   Fc                     |.t          t          t           j                                      }                                 }|r|t           j        |                   }|r fd|D             }n fd|D             }||fS )a*  
        Return a 'cookie' containing information about which row is
        selected, and what color configurations have been applied.
        this information can the be re-applied to the table (after
        making modifications) using ``_restore_config_info()``.  Color
        configuration information will be saved for any rows in
        ``row_indices``, or in the entire table, if
        ``row_indices=None``.  If ``index_by_id=True``, the the cookie
        will associate rows with their configuration information based
        on the rows' python id.  This is useful when performing
        operations that re-arrange the rows (e.g. ``sort``).  If
        ``index_by_id=False``, then it is assumed that all rows will be
        in the same order when ``_restore_config_info()`` is called.
        Nc                     i | ]<t          j                           fd t          j                  D             =S )c                 <    g | ]}                     |          S r<   rr  r   r  rq  r+   s     r,   r   z6Table._save_config_info.<locals>.<dictcomp>.<listcomp>&  s6     $ $ $34D((A..$ $ $r/   )idr  rJ   r  r   rq  r+   s    @r,   r  z+Table._save_config_info.<locals>.<dictcomp>%  sp         4:a=!! $ $ $ $ $8=d>O8P8P$ $ $  r/   c                 V    i | ]$fd t          j                  D             %S )c                 <    g | ]}                     |          S r<   rv  rw  s     r,   r   z6Table._save_config_info.<locals>.<dictcomp>.<listcomp>-  s)    QQQ1D((A..QQQr/   )rJ   r  ry  s    @r,   r  z+Table._save_config_info.<locals>.<dictcomp>,  sO        QQQQQd>O8P8PQQQ  r/   )rI   rJ   rK   r  r\  rx  )r+   row_indicesrb  	selectionconfigs   `    r,   rL  zTable._save_config_info  s      uS__5566K %%''	 	2904:i011I  	    %	  FF   $  F
 &  r/   c           
      b   |\  }}|| j                             dd           |rt          | j                  D ]\  }}t	          |          |v rLt          | j                  D ]7}| j                             |||t	          |                   |                    8t	          |          |k    r| j                             ||           dS || j                             ||           |D ]A}t          | j                  D ]*}| j                             ||||         |                    +BdS )zy
        Restore selection & color configuration information that was
        saved using ``_save_config_info``.
        Nr   r   )r   )	r!  r   rU   r  rx  rJ   r  r   r@   )	r+   cookierb  r   r}  r~  rq  r    r  s	            r,   rM  zTable._restore_config_info3  sm   
 #	6 I%%a///  	@#DJ// 1 13c77f$$"4#455 J J	//1fRWWoa6HIIIIc77i''I$$QC$0001 1 $	   444 @ @t011 @ @AI++Aq&)A,????@@ @r/   c                    | j         j        D ])}t          |           |                                k    sJ *| D ]}t          |          | j        k    sJ | j        t          | j         j                  k    sJ t          |           D ]^\  }}t          |          D ]I\  }}| j        |                     |||          }| j                             |          |         |k    sJ J_dS )a  
        Verify that the contents of the table's ``_rows`` variable match
        the contents of its multi-listbox (``_mlb``).  This is just
        included for debugging purposes, to make sure that the
        list-modifying operations are working correctly.
        N)	r!  r   rK   r   r  r   rU   r  r   )r+   r   r    rf   r:  cells         r,   r<  zTable._check_table_vs_mlbU  s    9& 	+ 	+Ct99

***** 	1 	1Cs88t000000 C	(>$?$?????oo 	3 	3FAs$S>> 3 34>->>!Q55Dy}}Q''*d222223	3 	3r/   r   r2   r   )r^  )T)NF)FF)*r   r   r   r   rR   r"  rY   r   r\   r   r   r   r   r   r   r  r  r  r   r@  rX   rD  rI  r   rP  rR  r   r  r   rZ   r   r   r\  r@   rh  r&  r'  rr  rL  rM  r;  r<  r<   r/   r,   r
  r
  E  s       $ $T M M M Mh* * *
* * *
  , , , ,
 +- 5 5 5 5 .0 8 8 8 8
H H H H
= = = =@ @ @ @> > > > I"LJ' ' '(' ' '	' 	' 	'' ' ', , , %5 %5 %5N' ' '  	 	 	 & & X&1 1 1? ? ?? ? ?
 
 
, , , ,'' '' '' ''R  &) ) ) )	
 	
 	
&! &! &! &!P@ @ @ @< F#3 3 3 3 3r/   r
  c                  v  
 t                      

                    d
fd           t          
d                                g dd           } |                     dd	           d
dlm}m} t          t          |
                                d d                             D ]\  }}|d
         dk    r|                                }|                    |          D ]}	 |                                d
                                         }n	#  d}Y nxY w	 |                                d
                                         }n	#  d}Y nxY w|                     ||                                ||g           |                     dd           |                     dd           |                     dd           |                     dd           t#          t%          |                     D ].}dD ])}	| ||	f         dk    r|                     ||	dd           */
                                 d S )Nz<Control-q>c                 ,                                     S r2   )destroy)r*   roots    r,   r-   zdemo.<locals>.<lambda>q  s    t||~~ r/   zWord Synset Hypernym Hyponym)r   r
   r
   r
   c                     d|z  S )Nz  %sr<   )rf   r:  ss      r,   r-   zdemo.<locals>.<lambda>w  s
    &1* r/   )rb   r*  Tr  )r  r  r   )brownwordneti  Nz*none*Wordz#afa)r   Synsetz#efeHypernymz#feeHyponymz#ffe)r  r  z#666)r   r   )r   r\   r
  splitr"  nltk.corpusr  r  sortedr#  tagged_wordslowersynsets	hypernyms
definitionrX   r  rJ   rK   r  mainloop)tabler  r  wordpossynset	hyper_defhypo_defr    r   r  s             @r,   demor  o  s   44DIIm5555666&,,..#||,,	  E 
JJdJ(((********C 2 2 4 4TcT :;;<< K K	cq6S==zz||ood++ 		K 		KF%",,..q1<<>>		%$			$!++--a0;;==$#LL$ 1 1 3 3YIJJJJ		K 
v&111	xF333	zf555	yV444SZZ    - 	 	FS&[!X--  FV !   	
 	MMOOOOOs   $,DD,EE__main__)r   re  tkinterr   r   r   r   r   r	   r
  r  r   r<   r/   r,   <module>r     s      8 8 8 8 8 8 8 8 8 8 8 8 8 8b b b b b5 b b bba3 a3 a3 a3 a3 a3 a3 a3T' ' 'T zDFFFFF r/   