
    g                     v    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
        yy)
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.Z8y)<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	        |      k7  rt        d      | _
        t        j                   |fi  j                    j                  dd       t         j                        D ]  \  }} j!                  |||          |rPt#         fd	|i j$                  }	 j                  j'                  |	       |	j)                  |dd
dd       ||	_        t-         fi  j.                  }
 j                  j'                  |
       |
j)                  |dd
dd       ||
_        |
j1                  d j2                         |
j1                  d j2                         |
j1                  d fd       |
j1                  d fd       |
j1                  d fd       |
j1                  d fd       |
j1                  d fd       |
j1                  dd        |
j1                  d j4                           j1                  d j4                          j1                  d fd        j1                  d fd        j1                  d fd        j1                  d  fd!         j6                  |fi | y)"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                 &    j                  d      S )N_scrolleselfs    D/var/www/openai/venv/lib/python3.12/site-packages/nltk/draw/table.py<lambda>z'MultiListbox.__init__.<locals>.<lambda>       DLL,<    z
<Button-5>c                 &    j                  d      S )Nr
   r'   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   r.   r/   z<MouseWheel>c                 :    j                  | j                        S N)r(   deltar)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    dll177.Cr/   z
<Button-2>c                 P    j                  | j                  | j                        S r2   )	scan_markxyr)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    DNN133,Dr/   z<B2-Motion>c                 P    j                  | j                  | j                        S r2   )scan_dragtor6   r7   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    T-=-=acc133-Gr/   z
<B1-Leave>c                      y)Nbreak )r*   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    Gr/   z<Up>c                 (    j                  d      S )Nr&   r3   selectr)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    DKKbK$9r/   z<Down>c                 (    j                  d      S )Nr
   r>   r?   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    dkkk&:r/   z<Prior>c                 F    j                  j                                S Nr>   r@   	_pagesizer)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    t{{$..:J9J{'Kr/   z<Next>c                 D    j                  j                               S rC   rD   r)   s    r,   r-   z'MultiListbox.__init__.<locals>.<lambda>   s    dkk8Hk&Ir/   )
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"N!Nw<1;<< #7^ !S3w</N CL0IJJ- 	tV9t'8'89q+!$"4"45HAu%%aq0A%B $@U@d.?.?@##A&aQvAAF!" 5!4!45BOO""2&GG1!FGCBO GGL$,,/GGM4<<0GGL"<=GGL"<=GGN$CDGGL"DEGGM#GH GGL"34GGL$"5"56= 6D 			, 3 34 			&9:		(:;		)KL		(IJ 	s!b!r/   c                 
   |j                   j                  d      ryd| _        |j                   | u r`t        | j                        D ]G  \  }}t        |j                  |j                         |j                         z   z
        dk  sA|| _        I n|j                  |j                   j                         dz
  kD  r|j                   j                  | _        nF|j                  dk  r7|j                   j                  dk7  r|j                   j                  dz
  | _        | j                  Z|j                   j                  d| j                         |j                   j                  d	|j                  z  | j                         y
y)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   s2    <<./ %)!<<4"4??32uww"**,1A"ABCbH01D- 4 WW002Q67(-(A(AD%WWq[U\\66!;(-(A(AA(ED% $$0LLj$*G*GHLL$uyy0$2V2V r/   c                 :   | j                   | j                     }|j                         |d   z  }|j                  |j                  j                         z   }|j                         |j                         z   }t        dt        |d   ||z
  |z  z               |d<   y )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67NN$r'{2	WWu||++--ZZ\BNN,,!SGRI/E!EFG7r/   c                     |j                   j                  d|j                  z         |j                   j                  d       y )Nrn   rm   )ro   unbindru   )r+   rw   s     r,   rv   z,MultiListbox._resize_column_buttonrelease_cb   s0    0599<=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                  |j                        }| j                  dd       | j	                  |       | j                  |       | j                          y )Nr   end)ro   nearestr7   selection_clearselection_setactivatefocus)r+   r*   rf   s      r,   r]   zMultiListbox._select   sM    HHQSS!Q&1a

r/   c                 J    | j                   D ]  }|j                  |d        y)Nunitr;   rO   yview_scroll)r+   r3   ri   s      r,   r(   zMultiListbox._scroll   s!    //BOOE6* "r/   c                 l    t        | j                  d            t        | j                  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   s)    4::l+,s4::f3E/FFFr/   c                 j   ||t        d      |At        | j                               dk(  rd|z   }nt        | j                         d         |z   }| j	                  dd       |Mt        t        |d      | j                         dz
        }| j                  |       |r| j                  |       yyy)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 4$$&'1,U
D--/23e; 	Q& E1tyy{Q7Eu% 	 r/   c                    t        t        |j                               t        |j                               z         }t        |j                               D ]  \  }}|j                  d      s|j                  d      r(| j                  D ]  }|j                  |dd |i        P|j                  d      s|j                  d      r(| j                  D ]  }|j                  |dd |i        t        j
                  | ||i        y)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		$tBHHJ'778SYY[)HC~~h'3>>(+C!\\EOOSWcN3 *
+s~~j/I#G%%s12wn5  / sCj1 *r/   c                 *    | j                  ||i       y)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                 N    | j                   D ]  } |j                  ||fi |  y)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)     //BBY2r2 "r/   c                 p   | j                   |   }t        t        |j                               t        |j                               z         }t        |j                               D ]O  \  }}|dv r3t	        |j                               D ]  }|j                  |||i        =|j                  ||i       Q y)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		$tBHHJ'778SYY[)HC   rwwy)A$$Qc
3 * c3Z( *r/   c                 H    | 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5r/   c                     |D ].  }t        |      t        | j                        k7  s%t        d       t        | j                  t        t        |             D ]  \  }} |j                  |g|   y)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  sn     C3x3t1122 8   DOOT#t*-=>HBBIIe#d# ?r/   c                     | j                   D cg c]  }|j                  ||       }}|rt        | D cg c]  }t        |       c}S t        |      S c c}w c c}w )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.
        )rO   getr   rM   )r+   firstlastri   valuesr    s         r,   r   zMultiListbox.get  sZ     15@""&&%@*-v,7,3E#J,77= 	 A7s
   AAc                     | j                  d|      \  }}}}| j                  |   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  sp     ~~!C~8B1__S)..s3
1a1vBQ#b'!13q63q6AAr/   c                     | j                   r| j                   |   j                          | j                  |   j                          | j                  |d       y)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  sH     <<LL#//1y!--/!!)A!6r/   c                     | j                   |   }| j                  r#| j                  |   j                  |dddd       | j                  |   j                  |dddd       | j	                  ||       y)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<<LL#(( aQQ )  		"''!F 	( 	
 	!!)F!;r/   c                 b    | j                   D cg c]  }|j                  |||       c}S c c}w )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).
        )r   r\   )r+   sequencefuncaddrg   s        r,   bind_to_labelszMultiListbox.bind_to_labels  s2     >B=O=OP=OE

8T3/=OPPPs   ,c                 L    | j                   D ]  }|j                  |||        y)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  s"     ~~GLL4- &r/   c                 P    | j                  |||      | j                  |||      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+   r   r   r   s       r,   bind_to_columnszMultiListbox.bind_to_columns  s4     ""8T37$:P:PdC;
 
 	
r/   c                 @     | j                   d   j                  |i |S Nr   )rO   r   r+   argskwargss      r,   r   zMultiListbox.curselection  s#    .tq!..???r/   c                 @     | j                   d   j                  |i |S r   )rO   selection_includesr   s      r,   r   zMultiListbox.selection_includes  s#    4tq!44dEfEEr/   c                 @     | j                   d   j                  |i |S r   )rO   itemcgetr   s      r,   r   zMultiListbox.itemcget  s#    *tq!**D;F;;r/   c                 @     | j                   d   j                  |i |S r   )rO   r   r   s      r,   r   zMultiListbox.size  s#    &tq!&&777r/   c                 @     | j                   d   j                  |i |S r   )rO   r   r   s      r,   r   zMultiListbox.index  s#    'tq!''888r/   c                 @     | j                   d   j                  |i |S r   )rO   r   r   s      r,   r   zMultiListbox.nearest  s#    )tq!))4:6::r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   r   r+   r   r   ri   s       r,   r   zMultiListbox.activate  s#    //BBKK(( "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   deleter   s       r,   r   zMultiListbox.delete  s#    //BBIIt&v& "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   r5   r   s       r,   r5   zMultiListbox.scan_mark  s#    //BBLL$)&) "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   r9   r   s       r,   r9   zMultiListbox.scan_dragto  s#    //BBNND+F+ "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   r   r   s       r,   r   zMultiListbox.see  s#    //BBFFD#F# "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   selection_anchorr   s       r,   r   zMultiListbox.selection_anchor  s%    //BB00 "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   r   r   s       r,   r   zMultiListbox.selection_clear  s%    //BB// "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   r   r   s       r,   r   zMultiListbox.selection_set  s%    //BBd-f- "r/   c                 L    | j                   D ]  } |j                  |i |} S r2   )rO   yview)r+   r   r   ri   vs        r,   r   zMultiListbox.yview  s*    //B$)&)A "r/   c                 J    | j                   D ]  } |j                  |i |  y r2   )rO   yview_movetor   s       r,   r   zMultiListbox.yview_moveto$  #    //BBOOT,V, "r/   c                 J    | j                   D ]  } |j                  |i |  y 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    6TaPL !L N 8< X"|BH( " " 
# 
# & &
G H  2*# +- 3 .0 ).6$"!B7<&
Q.
&@F<89;)'*,$10.
-- JI"L$M"L(OJr/   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)y)-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	                 j   t        |      | _        || _        t        |      | _        t        |      D 
ci c]  \  }
}||

 c}}
| _        |g | _        n%|D cg c]  }|D cg c]  }| c} c}}| _        | j                  D ]  }| j                  |        t        | j                  |||fi |	| _
        | j                  j                  ddd       |rlt        | j                  d| j                  j                        }|j                  | j                  j                  d   d	<   |j                  d
d       || _        d| _        |rCt        | j                  j$                        D ]!  \  }
}|j'                  d| j(                         # | j+                          yc c}}
w c c}w c c}}w )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.
        N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   rf   cr    r   sbrh   s                   r,   rR   zTable.__init__l  sx   V  -!Fm9B<9P%Q9Pv1ad9P%Q" <DJ6:;dsc*c1c*d;DJ::CNN3  !lNCVSUV			F4f= 4;;z499??SB79vvDII"#34 GGsG+ DO !$))"9"9:1|TZZ0 ; 	= &R +;s   F$	F/$	F*-F/*F/c                 <     | j                   j                  |i | y)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 | y)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                   j                          y)z-Direct (keyboard) input foxus to this widget.N)r  r   r   s    r,   r   zTable.focus  s    		r/   c                 >    | j                   j                  |||       y)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 | y)z%:see: ``MultiListbox.rowconfigure()``N)r  r   )r+   r   rc   rd   s       r,   r   zTable.rowconfigure  s    		y#44r/   c                 b    | j                  |      } | j                  j                  ||fi | y)z(:see: ``MultiListbox.columnconfigure()``N)rZ   r  r   )r+   r   rc   rd   s       r,   r   zTable.columnconfigure  s-    %%i0	!		!!)S7B7r/   c                 b    | j                  |      } | j                  j                  |||fi |S )z&:see: ``MultiListbox.itemconfigure()``)rZ   r  r   )r+   r   r   rc   rd   s        r,   r   zTable.itemconfigure  s2    %%i0	&tyy&&y)SGBGGr/   c                 <    | j                   j                  |||      S )z':see: ``MultiListbox.bind_to_labels()``)r  r   r   s       r,   r   zTable.bind_to_labels  s    yy''$<<r/   c                 <    | j                   j                  |||      S )z*:see: ``MultiListbox.bind_to_listboxes()``)r  r   r   s       r,   r   zTable.bind_to_listboxes  s    yy**8T3??r/   c                 <    | j                   j                  |||      S )z(:see: ``MultiListbox.bind_to_columns()``)r  r   r   s       r,   r   zTable.bind_to_columns  s    yy((4==r/   c           	      P   | j                  |       | j                  j                  ||       | j                  .t	        |      D cg c]  \  }}| j                  |||       }}}| j
                  j                  ||       | j                  r| j                          yyc c}}w )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.
        N)r  r  r   r  rU   r  _DEBUG_check_table_vs_mlb)r+   r   rowvaluejr   s        r,   r   zTable.insert  s     	x 

)X.>>%>G>Q>QFQy!Q/>Q   			H-;;$$& 	s   B"c                 n    |D ]  }| j                  |        | j                  r| j                          yy)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+   	rowvaluesr0  s      r,   extendzTable.extend	  s2     "HKK! ";;$$& r/   c                     | j                  t        | j                        |       | j                  r| j	                          yy)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+   r0  s     r,   rX   zTable.append  s2     	C

OX.;;$$& r/   c                     g | _         | j                  j                  dd       | j                  r| j	                          yy)z0
        Delete all rows in this table.
        r   r   N)r  r  r   r.  r/  r   s    r,   clearzTable.clear!  s7     
		E";;$$& r/   c                     t        |t              rt        d      t        |t              r5t	        |      dk(  r'| j
                  |d      | j                  |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__*  si     eU#455u%#e*/::eAh'(9(9%((CDDE*++r/   c           	         t        |t              rt        d      t        |t              rt	        |      dk(  r|d   | j                  |d         }}| j                  |g      }|| j                  |   |<   | j                  | j                  |||      }| j                  j                  |   j                  ||       | j                  j                  |   j                  |dz          | j                  |       y| j                  |g      }| j                  |       t        |      | j                  |<   | j                  .t!        |      D cg c]  \  }}| j                  |||       }}}| j                  j                  ||       | j                  j                  |dz          | j                  |       yc c}}w )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``.
        r:  r;  r   r
   N)rG   r<  rL   rM   rK   rZ   _save_config_infor  r  r  r   r   r   _restore_config_infor  rI   rU   )r+   r   r   rf   r1  config_cookier   s          r,   r   zTable.__setitem__:  s}    eU#455 u%#e*/8T..uQx8qA 22A37M"DJJqM!~~)nnQ3/II"))!S1II"))!a%0%%m4 !22E7;MNN3 $S	DJJu~~)AJ3Pv1t~~eQ2PIIUC(IIUQY'%%m4 Qs   F=c                    t        |t              rt        d      t        |t              rt	        |      dk(  rt        d      | j
                  |= | j                  j                  |       | j                  r| j                          yy)zA
        Delete the ``row_index``th row from this table.
        r:  r;  zCannot delete a single cell!N)
rG   r<  rL   rM   rK   r  r  r   r.  r/  )r+   r   s     r,   __delitem__zTable.__delitem__a  sq     i'455i'C	Na,?;<<JJy!		#;;$$& 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                  k7  r$t        d|t        |      | j                  fz        y)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   r6  s     r,   r  zTable._checkrowt  sD    
 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     yy%%%r/   c                 p    t        |t              rd|cxk  r| j                  k  r|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  s=     a!q"<4+<+<"<H #= --a00r/   c                 X    | j                   j                  | j                  |             y)z$:see: ``MultiListbox.hide_column()``N)r  r   rZ   r+   rZ   s     r,   r   zTable.hide_column      		d//=>r/   c                 X    | j                   j                  | j                  |             y)z$:see: ``MultiListbox.show_column()``N)r  r   rZ   rJ  s     r,   r   zTable.show_column  rK  r/   c                 X    | j                   j                         }|rt        |d         S y)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  s*     ii$$&s1v;r/   c                 >    | j                   j                  |||       y)z:see: ``MultiListbox.select()``N)r  r@   r   s       r,   r@   zTable.select  s    		s+r/   c                    |dvrt        d      | j                  |      }| j                  d      }|dk(  r*|| j                  k(  r| j                  j                          n:| j                  j                  t        j                  |      |dk(         || _        | j                          | j                  |dd       | j                  r| j                          y	y	)
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
descendingtogglezBsort_by(): order should be "ascending", "descending", or "toggle".T)index_by_idrT  rS  )r   reverse)rU  r   N)rL   rZ   r?  r  r  rV  sortoperator
itemgetterr  r@  r.  r/  )r+   rZ   orderrA  s       r,   sort_byzTable.sort_by  s    & ==W  ((6..4.@ H!>JJ JJOO''5@U   )DM 	!!-Tt!L;;$$& r/   c                     |j                   j                  }| j                  j                  |      ry| j	                  |       y)zLEvent handler for clicking on a column label -- sort by
        that column.continue)ro   rZ   r  r^   r[  )r+   rw   rZ   s      r,   r  zTable._sort  s;     ||00 99##E* LL&r/   c           
      .   | j                   j                  dd       t        | j                        D ][  \  }}| j                  .t        |      D cg c]  \  }}| j	                  |||       }}}| j                   j                  d|       ] yc c}}w )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   N)r  r   rU   r  r  r   )r+   save_configrf   r    r1  r   s         r,   r  zTable._fill_table  sy     			E"

+FAs~~)=Fs^L^6Aqt~~aA.^LIIUC( ,Ls   Bc           	      j    dD ci c]#  }|| j                   j                  |||      d   % c}S c c}w )N)r   r   r   r   r&   )r  r   )r+   rr   ks       r,   _get_itemconfigzTable._get_itemconfig   sJ    
 tyy##Aq!,R00
 	
 
s   (0Fc                 $   |'t        t        t        | j                                    }| j	                         }|r|t        | j                  |         }|r]|D ci c]L  }t        | j                  |         t        | j                        D cg c]  }| j                  ||       c}N }}}||fS |D ci c]6  }|t        | j                        D cg c]  }| j                  ||       c}8 }}}||fS c c}w c c}}w c c}w c c}}w )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.
        )rI   rJ   rK   r  rO  idr  rc  )r+   row_indicesrU  	selectionra  r   configs          r,   r?  zTable._save_config_info  s8     uS_56K %%'	904::i01I 
 %	 %A 4::a=!8=d>O>O8P$8P1D((A.8P$  %	   &   %$A d>O>O8PQ8P1D((A.8PQQ$  
 &  $ Rs0   3DC<)D:DD0D<DDc           
      N   |\  }}|| j                   j                  dd       |rt        | j                        D ]  \  }}t	        |      |v rFt        | j                        D ].  }| j                   j                  |||t	        |         |          0 t	        |      |k(  sh| j                   j                  ||        y|| j                   j                  ||       |D ]?  }t        | j                        D ]%  }| j                   j                  ||||   |          ' A y)zy
        Restore selection & color configuration information that was
        saved using ``_save_config_info``.
        Nr   r   )r   )	r  r   rU   r  re  rJ   r  r   r@   )	r+   cookierU  r   rg  rh  ra  r    r   s	            r,   r@  zTable._restore_config_info3  s	   
 #	6 II%%a/ #DJJ/3c7f$"4#4#45		//1fRWoa6HI 6c7i'II$$QC$0 0 $		   4t001AII++Aq&)A,? 2 r/   c                    | j                   j                  D ]   }t        |       |j                         k(  r J  | D ]  }t        |      | j                  k(  rJ  | j                  t        | j                   j
                        k(  sJ t        |       D ]Z  \  }}t        |      D ]G  \  }}| j                  | j                  |||      }| j                   j                  |      |   |k(  rGJ  \ y)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   r1  cells         r,   r/  zTable._check_table_vs_mlbU  s     99&&Ct9
*** 'Cs8t00000   C		(>(>$????oFAs$S>4>>->>!Q5Dyy}}Q'*d222 * &r/   r   r2   r   )rT  )T)NF)FF)*r   r   r   r   rR   r  rY   r   r\   r   r   r   r   r   r   r   r   r   r   r4  rX   r8  r=  r   rC  rE  r  r   r   rZ   r   r   rO  r@   r[  r  r  rc  r?  r@  r.  r/  r<   r/   r,   r  r  E  s    $T Mh*
*
,
 +- 5 .0 8
H
=@> I"LJ'('	'', %5N'	 & &1??
,''R&)	
&!P@< F#3r/   r  c                    
 t               

j                  d
fd       t        
dj                         g dd       } | j	                  dd	       d
dlm}m} t        t        |j                         d d             D ]  \  }}|d
   dk7  r|j                         }|j                  |      D ]i  }	 |j                         d
   j                         }	 |j                         d
   j                         }| j                  ||j                         ||g       k  | j!                  dd       | j!                  dd       | j!                  dd       | j!                  dd       t#        t%        |             D ])  }dD ]"  }	| ||	f   dk(  s| j'                  ||	dd       $ + 
j)                          y #  d}Y xY w#  d}Y xY w)Nz<Control-q>c                 $    j                         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   r1  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)rx  ry  z#666)r   r   )r   r\   r  splitr  nltk.corpusrs  rt  sortedr  tagged_wordslowersynsets	hypernyms
definitionrX   r   rJ   rK   r   mainloop)tablers  rt  wordpossynset	hyper_defhypo_defr    r   rp  s             @r,   demor  o  s   4DIIm56&,,.#,	E 
JJdJ(*C 2 2 4Tc :;<	cq6S=zz|ood+F%",,.q1<<>	$!++-a0;;= LL$ 1 1 3YIJ ,	 = 
v&1	xF3	zf5	yV4SZ -FS&[!X-  FV !  . ! 	MMO%%$	$#s   5!F<!G<GG__main__)r   rX  tkinterr   r   r   r   r   r	   r  r  r   r<   r/   r,   <module>r     sK     8 8b5 bba3 a3T'T zF r/   