3
d³                 @   s`   d Z ddlZddlmZmZmZmZmZ G dd deZG dd dZ	dd	 Z
ed
kr\e
  dS )zC
Tkinter widgets for displaying multi-column listboxes and tables.
    N)FrameLabelListbox	ScrollbarTkc            	   @   s  e Zd ZdZeddddZeddddd	d
ZeddddddddZdi fddZdd Z	dd Z
dd Zedd Zedd Zedd Zdd Zd d! Zd"d# Zdbd$d%Zi fd&d'Zd(d) Zi fd*d+Zi fd,d-Zdcd.d/Zd0d1 Zddd2d3Zd4d5 Zd6d7 Zd8d9 Zded:d;Zdfd<d=Zdgd>d?Z d@dA Z!dBdC Z"dDdE Z#dFdG Z$dHdI Z%dJdK Z&dLdM Z'dNdO Z(dPdQ Z)dRdS Z*dTdU Z+dVdW Z,dXdY Z-dZd[ Z.d\d] Z/d^d_ Z0d`da Z1eZ2eZ3eZ4e,Z5e-Z6e"Z7e.Z8dS )h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highlightthicknessZraisedzhelvetica -16 boldz#444Zwhite)borderwidthZrelieffontr	   
foregroundr   Fnone)r   Zselectborderwidthr   ZexportselectionselectbackgroundZactivestyler
   Nc                sR  t |trtt|}d}nd}t|dkr4tdt| _g  _g  _	|dkrbdgt| }nt|t|krztd| _
tj |f j  jddd x>t jD ].\}} j||| d |rt fd	|i j}	 j	j|	 |	j|dd
ddd ||	_t f j}
 jj|
 |
j|dd
ddd ||
_|
jd j |
jd j |
jd fdd |
jd fdd |
jd fdd |
jd fdd |
jd fdd |
jddd  |	jd j qW  jd j  jd fdd  jd fdd  jd fd d  jd! fd"d  j|f| 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,
            the 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.:

                >>> mlb = MultiListbox(master, 5, label_foreground='red')
        FTr   zExpected at least one columnNr   z*Expected one column_weight for each column)weighttextnews)columnrowstickypadxpadyz
<Button-1>z<B1-Motion>z
<Button-4>c                s
    j dS )Nr   )_scroll)e)self //tmp/pip-build-v9q4h5k9/nltk/nltk/draw/table.py<lambda>   s    z'MultiListbox.__init__.<locals>.<lambda>z
<Button-5>c                s
    j dS )Nr   r   )r   )r   )r   r   r   r      s    z<MouseWheel>c                s    j | jS )N)r   delta)r   )r   r   r   r      s    z
<Button-2>c                s    j | j| jS )N)	scan_markxy)r   )r   r   r   r      s    z<B2-Motion>c                s    j | j| jS )N)scan_dragtor"   r#   )r   )r   r   r   r      s    z
<B1-Leave>c             S   s   dS )Nbreakr   )r   r   r   r   r      s    z<Up>c                s    j ddS )Nr   )r    r   )select)r   )r   r   r   r      s    z<Down>c                s    j ddS )Nr   )r    )r&   )r   )r   r   r   r      s    z<Prior>c                s    j  j  dS )N)r    )r&   	_pagesize)r   )r   r   r   r      s    z<Next>c                s    j  j dS )N)r    )r&   r'   )r   )r   r   r   r      s    )
isinstanceintlistrangelen
ValueErrortuple_column_names
_listboxes_labels_column_weightsr   __init__FRAME_CONFIGZgrid_rowconfigure	enumerategrid_columnconfigurer   LABEL_CONFIGappendgridcolumn_indexr   LISTBOX_CONFIGbind_select_resize_column	configure)r   mastercolumnscolumn_weightscnfkwZinclude_labelsilabelllbr   )r   r   r3   >   sT    

zMultiListbox.__init__c             C   s   |j jdrdS d| _|j | kr^xt| jD ],\}}t|j|j |j   dk r,|| _q,W nD|j|j j d kr~|j j	| _n$|jdk r|j j	dkr|j j	d | _| jdk	r|j jd| j
 |j jd	|j | j d
S 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   z<Motion>z<ButtonRelease-%d>T)widgetr<   _resize_column_indexr5   r0   absr"   winfo_xwinfo_widthr:   _resize_column_motion_cbnum_resize_column_buttonrelease_cb)r   eventrE   rH   r   r   r   r>      s"    	

