U
    Bes                     @   sb   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e	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 (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highlightthicknessraisedzhelvetica -16 boldz#444white)borderwidthZreliefZfontr	   
foregroundr   Fnone)r   Zselectborderwidthr   ZexportselectionselectbackgroundZactivestyler
   Nc                    sL  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 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 q 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rowZstickyZpadxZpady
<Button-1>z<B1-Motion>z
<Button-4>c                    s
     dS )N_scrolleself k/var/www/nmhs-web.org.in/public_html/infoladakh/backend/venv/lib/python3.8/site-packages/nltk/draw/table.py<lambda>       z'MultiListbox.__init__.<locals>.<lambda>z
<Button-5>c                    s
     dS )Nr   r   r   r   r!   r"   r#      r$   z<MouseWheel>c                    s     | jS N)r   deltar   r   r!   r"   r#      r$   z
<Button-2>c                    s     | j| jS r%   )	scan_markxyr   r   r!   r"   r#      r$   z<B2-Motion>c                    s     | j| jS r%   )scan_dragtor(   r)   r   r   r!   r"   r#      r$   z
<B1-Leave>c                 S   s   dS )Nbreakr!   r   r!   r!   r"   r#      r$   z<Up>c                    s    j ddS )Nr   r&   selectr   r   r!   r"   r#      r$   z<Down>c                    s    j ddS )Nr   r,   r-   r   r   r!   r"   r#      r$   z<Prior>c                    s    j    dS Nr,   r.   	_pagesizer   r   r!   r"   r#      r$   z<Next>c                    s    j   dS r/   r0   r   r   r!   r"   r#      r$   )
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"   r=   @   sT    

zMultiListbox.__init__c                 C   s   |j drdS d| _|j | krZt| jD ],\}}t|j| |   dk r*|| _q*nD|j|j  d krz|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   <Motion><ButtonRelease-%d>T)widgetrF   _resize_column_indexr?   r:   absr(   winfo_xwinfo_widthrD   _resize_column_motion_cbnum_resize_column_buttonrelease_cb)r    eventrO   rR   r!   r!   r"   rH      s&    	


 zMultiListbox._resize_columnc                 C   s^   | j | j }| |d  }|j|j  }| |  }td|d || |  |d< d S )Nwidth   )r:   rX   r[   r(   rW   rZ   max)r    r_   rR   Z	charwidthx1Zx2r!   r!   r"   r\      s
    z%MultiListbox._resize_column_motion_cbc                 C   s"   |j d|j  |j d d S )NrV   rU   )rW   Zunbindr]   )r    r_   r!   r!   r"   r^      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.
        )r9   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.
        )r8   r;   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.
        )r8   r:   r   r!   r!   r"   	listboxes   s    	zMultiListbox.listboxesc                 C   s:   |j |j}| dd | | | | |   d S )Nr   end)rW   nearestr)   selection_clearselection_setactivatefocus)r    r   rO   r!   r!   r"   rG      s
    

zMultiListbox._selectc                 C   s   | j D ]}||d qdS )Nunitr+   r:   yview_scroll)r    r&   rR   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)r3   indexr   r!   r!   r"   r1      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   rg   r   )
r7   r6   curselectionr3   ri   minrb   sizerj   seer    rp   r&   rt   r!   r!   r"   r.     s    

zMultiListbox.selectc                 K   s   t t| t|  }t| D ]\}}|dsD|drh| jD ]}||dd |i qJq(|ds||dr| jD ]}||dd |i qq(t| ||i q(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-   )dictr4   items
startswithr;   rI   r:   r   )r    rM   rN   keyvalrP   listboxr!   r!   r"   rI   ,  s    	

