B
    P?[                 @   sn   d Z ddlm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eZd	d
 Zedkrje  dS )zC
Tkinter widgets for displaying multi-column listboxes and tables.
    )divisionN)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 (http://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reliefZfontr
   
foregroundr   FZ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|dd
ddd ||	_t f j}
 j|
 |
j|dd
ddd ||
_|
d j |
d j |
d fdd |
d fdd |
d fdd |
d fdd |
d fdd |
ddd  |	d j qW  d j  d fdd  d fdd  d fd d  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
     dS )N)_scroll)e)self .lib/python3.7/site-packages/nltk/draw/table.py<lambda>   s    z'MultiListbox.__init__.<locals>.<lambda>z
<Button-5>c                s
     dS )Nr	   )r   )r   )r   r   r   r      s    z<MouseWheel>c                s     | jS )N)r   delta)r   )r   r   r   r      s    z
<Button-2>c                s     | j| jS )N)	scan_markxy)r   )r   r   r   r      s    z<B2-Motion>c                s     | 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   )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    dS )N)r   )r%   	_pagesize)r   )r   r   r   r      s    z<Next>c                s    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   r2   C   sT    

zMultiListbox.__init__c             C   s   |j drdS d| _|j | kr^xt| jD ],\}}t|j| |   dk r,|| _q,W nD|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 d| 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_indexr4   r/   absr!   winfo_xwinfo_widthr9   _resize_column_motion_cbnum_resize_column_buttonrelease_cb)r   eventrD   rG   r   r   r   r=      s"    	

zMultiListbox._resize_columnc             C   s^   | j | j }| |d  }|j|j  }| |  }td|d || |  |d< d S )Nwidth   )r/   rK   rN   r!   rJ   rM   max)r   rR   rG   Z	charwidthZx1Zx2r   r   r   rO      s
    z%MultiListbox._resize_column_motion_cbc             C   s"   |j d|j  |j d d S )Nz<ButtonRelease-%d>z<Motion>)rJ   ZunbindrP   )r   rR   r   r   r   rQ      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-   r0   )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-   r/   )r   r   r   r   	listboxes   s    	zMultiListbox.listboxesc             C   s:   |j |j}| dd | | | | |   d S )Nr   end)rJ   nearestr"   selection_clearselection_setactivatefocus)r   r   rD   r   r   r   r<      s
    

zMultiListbox._selectc             C   s    x| j D ]}||d qW dS )NZunitr$   )r/   yview_scroll)r   r   rG   r   r   r   r      s    zMultiListbox._scrollc             C   s   t | dt | 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|  dkr:d| }nt|  d | }| dd |dk	rtt|d|  d }| | |r| 	| 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   rY   r	   )
r,   r+   curselectionr(   r[   minrU   sizer\   see)r   r`   r   rd   r   r   r   r%     s    

zMultiListbox.selectc             K   s   t t| t|  }xt| D ]\}}|dsF|drnxr| jD ]}||dd |i qNW q*|ds|drx6| jD ]}||dd |i qW q*t| ||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
startswithr0   r>   r/   r   )r   rB   rC   keyvalrE   listboxr   r   r   r>   /  s    	zMultiListbox.configurec             C   s   |  ||i dS )z|
        Configure this widget.  This is equivalent to
        ``self.configure({key,val``)}.  See ``configure()``.
        N)r>   )r   rj   rk   r   r   r   __setitem__C  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)r/   itemconfigure)r   	row_indexrB   rC   rG   r   r   r   rowconfigureJ  s    zMultiListbox.rowconfigurec             K   s   | j | }tt| t|  }xVt| D ]F\}}|dkrlx4t| D ]}||||i qRW q4|||i q4W dS )z
        Configure all table cells in the given column.  Valid keyword
        arguments are: ``background``, ``bg``, ``foreground``, ``fg``,
        ``selectbackground``, ``selectforeground``.
        )r
   Zbgr   Zfgr   selectforegroundN)r/   rg   r)   rh   r*   rc   rn   r>   )r   	col_indexrB   rC   rG   rj   rk   rD   r   r   r   columnconfigureS  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``.
        )r/   rn   )r   ro   rr   rB   rC   rG   r   r   r   rn   j  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,   zipr/   r)   insert)r   r`   rowsZeltrG   Zeltsr   r   r   ru   w  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 | ]}|  qS r   )get).0rG   )firstlastr   r   