zMultiListbox._resize_columnc             C   s^   | j | j }|j |d  }|j|jj  }|j |j  }td|d || |  |d< d S )Nwidth   )r0   rL   rO   r"   rK   rN   max)r   rS   rH   Z	charwidthZx1Zx2r   r   r   rP      s
    z%MultiListbox._resize_column_motion_cbc             C   s"   |j jd|j  |j jd d S )Nz<ButtonRelease-%d>z<Motion>)rK   ZunbindrQ   )r   rS   r   r   r   rR      s    z,MultiListbox._resize_column_buttonrelease_cbc             C   s   | j S )zh
        A tuple containing the names of the columns used by this
        multi-column listbox.
        )r/   )r   r   r   r   column_names   s    zMultiListbox.column_namesc             C   s
   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.
        )r.   r1   )r   r   r   r   column_labels   s    zMultiListbox.column_labelsc             C   s
   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.
        )r.   r0   )r   r   r   r   	listboxes   s    	zMultiListbox.listboxesc             C   s:   |j j|j}| jdd | j| | j| | j  d S )Nr   end)rK   nearestr#   selection_clearselection_setactivatefocus)r   r   rE   r   r   r   r=      s
    

zMultiListbox._selectc             C   s    x| j D ]}|j|d qW dS )Nunitr%   )r0   yview_scroll)r   r    rH   r   r   r   r      s    zMultiListbox._scrollc             C   s   t | jdt | jd S )z2:return: The number of rows that makes up one pagez
@0,1000000z@0,0)r)   index)r   r   r   r   r'      s    zMultiListbox._pagesizec             C   s   |dk	r|dk	rt d|dk	rNt| j dkr:d| }nt| j d | }| jdd |dk	rtt|d| j d }| j| |r| j	| 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   rZ   r   )
r-   r,   curselectionr)   r\   minrV   sizer]   see)r   rb   r    rf   r   r   r   r&     s    

zMultiListbox.selectc             K   s   t t|j t|j  }xt|j D ]\}}|jdsF|jdrnxr| jD ]}|j|dd |i qNW q*|jds|jdrx6| jD ]}|j|dd |i qW q*tj| ||i q*W dS )a8  
        Configure this widget.  Use ``label_*`` to configure all
        labels; and ``listbox_*`` to configure all listboxes.  E.g.:

                >>> mlb = MultiListbox(master, 5)
                >>> mlb.configure(label_foreground='red')
                >>> mlb.configure(listbox_foreground='red')
        Zlabel_zlabel-   NZlistbox_zlistbox-   )dictr*   items
startswithr1   r?   r0   r   )r   rC   rD   keyvalrF   listboxr   r   r   r?   *  s    	zMultiListbox.configurec             C   s   | j ||i dS )z|
        Configure this widget.  This is equivalent to
        ``self.configure({key,val``)}.  See ``configure()``.
        N)r?   )r   rl   rm   r   r   r   __setitem__>  s    zMultiListbox.__setitem__c             K   s$   x| j D ]}|j||f| qW dS )z
        Configure all table cells in the given row.  Valid keyword
        arguments are: ``background``, ``bg``, ``foreground``, ``fg``,
        ``selectbackground``, ``selectforeground``.
        N)r0   itemconfigure)r   	row_indexrC   rD   rH   r   r   r   rowconfigureE  s    zMultiListbox.rowconfigurec             K   s   | j | }tt|j t|j  }xVt|j D ]F\}}|dkrlx4t|j D ]}|j|||i qRW q4|j||i q4W 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)r	   rs   r   rt   r   ru   )r0   ri   r*   rj   r+   re   rp   r?   )r   	col_indexrC   rD   rH   rl   rm   rE   r   r   r   columnconfigureN  s    
     zMultiListbox.columnconfigurec             K   s   | j | }|j||f|S )z
        Configure the table cell at the given row and column.  Valid
        keyword arguments are: ``background``, ``bg``, ``foreground``,
        ``fg``, ``selectbackground``, ``selectforeground``.
        )r0   rp   )r   rq   rv   rC   rD   rH   r   r   r   rp   e  s    