zMultiListbox.configurec                 C   s   |  ||i dS )z|
        Configure this widget.  This is equivalent to
        ``self.configure({key,val``)}.  See ``configure()``.
        N)rI   )r    r{   r|   r!   r!   r"   __setitem__@  s    zMultiListbox.__setitem__c                 K   s    | j D ]}|j||f| q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_indexrM   rN   rR   r!   r!   r"   rowconfigureG  s    
zMultiListbox.rowconfigurec                 K   sz   | j | }tt| t|  }t| D ]B\}}|dkrft| D ]}||||i qNq2|||i q2dS )z
        Configure all table cells in the given column.  Valid keyword
        arguments are: ``background``, ``bg``, ``foreground``, ``fg``,
        ``selectbackground``, ``selectforeground``.
        )r	   bgr   Zfgr   selectforegroundN)r:   rx   r4   ry   r5   rs   r   rI   )r    	col_indexrM   rN   rR   r{   r|   rO   r!   r!   r"   columnconfigureP  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   )r    r   r   rM   rN   rR   r!   r!   r"   r   g  s    
zMultiListbox.itemconfigurec                 G   sV   |D ]}t |t | jkrtdqt| jtt| D ]\}}|j|f|  q8d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)r6   r9   r7   zipr:   r4   insert)r    rp   rowseltrR   eltsr!   r!   r"   r   t  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).0rR   firstlastr!   r"   
<listcomp>  s     z$MultiListbox.get.<locals>.<listcomp>c                 S   s   g | ]}t |qS r!   )r8   r   r   r!   r!   r"   r     s     N)r:   r   r8   )r    r   r   valuesr!   r   r"   r     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:   bboxr3   )
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)r;   Zgrid_forgetrf   r@   )r    r   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   N)r<   r;   rC   r:   r@   )r    r   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!   )rF   )r   rP   addfuncsequencer!   r"   r     s     z/MultiListbox.bind_to_labels.<locals>.<listcomp>)re   r    r   r   r   r!   r   r"   bind_to_labels  s    
zMultiListbox.bind_to_labelsc                 C   s   | j D ]}|||| q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)rf   rF   )r    r   r   r   r}   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"   bind_to_columns  s
    
  zMultiListbox.bind_to_columnsc                 O   s   | j d j||S Nr   )r:   rq   r    argskwargsr!   r!   r"   rq     s    zMultiListbox.curselectionc                 O   s   | j d j||S r   )r:   selection_includesr   r!   r!   r"   r     s    zMultiListbox.selection_includesc                 O   s   | j d j||S r   )r:   itemcgetr   r!   r!   r"   r     s    zMultiListbox.itemcgetc                 O   s   | j d j||S r   )r:   rs   r   r!   r!   r"   rs     s    zMultiListbox.sizec                 O   s   | j d j||S r   )r:   rp   r   r!   r!   r"   rp     s    zMultiListbox.indexc                 O   s   | j d j||S r   )r:   rh   r   r!   r!   r"   rh     s    zMultiListbox.nearestc                 O   s   | j D ]}|j|| qd S r%   )r:   rk   r    r   r   rR   r!   r!   r"   rk      s    
zMultiListbox.activatec                 O   s   | j D ]}|j|| qd S r%   )r:   deleter   r!   r!   r"   r     s    
zMultiListbox.deletec                 O   s   | j D ]}|j|| qd S r%   )r:   r'   r   r!   r!   r"   r'     s    
zMultiListbox.scan_markc                 O   s   | j D ]}|j|| qd S r%   )r:   r*   r   r!   r!   r"   r*     s    
zMultiListbox.scan_dragtoc                 O   s   | j D ]}|j|| qd S r%   )r:   rt   r   r!   r!   r"   rt     s    
zMultiListbox.seec                 O   s   | j D ]}|j|| qd S r%   )r:   selection_anchorr   r!   r!   r"   r     s    
zMultiListbox.selection_anchorc                 O   s   | j D ]}|j|| qd S r%   )r:   ri   r   r!   r!   r"   ri     s    
zMultiListbox.selection_clearc                 O   s   | j D ]}|j|| qd S r%   )r:   rj   r   r!   r!   r"   rj     s    
zMultiListbox.selection_setc                 O   s   | j D ]}|j||}q|S r%   )r:   yview)r    r   r   rR   vr!   r!   r"   r      s    
zMultiListbox.yviewc                 O   s   | j D ]}|j|| qd S r%   )r:   yview_movetor   r!   r!   r"   r   %  s    
zMultiListbox.yview_movetoc                 O   s   | j D ]}|j|| qd S r%   rn   r   r!   r!   r"   ro   )  s    
zMultiListbox.yview_scroll)NNT)N)N)NNN)NNN)NNN)9__name__
__module____qualname____doc__rx   r>   rA   rE   r=   rH   r\   r^   propertyrd   re   rf   rG   r   r1   r.   rI   r~   r   r   r   r   r   r   r   r   r   r   r   rq   r   r   rs   rp   rh   rk   r   r'   r*   rt   r   ri   rj   r   r   ro   
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 | _| jD ]}
| 	|
 qXt
