U
    ºñdZÁ3  ã                   @   sd  d dl mZmZ d dlmZ d dlmZmZmZ d dl	Z	ej
Z
e
jZe
jZe
jZe
jZe
jZe
jZdd„ Zdeƒ kr|eƒ Znd sˆtdƒ‚dad	ad
d„ Zdd„ Zdd„ Zeeƒ 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"d"d#„ Z#d$d%„ Z$G d&d'„ d'e%ƒZ&d(d)„ Z'd*d+„ Z(d,d-„ Z)d.d/„ Z*G d0d1„ d1e+ƒZ,d2d3„ Z-G d4d5„ d5e.ƒZ/dS )6é    )ÚdivisionÚprint_function)Úescape)ÚbytesÚ	text_typeÚ
text_typesNc               
   C   sŽ   dd l } z<z|  | jd¡ W n | jk
r2   Y nX |  ¡ d pBdW S  tk
rˆ } z&|jrv|jd  d¡rvW Y ¢
dS ‚ W 5 d }~X Y nX d S )Nr   Ú é   zunknown locale)ÚlocaleÚ	setlocaleÚLC_ALLÚErrorZ	getlocaleÚ
ValueErrorÚargsÚ
startswith)r
   Úe© r   ú,/usr/lib/python3/dist-packages/urwid/util.pyÚdetect_encoding)   s    
r   Údetected_encodingz
It worked!Tc                 C   sz   |   ¡ } | dkr t d¡ dan&| dkr8t d¡ dant d¡ dadaz| r^d	 | ¡ | aW n tk
rt   Y nX d
S )z~
    Set the byte encoding to assume when processing strings and the
    encoding to use when converting unicode strings.
    )zutf-8Úutf8Úutfr   F)zeuc-jpzeuc-krzeuc-cnzeuc-twÚgb2312ÚgbkÚbig5zcn-gbÚuhcÚeucjpÚeuckrÚeuccnZeuctwZcncbZwideTZnarrowÚasciir   N)ÚlowerÚstr_utilZset_byte_encodingÚ_use_dec_specialÚ_target_encodingÚencodeÚLookupError)Úencodingr   r   r   Úset_encodingB   s     



 r'   c                   C   s   t  ¡ S )z©
    Get the mode Urwid is using when processing text strings.
    Returns 'narrow' for 8-bit encodings, 'wide' for CJK encodings
    or 'utf8' for UTF-8 encodings.
    )r!   Zget_byte_encodingr   r   r   r   Úget_encoding_moded   s    r(   c              	   C   s&  t rft| ƒtkrfz|  tj¡} W nD tk
rd   ttjtj	ƒD ] \}}|  
|tj| tj ¡} q>Y nX t| ƒtkr”|  
tjtj d¡} t | td¡} t| tƒs¢t‚tj d¡}tj d¡}|  |¡}t|d tƒsÖt‚|d  
|tƒ ¡}g }g }|�r| |¡ | dt|ƒf¡ t|ƒdk�r(||fS |dd… D ]Ü}	t|	tƒ�sHt‚t|tƒ�sXt‚|	 |d¡}
t|
ƒdk�r²|
d }t|tƒ�sŠt‚| |¡ t|tj d¡t|ƒfƒ �q4|
\}}| 
|tƒ ¡}|�rì| |¡ t|tjt|ƒfƒ |�r4| |¡ t|dt|ƒfƒ �q4tƒ  |¡}||fS )z:
    Return (encoded byte string, character set rle).
    r   Úreplacer   r   Nr	   )r"   Útyper   Ú	translater   ZDEC_SPECIAL_CHARMAPÚNotImplementedErrorÚzipZDEC_SPECIAL_CHARSZALT_DEC_SPECIAL_CHARSr)   ÚSOÚSIÚcodecsr$   r#   Ú
isinstancer   ÚAssertionErrorÚsplitÚappendÚlenÚrle_append_modifyZDEC_TAGÚjoin)ÚsÚcZaltr.   r/   ZsisZsis0ZsoutZcoutZsnZslZsinZsonZoutstrr   r   r   Úapply_target_encodingm   sX    ÿ 