zMultiListbox.itemconfigurec             G   s^   x&|D ]}t |t | jkrtdqW x0t| jtt| D ]\}}|j|f|  q>W 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)r,   r/   r-   zipr0   r*   insert)r   rb   rowseltrH   Zeltsr   r   r   ry   r  s    

zMultiListbox.insertc                s8    fdd| j D }r,dd t| D S t|S d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                s   g | ]}|j  qS r   )get).0rH   )firstlastr   r   
<listcomp>  s    z$MultiListbox.get.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )r.   )r}   r   r   r   r   r     s    N)r0   rx   r.   )r   r~   r   valuesr   )r~   r   r   r|     s    zMultiListbox.getc       
      C   sZ   | j d|d\}}}}| j| j|\}}}}	t|t| t|t| 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   )Z	grid_bboxr0   bboxr)   )
r   r   colZdxZdy_r"   r#   whr   r   r   r     s    zMultiListbox.bboxc             C   s4   | j r| j | j  | j| j  | j|d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)r1   Zgrid_forgetrY   r6   )r   rv   r   r   r   hide_column  s    	zMultiListbox.hide_columnc             C   sV   | j | }| jr*| j| j|ddddd | j| j|ddddd | j||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   r   r   r   )r   N)r2   r1   r9   r0   r6   )r   rv   r   r   r   r   show_column  s    


zMultiListbox.show_columnc                s    fd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                s   g | ]}|j  qS r   )r<   )r}   rF   )addfuncsequencer   r   r     s    z/MultiListbox.bind_to_labels.<locals>.<listcomp>)rX   )r   r   r   r   r   )r   r   r   r   bind_to_labels  s    
zMultiListbox.bind_to_labelsc             C   s"   x| j D ]}|j||| qW 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)rY   r<   )r   r   r   r   rn   r   r   r   bind_to_listboxes  s    
zMultiListbox.bind_to_listboxesc             C   s   | j |||| j||| 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   r   r   r   bind_to_columns  s    
zMultiListbox.bind_to_columnsc             O   s   | j d j||S )Nr   )r0   rc   )r   argskwargsr   r   r   rc     s    zMultiListbox.curselectionc             O   s   | j d j||S )Nr   )r0   selection_includes)r   r   r   r   r   r   r     s    zMultiListbox.selection_includesc             O   s   | j d j||S )Nr   )r0   itemcget)r   r   r   r   r   r   r     s    zMultiListbox.itemcgetc             O   s   | j d j||S )Nr   )r0   re   )r   r   r   r   r   r   re     s    zMultiListbox.sizec             O   s   | j d j||S )Nr   )r0   rb   )r   r   r   r   r   r   rb     s    zMultiListbox.indexc             O   s   | j d j||S )Nr   )r0   r[   )r   r   r   r   r   r   r[     s    zMultiListbox.nearestc             O   s    x| j D ]}|j|| qW d S )N)r0   r^   )r   r   r   rH   r   r   r   r^     s    zMultiListbox.activatec             O   s    x| j D ]}|j|| qW d S )N)r0   delete)r   r   r   rH   r   r   r   r     s    zMultiListbox.deletec             O   s    x| j D ]}|j|| qW d S )N)r0   r!   )r   r   r   rH   r   r   r   r!     s    zMultiListbox.scan_markc             O   s    x| j D ]}|j|| qW d S )N)r0   r$   )r   r   r   rH   r   r   r   r$   
  s    zMultiListbox.scan_dragtoc             O   s    x| j D ]}|j|| qW d S )N)r0   rf   )r   r   r   rH   r   r   r   rf     s    zMultiListbox.seec             O   s    x| j D ]}|j|| qW d S )N)r0   selection_anchor)r   r   r   rH   r   r   r   r     s    zMultiListbox.selection_anchorc             O   s    x| j D ]}|j|| qW d S )N)r0   r\   )r   r   r   rH   r   r   r   r\     s    zMultiListbox.selection_clearc             O   s    x| j D ]}|j|| qW d S )N)r0   r]   )r   r   r   rH   r   r   r   r]     s    zMultiListbox.selection_setc             O   s    x| j D ]}|j||}qW |S )N)r0   yview)r   r   r   rH   vr   r   r   r     s    zMultiListbox.yviewc             O   s    x| j D ]}|j|| qW d S )N)r0   yview_moveto)r   r   r   rH   r   r   r   r   #  s    zMultiListbox.yview_movetoc             O   s    x| j D ]}|j|| qW d S )N)r0   ra   )r   r   r   rH   r   r   r   ra   '  s    zMultiListbox.yview_scroll)NNT)N)N)NNN)NNN)NNN)9__name__