| j|||f|	| _| jjdddd	 |rt| jd
| jjd}|j| jjd d< |jddd || _d| _|rt| jjD ]\}}|d| j q|   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 r%   r!   )r   rO   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!   )r   r   r!   r!   r"   r     s     z-Table.__init__.<locals>.<listcomp>.<listcomp>r!   r   r!   r!   r"   r     s     z"Table.__init__.<locals>.<listcomp>leftTboth)sideexpandfillvertical)Zorientcommandr   Zyscrollcommandrightr)   )r   r   r   )r6   _num_columns	_reprfuncr   _framerx   r?   _column_name_to_index_rows	_checkrowr   _mlbpackr   r   setrf   Z
_scrollbar_sortkeyre   rF   _sort_fill_table)r    rJ   rd   r   rL   Z	scrollbarZclick_to_sortreprfuncrM   rN   r   sbrO   rQ   r!   r!   r"   r=   m  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     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   rC   r   r!   r!   r"   rC     s    z
Table.gridc                 C   s   | j   dS )z-Direct (keyboard) input foxus to this widget.N)r   rl   r   r!   r!   r"   rl     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   rF   r   r!   r!   r"   rF     s    z
Table.bindc                 K   s   | j j||f| dS )z%:see: ``MultiListbox.rowconfigure()``N)r   r   )r    r   rM   rN   r!   r!   r"   r     s    zTable.rowconfigurec                 K   s    |  |}| jj||f| dS )z(:see: ``MultiListbox.columnconfigure()``N)rD   r   r   )r    r   rM   rN   r!   r!   r"   r     s    
zTable.columnconfigurec                 K   s   |  |}| jj|||f|S )z&:see: ``MultiListbox.itemconfigure()``)rD   r   r   )r    r   r   rM   rN   r!   r!   r"   r     s    
zTable.itemconfigurec                 C   s   | j |||S )z':see: ``MultiListbox.bind_to_labels()``)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     s    zTable.bind_to_listboxesc                 C   s   | j |||S )z(:see: ``MultiListbox.bind_to_columns()``)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   r   jr   r   r    r!   r"   r     s    z Table.insert.<locals>.<listcomp>)r   r   r   r   r?   r   _DEBUG_check_table_vs_mlb)r    r   rowvaluer!   r   r"   r     s    


zTable.insertc                 C   s&   |D ]}|  | q| 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)rB   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)r   r6   r   r   r   r    r   r!   r!   r"   rB     s    zTable.appendc                 C   s&   g | _ | jdd | jr"|   dS )z0
        Delete all rows in this table.
        r   rg   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.
        Slicing not supported   r   r   N)r2   slicer7   r8   r6   r   rD   )r    rp   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``.
        r   r   r   r   Nc                    s   g | ]\}}  ||qS r!   r   r   rp   r    r!   r"   r   ]  s     z%Table.__setitem__.<locals>.<listcomp>)r2   r   r7   r8   r6   rD   _save_config_infor   r   r   rf   r   r   _restore_config_infor   r4   r?   )r    rp   r|   rO   r   config_cookier!   r   r"   r~   ;  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.
        r   r   zCannot delete a single cell!N)
r2   r   r7   r8   r6   r   r   r   r   r   )r    r   r!   r!   r"   __delitem__b  s    
zTable.__delitem__c                 C   s
   t | jS )z<
        :return: the number of rows in this table.
        )r6   r   r   r!   r!   r"   __len__o  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)r6   r   r7   r   r!   r!   r"   r   u  s    zTable._checkrowc                 C   s   | j jS )z1A list of the names of the columns in this table.)r   rd   r   r!   r!   r"   rd     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)r2   r3   r   r   )r    rO   r!   r!   r"   rD     s    $zTable.column_indexc                 C   s   | j | | dS )z$:see: ``MultiListbox.hide_column()``N)r   r   rD   r    rD   r!   r!   r"   r     s    zTable.hide_columnc                 C   s   | j | | dS )z$:see: ``MultiListbox.show_column()``N)r   r   rD   r   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   rq   r3   )r    selr!   r!   r"   selected_row  s    