r:   c                   C   s   t o
t dkS )zi
    Return True if python is able to convert non-ascii unicode strings
    to the current encoding.
    r   )r#   r   r   r   r   Úsupports_unicode®   s    r;   c                 C   s~   |}d }}|dkrHt | |||ƒ\}}||k rHd}t | |||d ƒ\}}|| | }	t | |||	ƒ\}
}||	k rrd}||
||fS )a	  
    Calculate the result of trimming text.
    start_offs -- offset into text to treat as screen column 0
    end_offs -- offset into text to treat as the end of the line
    start_col -- screen column to trim at the left
    end_col -- screen column to trim at the right

    Returns (start, end, pad_left, pad_right), where:
    start -- resulting start offset
    end -- resulting end offset
    pad_left -- 0 for no pad or 1 for one space to be added
    pad_right -- 0 for no pad or 1 for one space to be added
    r   r	   )Úcalc_text_pos)ÚtextZ
start_offsZend_offsÚ	start_colÚend_colÚsposÚpad_leftÚ	pad_rightZscÚrunÚposr   r   r   Úcalc_trim_text¹   s     ÿrE   c                 C   s®   t | dt| ƒ||ƒ\}}}}t|||ƒ}	t|||ƒ}
|r^t||d ƒ}t|	|dfƒ t|
dƒ |r„t||ƒ}t|	|dfƒ t|
dƒ tƒ  |¡| ||…  tƒ  |¡ |	|
fS )z<
    Return ( trimmed text, trimmed attr, trimmed cs ).
    r   r	   )Nr	   )rE   r5   Ú
rle_subsegÚ
rle_get_atÚrle_append_beginning_modifyr6   r   Úrjust)r=   ÚattrZcsr>   r?   r@   ÚeposrA   rB   ZattrtrZcstrÚalr   r   r   Útrim_text_attr_csØ   s.        ÿ



ÿ ÿrM   c                 C   s>   d}|dk rdS | D ]$\}}|| |kr0|  S ||7 }qdS )z-
    Return the attribute at offset pos.
    r   Nr   )ÚrlerD   ÚxÚarC   r   r   r   rG   í   s    
rG   c                 C   s‚   g }d}| D ]p\}}|rF||kr2||8 }||7 }q||7 }||8 }d}||krR q~|| |krf|| }||7 }|  ||f¡ q|S )z$Return a sub segment of an rle list.r   ©r4   )rN   ÚstartÚendÚlrO   rP   rC   r   r   r   rF   û   s$    rF   c                 C   s:   d}| D ],}t |ƒtks$tt| ƒƒ‚|\}}||7 }q|S )z]
    Return the number of characters covered by a run length
    encoded attribute list.
    r   )r*   Útupler2   Úrepr)rN   rC   ÚvrP   Úrr   r   r   Úrle_len  s    
rY   c                 C   s\   |\}}| s ||fg| dd…< n8| d \}}||krF||| f| d< n||fg| dd…< dS )z�
    Append (a, r) (unpacked from *a_r*) to BEGINNING of rle.
    Merge with first run when possible

    MODIFIES rle parameter contents. Returns None.
    Nr   r   )rN   Úa_rrP   rX   rL   rC   r   r   r   rH     s    rH   c                 C   sN   |\}}| r| d d |kr.|   ||f¡ dS | d \}}||| f| d< dS )z�
    Append (a, r) (unpacked from *a_r*) to the rle list rle.
    Merge with last run when possible.

    MODIFIES rle parameter contents. Returns None.
    éÿÿÿÿr   NrQ   )rN   rZ   rP   rX   ZlaZlrr   r   r   r6   0  s    r6   c                 C   s*   |sdS t | |d ƒ | |dd… 7 } dS )z¡
    Append attribute list rle2 to rle.
    Merge last run of rle with first run of rle2 when possible.

    MODIFIES attr parameter contents. Returns None.
    Nr   r	   ©r6   )rN   Úrle2r   r   r   Úrle_join_modify>  s    r^   c           
      C   sº   d }}| r|sg S | d \}}|d \}}g }|r¶|r¶t ||ƒ}	t|||f|	fƒ ||	8 }|dkr„|t| ƒk r„| | \}}|d7 }||	8 }|dkr0|t|ƒk r0|| \}}|d7 }q0|S )a  
    Merge the runs of rle1 and rle2 like this:
    eg.
    rle1 = [ ("a", 10), ("b", 5) ]
    rle2 = [ ("Q", 5), ("P", 10) ]
    rle_product: [ (("a","Q"), 5), (("a","P"), 5), (("b","P"), 5) ]

    rle1 and rle2 are assumed to cover the same total run.
    r	   r   )Úminr6   r5   )
Úrle1r]   Zi1Zi2Úa1Zr1Úa2Zr2rT   rX   r   r   r   Úrle_productJ  s$    
 