__module____qualname____doc__ri   r4   r7   r;   r3   r>   rP   rR   propertyrW   rX   rY   r=   r   r'   r&   r?   ro   rr   rw   rp   ry   r|   r   r   r   r   r   r   rc   r   r   re   rb   r[   r^   r   r!   r$   rf   r   r\   r]   r   r   ra   
itemconfig	rowconfigcolumnconfigZselect_anchorZselect_clearZselect_includesZ
select_setr   r   r   r   r      s   	^!	
$	




r   c               @   sV  e Zd ZdZdddddi fddZdd Zdd	 Zd
d ZdHddZi fddZ	i fddZ
dIddZdJddZdKddZdLddZe	Ze
ZeZdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zed,d- Zd.d/ Zd0d1 Zd2d3 Zd4d5 Z dMd6d7Z!dNd9d:Z"d;d< Z#dOd=d>Z$d?d@ Z%dPdBdCZ&dQdDdEZ'dAZ(dFdG Z)dS )R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'

    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'])
        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	             K   s  t || _|| _t|| _dd t|D | _|dkr>g | _ndd |D | _x| jD ]}
| j|
 qVW t	| j|||f|	| _
| j
jdddd	 |rt| jd
| j
jd}|j| j
jd d< |jddd || _d| _|rx&t| j
jD ]\}}|jd| j qW | 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             S   s   i | ]\}}||qS r   r   )r}   rE   cr   r   r   
<dictcomp>  s    z"Table.__init__.<locals>.<dictcomp>Nc             S   s   g | ]}d d |D qS )c             S   s   g | ]}|qS r   r   )r}   r   r   r   r   r     s    z-Table.__init__.<locals>.<listcomp>.<listcomp>r   )r}   r   r   r   r   r     s    z"Table.__init__.<locals>.<listcomp>leftTboth)sideexpandfillZvertical)Zorientcommandr   Zyscrollcommandrightr#   )r   r   z
<Button-1>)r,   _num_columns	_reprfuncr   _framer5   _column_name_to_index_rows	_checkrowr   _mlbpackr   r   setrY   Z
_scrollbar_sortkeyrX   r<   _sort_fill_table)r   r@   rW   rz   rB   Z	scrollbarZclick_to_sortreprfuncrC   rD   r   ZsbrE   rG   r   r   r   r3   k  s*    +

zTable.__init__c             O   s   | j j|| dS )zrPosition this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.pack()`` for more info.N)r   r   )r   r   r   r   r   r   r     s    z
Table.packc             O   s   | j j|| dS )zrPosition this table's main frame widget in its parent
        widget.  See ``Tkinter.Frame.grid()`` for more info.N)r   r9   )r   r   r   r   r   r   r9     s    z
Table.gridc             C   s   | j j  dS )z-Direct (keyboard) input foxus to this widget.N)r   r_   )r   r   r   r   r_     s    zTable.focusc             C   s   | j 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   r   r   r   r   r   r   r<     s    z
Table.bindc             K   s   | j j||f| dS )z%:see: ``MultiListbox.rowconfigure()``N)r   rr   )r   rq   rC   rD   r   r   r   rr     s    zTable.rowconfigurec             K   s    | j |}| jj||f| dS )z(:see: ``MultiListbox.columnconfigure()``N)r:   r   rw   )r   rv   rC   rD   r   r   r   rw     s    
zTable.columnconfigurec             K   s   | j |}| jj|||f|S )z&:see: ``MultiListbox.itemconfigure()``)r:   r   rp   )r   rq   rv   rC   rD   r   r   r   rp     s    
zTable.itemconfigurec             C   s   | j j|||S )z':see: ``MultiListbox.bind_to_labels()``)r   r   )r   r   r   r   r   r   r   r     s    zTable.bind_to_labelsc             C   s   | j j|||S )z*:see: ``MultiListbox.bind_to_listboxes()``)r   r   )r   r   r   r   r   r   r   r     s    zTable.bind_to_listboxesc             C   s   | j j|||S )z(:see: ``MultiListbox.bind_to_columns()``)r   r   )r   r   r   r   r   r   r   r     s    zTable.bind_to_columnsc                sZ   j | jj | jdk	r: fddt|D }jj | jrVj  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                s   g | ]\}}j  ||qS r   )r   )r}   jr   )rq   r   r   r   r     s    z Table.insert.<locals>.<listcomp>)r   r   ry   r   r5   r   _DEBUG_check_table_vs_mlb)r   rq   rowvaluer   )rq   r   r   ry     s    