<listcomp>  s    z$MultiListbox.get.<locals>.<listcomp>c             S   s   g | ]}t |qS r   )r-   )rx   r   r   r   r   r{     s    N)r/   rt   r-   )r   ry   rz   valuesr   )ry   rz   r   rw     s    zMultiListbox.getc       
      C   sZ   | j d|d\}}}}| 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_bboxr/   bboxr(   )
r   r   colZdxZdy_r!   r"   whr   r   r   r}     s    zMultiListbox.bboxc             C   s4   | j r| 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)r0   Zgrid_forgetrX   r5   )r   rr   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)r1   r0   r8   r/   r5   )r   rr   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 | ]}|  qS r   )r;   )rx   rE   )addfuncsequencer   r   r{     s    z/MultiListbox.bind_to_labels.<locals>.<listcomp>)rW   )r   r   r   r   r   )r   r   r   r   bind_to_labels  s    
zMultiListbox.bind_to_labelsc             C   s"   x| j D ]}|||| 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)rX   r;   )r   r   r   r   rl   r   r   r   bind_to_listboxes  s    
zMultiListbox.bind_to_listboxesc             C   s   |  |||| ||| 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   )r/   ra   )r   argskwargsr   r   r   ra     s    zMultiListbox.curselectionc             O   s   | j d j||S )Nr   )r/   selection_includes)r   r   r   r   r   r   r     s    zMultiListbox.selection_includesc             O   s   | j d j||S )Nr   )r/   itemcget)r   r   r   r   r   r   r     s    zMultiListbox.itemcgetc             O   s   | j d j||S )Nr   )r/   rc   )r   r   r   r   r   r   rc     s    zMultiListbox.sizec             O   s   | j d j||S )Nr   )r/   r`   )r   r   r   r   r   r   r`     s    zMultiListbox.indexc             O   s   | j d j||S )Nr   )r/   rZ   )r   r   r   r   r   r   rZ     s    zMultiListbox.nearestc             O   s    x| j D ]}|j|| qW d S )N)r/   r]   )r   r   r   rG   r   r   r   r]     s    zMultiListbox.activatec             O   s    x| j D ]}|j|| qW d S )N)r/   delete)r   r   r   rG   r   r   r   r     s    zMultiListbox.deletec             O   s    x| j D ]}|j|| qW d S )N)r/   r    )r   r   r   rG   r   r   r   r      s    zMultiListbox.scan_markc             O   s    x| j D ]}|j|| qW d S )N)r/   r#   )r   r   r   rG   r   r   r   r#     s    zMultiListbox.scan_dragtoc             O   s    x| j D ]}|j|| qW d S )N)r/   rd   )r   r   r   rG   r   r   r   rd     s    zMultiListbox.seec             O   s    x| j D ]}|j|| qW d S )N)r/   selection_anchor)r   r   r   rG   r   r   r   r     s    zMultiListbox.selection_anchorc             O   s    x| j D ]}|j|| qW d S )N)r/   r[   )r   r   r   rG   r   r   r   r[     s    zMultiListbox.selection_clearc             O   s    x| j D ]}|j|| qW d S )N)r/   r\   )r   r   r   rG   r   r   r   r\     s    zMultiListbox.selection_setc             O   s    x| j D ]}|j||}qW |S )N)r/   yview)r   r   r   rG   vr   r   r   r   #  s    zMultiListbox.yviewc             O   s    x| j D ]}|j|| qW d S )N)r/   yview_moveto)r   r   r   rG   r   r   r   r   (  s    zMultiListbox.yview_movetoc             O   s    x| j D ]}|j|| qW d S )N)r/   r_   )r   r   r   rG   r   r   r   r_   ,  s    zMultiListbox.yview_scroll)NNT)N)N)NNN)NNN)NNN)9__name__
__module____qualname____doc__rg   r3   r6   r:   r2   r=   rO   rQ   propertyrV   rW   rX   r<   r   r&   r%   r>   rm   rp   rs   rn   ru   rw   r}   r   r   r   r   r   ra   r   r   rc   r`   rZ   r]   r   r    r#   rd   r   r[   r\   r   r   r_   
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 lits 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|| _tdd t|D | _|dkrBg | _ndd |D | _x| jD ]}
| 	|
 qZW 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 ]\}}|d| j qW |   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 initialze 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   | ]\}}||fV  qd S )Nr   )rx   rD   cr   r   r   	<genexpr>  s    z!Table.__init__.<locals>.<genexpr>Nc             S   s   g | ]}d d |D qS )c             S   s   g | ]}|qS r   r   )rx   r   r   r   r   r{     s    z-Table.__init__.<locals>.<listcomp>.<listcomp>r   )rx   r   r   r   r   r{     s    z"Table.__init__.<locals>.<listcomp>leftTboth)sideexpandfillZvertical)ZorientZcommandr   Zyscrollcommandrightr"   )r   r   z
<Button-1>)r+   _num_columns	_reprfuncr   _framerg   r4   _column_name_to_index_rows	_checkrowr   _mlbpackr   r   setrX   Z
_scrollbar_sortkeyrW   r;   _sort_fill_table)r   r?   rV   rv   rA   Z	scrollbarZclick_to_sortreprfuncrB   rC   r   ZsbrD   rF   r   r   r   r2   p  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   r8   )r   r   r   r   r   r   r8     s    z
Table.gridc             C   s   | 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 ||| 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   rp   )r   ro   rB   rC   r   r   r   rp     s    zTable.rowconfigurec             K   s    |  |}| jj||f| dS )z(:see: ``MultiListbox.columnconfigure()``N)r9   r   rs   )r   rr   rB   rC   r   r   r   rs     s    
zTable.columnconfigurec             K   s   |  |}| jj|||f|S )z&:see: ``MultiListbox.itemconfigure()``)r9   r   rn   )r   ro   rr   rB   rC   r   r   r   rn     s    
zTable.itemconfigurec             C   s   | 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 |||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 |||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dk	r: fddt|D }j | jrV  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 | ]\}}  ||qS r   )r   )rx   jr   )ro   r   r   r   r{     s    z Table.insert.<locals>.<listcomp>)r   r   ru   r   r4   r   _DEBUG_check_table_vs_mlb)r   ro   rowvaluer   )ro   r   r   ru     s    


zTable.insertc             C   s*   x|D ]}|  | qW | jr&|   dS )z
        Add new rows at the end of the table.

        :param rowvalues: A list of row values used to initialze the
            table.  Each row value should be a tuple of cell values,
            one for each column in the row.
        N)r7   r   r   )r   Z	rowvaluesr   r   r   r   extend  s    
zTable.extendc             C   s$   |  t| j| | jr |   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)ru   r+   r   r   r   )r   r   r   r   r   r7     s    zTable.appendc             C   s&   g | _ | jdd | jr"|   dS )z0
        Delete all rows in this table.
        r   rY   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  | |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   r9   )r   r`   r   r   r   __getitem__.  s
    	