zTable.selected_rowc                 C   s   | j ||| dS )z:see: ``MultiListbox.select()``N)r   r.   ru   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   )r{   reverse)r   rt   N)r7   rD   r   r   r   r   sortoperator
itemgetterr   r   r   r   )r    rD   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)rW   rD   r   rH   r   )r    r_   rD   r!   r!   r"   r     s
    
zTable._sortc                    sV   j dd tjD ]8\ }jdk	rB fddt|D }j d| q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   rg   Nc                    s   g | ]\}}  ||qS r!   r   r   rO   r    r!   r"   r     s     z%Table._fill_table.<locals>.<listcomp>)r   r   r?   r   r   r   )r    Zsave_configr   r!   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   )r   kr   rr    r!   r"   r     s   z(Table._get_itemconfig.<locals>.<genexpr>)r   r   r	   r   )rx   )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   r   r   r   r    r!   r"   r   )  s     5Table._save_config_info.<locals>.<genexpr>.<listcomp>N)idr   r5   r   r   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   r   r   r!   r"   r   /  s     r   N)r5   r   r   r   r   r"   r   .  s   )r4   r5   r6   r   r   r   rx   )r    Zrow_indicesr   	selectionconfigr!   r   r"   r     s    
zTable._save_config_infoc           	   	   C   s   |\}}|dkr| j dd |rt| jD ]\\}}t||krlt| jD ] }| j |||t| |  qJt||kr,| j j||d q,nJ|dk	r| j j||d |D ],}t| jD ]}| j |||| |  qqdS )zy
        Restore selection & color configuration information that was
        saved using ``_save_config_info``.
        Nr   rg   )rt   )	r   ri   r?   r   r   r5   r   r   r.   )	r    cookier   rt   r   r   r   r   r   r!   r!   r"   r   5  s    zTable._restore_config_infoc                 C   s   | j jD ]}t| | kstq| D ]}t|| jks&tq&| jt| j jksTtt| D ]J\}}t|D ]8\}}| jdk	r| |||}| j 	|| |ksltqlq\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   rf   r6   rs   AssertionErrorr   rd   r?   r   r   )r    r   r   rO   r   cellr!   r!   r"   r   W  s    
zTable._check_table_vs_mlb)NNN)N)NNN)NNN)NNN)NNT)r   )T)NF)FF)*r   r   r   r   r=   r   rC   rl   rF   r   r   r   r   r   r   r   r   r   r   r   rB   r   r   r~   r   r   r   r   rd   rD   r   r   r   r.   r   r   r   r   r   r   r   r   r!   r!   r!   r"   r   F  sZ   *
T




	'


)

)
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} tt	|
 d d D ]\}}|d dkrqx| }||D ]f}z| d  }W n   d}Y nX z| d  }W n   d}Y nX | || ||g qqx| jddd | jddd | jddd | jddd tt| D ]6}dD ]*}	| ||	f dkrV| j||	ddd qVqN   d S )Nz<Control-q>c                    s      S r%   )destroyr   rootr!   r"   r#   r  r$   zdemo.<locals>.<lambda>zWord Synset Hypernym Hyponymr   r   c                 S   s   d| S )Nz  %sr!   )rO   r   sr!   r!   r"   r#   x  r$   )rL   r   Tr   )r   r   )wordnet)browni  Nz*none*Wordz#afa)r	   ZSynsetz#efeHypernymz#feeHyponymz#ffe)r
  r  z#666)r   r   )r   rF   r   splitr   Znltk.corpusr  r  sortedr   Ztagged_wordslowerZsynsetsZ	hypernymsZ
definitionrB   r   r5   r6   r   Zmainloop)
tabler  r  wordposZsynsetZ	hyper_defZhypo_defr   r   r!   r  r"   demop  sN    
 

   r  __main__)r   r   tkinterr   r   r   r   r   r   objectr   r  r   r!   r!   r!   r"   <module>   s       4    .+