zTable.insertc             C   s*   x|D ]}| j | qW | jr&| j  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)r8   r   r   )r   Z	rowvaluesr   r   r   r   extend  s    
zTable.extendc             C   s$   | j t| j| | jr | j  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)ry   r,   r   r   r   )r   r   r   r   r   r8     s    zTable.appendc             C   s&   g | _ | jjdd | jr"| j  dS )z0
        Delete all rows in this table.
        r   rZ   N)r   r   r   r   r   )r   r   r   r   clear   s    zTable.clearc             C   sX   t |trtdn@t |trFt|dkrF| j|d  | j|d  S t| j| S d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.
        zSlicing not supported   r   r   N)r(   slicer-   r.   r,   r   r:   )r   rb   r   r   r   __getitem__)  s
    	

zTable.__getitem__c                s  t  trtdnt  trt dkr d j d  }}j|g}|j| |< jdk	rvj|||}j	j
| j|| j	j
| j|d  j| nnj g}j| t|j < jdk	r fddt|D }j	j | j	j d  j| 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``.
        zSlicing not supportedr   r   r   Nc                s   g | ]\}}j  ||qS r   )r   )r}   r   r   )rb   r   r   r   r   [  s    z%Table.__setitem__.<locals>.<listcomp>)r(   r   r-   r.   r,   r:   _save_config_infor   r   r   rY   ry   r   _restore_config_infor   r*   r5   )r   rb   rm   rE   r   config_cookier   )rb   r   r   ro   9  s&    



zTable.__setitem__c             C   sV   t |trtdt |tr0t|dkr0td| j|= | jj| | jrR| j	  dS )zA
        Delete the ``row_index``th row from this table.
        zSlicing not supportedr   zCannot delete a single cell!N)
r(   r   r-   r.   r,   r   r   r   r   r   )r   rq   r   r   r   __delitem__`  s    
zTable.__delitem__c             C   s
   t | jS )z<
        :return: the number of rows in this table.
        )r,   r   )r   r   r   r   __len__m  s    zTable.__len__c             C   s*   t || jkr&td|t || jf 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)r,   r   r-   )r   r   r   r   r   r   s  s    zTable._checkrowc             C   s   | j jS )z1A list of the names of the columns in this table.)r   rW   )r   r   r   r   rW     s    zTable.column_namesc             C   s6   t |tr(d|  ko| jk n  r(|S | j| S d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   N)r(   r)   r   r   )r   rE   r   r   r   r:     s    $zTable.column_indexc             C   s   | j j| j| dS )z$:see: ``MultiListbox.hide_column()``N)r   r   r:   )r   r:   r   r   r   r     s    zTable.hide_columnc             C   s   | j j| j| dS )z$:see: ``MultiListbox.show_column()``N)r   r   r:   )r   r:   r   r   r   r     s    zTable.show_columnc             C   s"   | j j }|rt|d S 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   rc   r)   )r   selr   r   r   selected_row  s    
zTable.selected_rowc             C   s   | j j||| dS )z:see: ``MultiListbox.select()``N)r   r&   )r   rb   r    rf   r   r   r   r&     s    zTable.selecttogglec             C   s   |d
krt d| j|}| jdd}|dkrD|| jkrD| jj  n | jjtj||dkd || _| j	  | j
|ddd | jr| j  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_id)rl   reverse)r   rf   N)r   r   r   )r-   r:   r   r   r   r   sortoperator
itemgetterr   r   r   r   )r   r:   orderr   r   r   r   sort_by  s    
zTable.sort_byc             C   s*   |j j}| jj|rdS | j| dS dS )zLEvent handler for clicking on a column label -- sort by
        that column.continueN)rK   r:   r   r>   r   )r   rS   r:   r   r   r   r     s
    
zTable._sortc                sZ   j jdd xFtjD ]8\ }jdk	rD fddt|D }j jd| qW d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   rZ   Nc                s   g | ]\}}j  ||qS r   )r   )r}   r   r   )rE   r   r   r   r     s    z%Table._fill_table.<locals>.<listcomp>)r   r   r5   r   r   ry   )r   Zsave_configr   r   )rE   r   r   r     s
    	
zTable._fill_tablec                s    fdddD S )Nc                s"   i | ]}j j |d |qS )r   r   )r   r   )r}   k)r   rr   r   r   r      s   z)Table._get_itemconfig.<locals>.<dictcomp>r   ru   r	   r   )r   ru   r	   r   r   )r   r   r   r   )r   r   r   r   _get_itemconfig  s
       zTable._get_itemconfigFc                sn   |dkrt tt j} j }|r<|dk	r<t j| }|rT fdd|D }n fd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                s2   i | ]*  fd dt jD tj  qS )c                s   g | ]}j  |qS r   )r   )r}   r   )r   r   r   r   r   &  s    z6Table._save_config_info.<locals>.<dictcomp>.<listcomp>)r+   r   idr   )r}   )r   )r   r   r   $  s   z+Table._save_config_info.<locals>.<dictcomp>c                s(   i | ]   fd dt jD  qS )c                s   g | ]}j  |qS r   )r   )r}   r   )r   r   r   r   r   ,  s    z6Table._save_config_info.<locals>.<dictcomp>.<listcomp>)r+   r   )r}   )r   )r   r   r   +  s   )r*   r+   r,   r   r   r   )r   Zrow_indicesr   	selectionconfigr   )r   r   r   
  s    


zTable._save_config_infoc       	      C   s   |\}}|dkr| j jdd |rxt| jD ]`\}}t||krrx.t| jD ] }| j j|||t| |  qNW t||kr.| j j||d q.W nR|dk	r| j j||d x8|D ]0}x*t| jD ]}| j j|||| |  qW qW dS )zy
        Restore selection & color configuration information that was
        saved using ``_save_config_info``.
        Nr   rZ   )rf   )	r   r\   r5   r   r   r+   r   rp   r&   )	r   cookier   rf   r   r   r   r   r   r   r   r   r   2  s     