zTable.__getitem__c                s  t  trtdnt  trt dkr d  d  }}|g}|j| |< jdk	rv|||}j	j
| || j	j
| |d  | nn g}| t|j < jdk	r fddt|D }j	 | j	 d  | 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 | ]\}}  ||qS r   )r   )rx   r   r   )r`   r   r   r   r{   `  s    z%Table.__setitem__.<locals>.<listcomp>)r'   r   r,   r-   r+   r9   _save_config_infor   r   r   rX   ru   r   _restore_config_infor   r)   r4   )r   r`   rk   rD   r   config_cookier   )r`   r   r   rm   >  s&    



zTable.__setitem__c             C   sV   t |trtdt |tr0t|dkr0td| j|= | j| | jrR| 	  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   ro   r   r   r   __delitem__e  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__r  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   x  s    zTable._checkrowc             C   s   | j jS )z1A list of the names of the columns in this table.)r   rV   )r   r   r   r   rV     s    zTable.column_namesc             C   s6   t |tr(d|  kr | jk r(n n|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   rD   r   r   r   r9     s    $zTable.column_indexc             C   s   | j | | dS )z$:see: ``MultiListbox.hide_column()``N)r   r   r9   )r   r9   r   r   r   r     s    zTable.hide_columnc             C   s   | j | | dS )z$:see: ``MultiListbox.show_column()``N)r   r   r9   )r   r9   r   r   r   r     s    zTable.show_columnc             C   s"   | 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   ra   r(   )r   Zselr   r   r   selected_row  s    
zTable.selected_rowc             C   s   | j ||| dS )z:see: ``MultiListbox.select()``N)r   r%   )r   r`   r   rd   r   r   r   r%     s    zTable.selecttogglec             C   s   |dkrt d| |}| jdd}|dkrD|| jkrD| j  n | jjt||dkd || _| 	  | j
|ddd | jr|   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.
        )Z	ascending
descendingr   zBsort_by(): order should be "ascending", "descending", or "toggle".T)index_by_idr   r   )rj   reverse)r   rd   N)r,   r9   r   r   r   r   sortoperator
itemgetterr   r   r   r   )r   r9   orderr   r   r   r   sort_by  s    
zTable.sort_byc             C   s*   |j j}| j|rdS | | dS dS )zLEvent handler for clicking on a column label -- sort by
        that column.continueN)rJ   r9   r   r=   r   )r   rR   r9   r   r   r   r     s
    
zTable._sortc                sZ   j dd xFtjD ]8\ }jdk	rD fddt|D }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   rY   Nc                s   g | ]\}}  ||qS r   )r   )rx   r   r   )rD   r   r   r   r{     s    z%Table._fill_table.<locals>.<listcomp>)r   r   r4   r   r   ru   )r   Zsave_configr   r   )rD   r   r   r     s
    	
zTable._fill_tablec                s   t  fdddD S )Nc             3   s&   | ]}|j  |d  fV  qdS )r   N)r   r   )rx   k)r   rr   r   r   r     s   z(Table._get_itemconfig.<locals>.<genexpr>)r   rq   r
   r   )rg   )r   r   r   r   )r   r   r   r   _get_itemconfig  s    zTable._get_itemconfigFc                sv   |dkrt tt j}  }|r<|dk	r<t j| }|rXt fdd|D }nt 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             3   s6   | ]. t j   fd dtjD fV  qdS )c                s   g | ]}  |qS r   )r   )rx   r   )r   r   r   r   r{   ,  s    z5Table._save_config_info.<locals>.<genexpr>.<listcomp>N)idr   r*   r   )rx   )r   )r   r   r   *  s   z*Table._save_config_info.<locals>.<genexpr>c             3   s,   | ]$   fd dt jD fV  qdS )c                s   g | ]}  |qS r   )r   )rx   r   )r   r   r   r   r{   2  s    z5Table._save_config_info.<locals>.<genexpr>.<listcomp>N)r*   r   )rx   )r   )r   r   r   2  s   )r)   r*   r+   r   r   r   rg   )r   Zrow_indicesr   	selectionconfigr   )r   r   r     s    


zTable._save_config_infoc       	   	   C   s   |\}}|dkr| j dd |rxt| jD ]`\}}t||krrx.t| jD ] }| 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 |||| |  qW qW dS )zy
        Restore selection & color configuration information that was
        saved using ``_save_config_info``.
        Nr   rY   )rd   )	r   r[   r4   r   r   r*   r   rn   r%   )	r   Zcookier   rd   r   r   r   r   r   r   r   r   r   8  s     