rc   c                 C   s>   g }g }| D ](\\}}}t |||fƒ t |||fƒ q||fS )z!
    Inverse of rle_product.
    r\   )rN   r`   r]   ra   rb   rX   r   r   r   Ú
rle_factorh  s    rd   c                   @   s   e Zd ZdS )ÚTagMarkupExceptionN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   re   t  s    re   c                 C   sF   t | dƒ\}}|d dd…  |¡}|r>|d d dkr>|d= ||fS )z:Return (text string, attribute list) for tagmarkup passed.Nr   r[   )Ú_tagmarkup_recurser7   )ÚtmÚtlrL   r=   r   r   r   Údecompose_tagmarkupv  s
    rl   c                 C   sæ   t | ƒtkr~g }g }| D ]\}t||ƒ\}}|rd|d \}}|d \}	}
||	krd|	||
 f|d< |d= ||7 }||7 }q||fS t | ƒtkr¶t| ƒdkr¤td| f ƒ‚| \}}t||ƒS t| ttf ƒsÒtd|  ƒ‚| g|t| ƒfgfS )zsReturn (text list, attribute list) for tagmarkup passed.

    tm -- tagmarkup
    attr -- current attribute or Noner[   r   é   z5Tuples must be in the form (attribute, tagmarkup): %rzInvalid markup element: %r)	r*   Úlistri   rU   r5   re   r1   r   r   )rj   rJ   ZrtlZralÚelementrk   rL   Z	last_attrZlast_runZtop_attrZtop_runr   r   r   ri   ‚  s,    

ri   c                 C   s*   t | ƒtko(t| ƒdko(| d  d¡dkS )Né   r   Zmouse)r*   rU   r5   Úfind©Zevr   r   r   Úis_mouse_event©  s    rs   c                 C   s   |   d¡dkS )NZpressr   )rq   rr   r   r   r   Úis_mouse_press¬  s    rt   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )Ú	MetaSuperzadding .__superc                    sB   t t| ƒ |||¡ t| d| ƒr*tdƒ‚t| d| t | ƒƒ d S )Nz
_%s__superz/Class has same name as one of its super classes)Úsuperru   Ú__init__ÚhasattrÚAttributeErrorÚsetattr)ÚclsÚnameÚbasesÚd©Ú	__class__r   r   rw   ³  s    zMetaSuper.__init__)rf   rg   rh   Ú__doc__rw   Ú__classcell__r   r   r   r   ru   ±  s   ru   c                 C   s0   t | |d  d |d  ƒ}|d d }|| S )aW  
    Scale val in the range [0, val_range-1] to an integer in the range
    [0, out_range-1].  This implementation uses the "round-half-up" rounding
    method.

    >>> "%x" % int_scale(0x7, 0x10, 0x10000)
    '7777'
    >>> "%x" % int_scale(0x5f, 0x100, 0x10)
    '6'
    >>> int_scale(2, 6, 101)
    40
    >>> int_scale(1, 3, 4)
    2
    r	   rm   )Úint)ÚvalZ	val_rangeZ	out_rangeZnumZdemr   r   r   Ú	int_scale»  s    r…   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	ÚStoppingContextz±Context manager that calls ``stop`` on a given object on exit.  Used to
    make the ``start`` method on `MainLoop` and `BaseScreen` optionally act as
    context managers.
    c                 C   s
   || _ d S ©N)Ú_wrapped)ÚselfÚwrappedr   r   r   rw   Õ  s    zStoppingContext.__init__c                 C   s   | S r‡   r   )r‰   r   r   r   Ú	__enter__Ø  s    zStoppingContext.__enter__c                 G   s   | j  ¡  d S r‡   )rˆ   Ústop)r‰   Úexc_infor   r   r   Ú__exit__Û  s    zStoppingContext.__exit__N)rf   rg   rh   r�   rw   r‹   rŽ   r   r   r   r   r†   Ð  s   r†   )0Z
__future__r   r   Zurwidr   Zurwid.compatr   r   r   r0   r!   r<   Z
calc_widthZis_wide_charZmove_next_charZmove_prev_charZwithin_double_byter   Úlocalsr   r2   r#   r"   r'   r(   r:   r;   rE   rM   rG   rF   rY   rH   r6   r^   rc   rd   Ú	Exceptionre   rl   ri   rs   rt   r*   ru   r…   Úobjectr†   r   r   r   r   Ú<module>   sN   
"	='