zTable._restore_config_infoc             C   s   x$| j jD ]}t| |j ks
tq
W x| D ]}t|| jks,tq,W | jt| j jks\txZt| D ]N\}}xDt|D ]8\}}| jdk	r| j|||}| j j	|| |ksxtqxW qfW 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   rY   r,   re   AssertionErrorr   rW   r5   r   r|   )r   r   r   rE   r   Zcellr   r   r   r   T  s    

zTable._check_table_vs_mlb)NNN)N)NNN)NNN)NNN)NNT)r   )T)NF)FF)*r   r   r   r   r3   r   r9   r_   r<   rr   rw   rp   r   r   r   r   r   r   ry   r   r8   r   r   ro   r   r   r   r   rW   r:   r   r   r   r&   r   r   r   r   r   r   r   r   r   r   r   r   r   D  sV   %K




	'

)

(
r   c        
         s  t    jd fdd t dj ddddgdd d} | jd	d
d ddlm}m} xtt	|j
 d d D ]\}}|d dkrqr|j }xt|j|D ]f}y|j d j }W n   d}Y nX y|j d j }W n   d}Y nX | j||j ||g qW qrW | jddd | jddd | jddd | jddd xJtt| D ]:}x2dD ]*}	| ||	f dkrZ| j||	ddd qZW qPW  j  d S )Nz<Control-q>c                s    j  S )N)destroy)r   )rootr   r   r   o  s    zdemo.<locals>.<lambda>zWord Synset Hypernym Hyponymr   r   c             S   s   d| S )Nz  %sr   )rE   r   sr   r   r   r   u  s    )rB   r   Tr   )r   r   )brownwordneti  Nz*none*Wordz#afa)r	   ZSynsetz#efeHypernymz#feeHyponymz#ffez#666)r   ru   )r   r   )r   r<   r   splitr   Znltk.corpusr   r   sortedr   Ztagged_wordslowerZsynsetsZ	hypernymsZ
definitionr8   r   r+   r,   r   Zmainloop)
tabler   r   wordposZsynsetZ	hyper_defZhypo_defr   r   r   )r   r   demom  sB    
"


r   __main__)r   r   tkinterr   r   r   r   r   r   r   r   r   r   r   r   r   <module>
   s       4    -*