zTable._restore_config_infoc             C   s   x$| j jD ]}t| | 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 	|| |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   rX   r+   rc   AssertionErrorr   rV   r4   r   rw   )r   r~   r   rD   r   Zcellr   r   r   r   Z  s    

zTable._check_table_vs_mlb)NNN)N)NNN)NNN)NNN)NNT)r   )T)NF)FF)*r   r   r   r   r2   r   r8   r^   r;   rp   rs   rn   r   r   r   r   r   r   ru   r   r7   r   r   rm   r   r   r   r   rV   r9   r   r   r   r%   r   r   r   r   r   r   r   r   r   r   r   r   r   I  sV   %K




	'

)

)
r   c        
         s  t    d fdd t d ddddgdd d} | jd	d
d ddlm} ddlm} xtt	|
 d d D ]\}}|d dkrqz| }xt||D ]f}y| d  }W n   d}Y nX y| d  }W n   d}Y nX | || ||g qW qzW | jddd | jddd | jddd | jddd xJtt| D ]:}x2dD ]*}	| ||	f dkrb| j||	ddd qbW qXW    d S )Nz<Control-q>c                s      S )N)Zdestroy)r   )rootr   r   r   u  s    zdemo.<locals>.<lambda>zWord Synset Hypernym Hyponymr   r	   c             S   s   d| S )Nz  %sr   )rD   r   sr   r   r   r   {  s    )rA   r   Tr   )r   r   )wordnet)browni  Nz*none*ZWordz#afa)r
   ZSynsetz#efeHypernymz#feeHyponymz#ffe)r   r   z#666)r   rq   )r   r;   r   splitr   Znltk.corpusr   r   sortedr   Ztagged_wordslowerZsynsetsZ	hypernymsZ
definitionr7   r   r*   r+   r   Zmainloop)
tabler   r   ZwordposZsynsetZ	hyper_defZhypo_defr   r   r   )r   r   demos  sD    
"


r   __main__)r   Z
__future__r   r   Zsix.moves.tkinterr   r   r   r   r   r   objectr   r   r   r   r   r   r   <module>
   s        4    .+