o
    o_*                     @   sT   d dl mZ d dlmZ d dlZG dd deZG dd deZG dd	 d	eZdS )
    )Edit)DecimalNc                       s6   e Zd ZdZdZd
 fdd	Zdd Zdd	 Z  ZS )NumEdita  NumEdit - edit numerical types

    based on the characters in 'allowed' different numerical types
    can be edited:
      + regular int: 0123456789
      + regular float: 0123456789.
      + regular oct: 01234567
      + regular hex: 0123456789abcdef
    $0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZTc                    s"   t t| || || _|| _d S )N)superr   __init___allowedtrimLeadingZeros)selfallowedcaptiondefaultr	   	__class__ //usr/lib/python3/dist-packages/urwid/numedit.pyr   (   s   
zNumEdit.__init__c                 C   s   t |dko| | jv S )z5
        Return true for allowed characters.
           )lenupperr   )r
   chr   r   r   
valid_char-   s   zNumEdit.valid_charc                 C   s   |\}t | |f|}|s>| jr>| jdkr>| jdd dkr>| | jd  | | jdd  | jdkr>| jdd dks|S )aC  
        Handle editing keystrokes.  Remove leading zeros.

        >>> e, size = NumEdit("0123456789", u"", "5002"), (10,)
        >>> e.keypress(size, 'home')
        >>> e.keypress(size, 'delete')
        >>> assert e.edit_text == "002"
        >>> e.keypress(size, 'end')
        >>> assert e.edit_text == "2"
        >>> # binary only
        >>> e, size = NumEdit("01", u"", ""), (10,)
        >>> assert e.edit_text == ""
        >>> e.keypress(size, '1')
        >>> e.keypress(size, '0')
        >>> e.keypress(size, '1')
        >>> assert e.edit_text == "101"
        r   Nr   0)r   keypressr	   edit_pos	edit_textset_edit_posset_edit_text)r
   sizekeymaxcol	unhandledr   r   r   r   3   s   zNumEdit.keypress)T)	__name__
__module____qualname____doc__ALLOWEDr   r   r   __classcell__r   r   r   r   r      s    	r   c                       s*   e Zd ZdZd	 fdd	Zdd Z  ZS )
IntegerEditzEdit widget for integer values N
   c                    s   || _ d}| jd| j  }|durSt|tttfstdt|tr>t|r>d|}t	
|t|t	js=td||nt|trO| d dkrOtdt|}tt| j|||| j d	kd
 dS )a  
        caption -- caption markup
        default -- default edit value

        >>> IntegerEdit(u"", 42)
        <IntegerEdit selectable flow widget '42' edit_pos=2>
        >>> e, size = IntegerEdit(u"", "5002"), (10,)
        >>> e.keypress(size, 'home')
        >>> e.keypress(size, 'delete')
        >>> assert e.edit_text == "002"
        >>> e.keypress(size, 'end')
        >>> assert e.edit_text == "2"
        >>> e.keypress(size, '9')
        >>> e.keypress(size, '0')
        >>> assert e.edit_text == "290"
        >>> e, size = IntegerEdit("", ""), (10,)
        >>> assert e.value() is None
        >>> # binary
        >>> e, size = IntegerEdit(u"", "1010", base=2), (10,)
        >>> e.keypress(size, 'end')
        >>> e.keypress(size, '1')
        >>> assert e.edit_text == "10101"
        >>> assert e.value() == Decimal("21")
        >>> # HEX
        >>> e, size = IntegerEdit(u"", "10", base=16), (10,)
        >>> e.keypress(size, 'end')
        >>> e.keypress(size, 'F')
        >>> e.keypress(size, 'f')
        >>> assert e.edit_text == "10Ff"
        >>> assert e.keypress(size, 'G') == 'G'  # unhandled key
        >>> assert e.edit_text == "10Ff"
        >>> # keep leading 0's when not base 10
        >>> e, size = IntegerEdit(u"", "10FF", base=16), (10,)
        >>> assert e.edit_text == "10FF"
        >>> assert e.value() == Decimal("4351")
        >>> e.keypress(size, 'home')
        >>> e.keypress(size, 'delete')
        >>> e.keypress(size, '0')
        >>> assert e.edit_text == "00FF"
        >>> # test exception on incompatable value for base
        >>> e, size = IntegerEdit(u"", "10FG", base=16), (10,)
        Traceback (most recent call last):
            ...
        ValueError: invalid value: 10FG for base 16
        >>> # test exception on float init value
        >>> e, size = IntegerEdit(u"", 10.0), (10,)
        Traceback (most recent call last):
            ...
        ValueError: default: Only 'str', 'int', 'long' or Decimal input allowed
        >>> e, size = IntegerEdit(u"", Decimal("10.0")), (10,)
        Traceback (most recent call last):
            ...
        ValueError: not an 'integer Decimal' instance
        r(   N;default: Only 'str', 'int', 'long' or Decimal input allowedz^[{}]+$zinvalid value: {} for base {}   r   z!not an 'integer Decimal' instancer)   )r	   )baser%   
isinstanceintstrr   
ValueErrorr   formatrematch
IGNORECASEas_tupler   r'   r   )r
   r   r   r,   valallowed_charsvalidation_rer   r   r   r   U   s(   7


zIntegerEdit.__init__c                 C   s   | j rtt| j | jS dS )z
        Return the numeric value of self.edit_text.

        >>> e, size = IntegerEdit(), (10,)
        >>> e.keypress(size, '5')
        >>> e.keypress(size, '1')
        >>> assert e.value() == 51
        N)r   r   r.   r,   )r
   r   r   r   value   s   	zIntegerEdit.value)r(   Nr)   r!   r"   r#   r$   r   r9   r&   r   r   r   r   r'   R   s    Sr'   c                       s.   e Zd ZdZ		d
 fdd	Zdd	 Z  ZS )	FloatEditzEdit widget for float values.r(   NT.c                    s   d| _ || _|dvrtd|d}|durG|dkrGt|tttfs'tdt|tr8t|r8t	| t|}|rCt
| d | _ t|}tt| | jdd | || dS )	a  
        caption -- caption markup
        default -- default edit value
        preserveSignificance -- return value has the same signif. as default
        decimalSeparator -- use '.' as separator by default, optionally a ','

        >>> FloatEdit(u"",  "1.065434")
        <FloatEdit selectable flow widget '1.065434' edit_pos=8>
        >>> e, size = FloatEdit(u"", "1.065434"), (10,)
        >>> e.keypress(size, 'home')
        >>> e.keypress(size, 'delete')
        >>> assert e.edit_text == ".065434"
        >>> e.keypress(size, 'end')
        >>> e.keypress(size, 'backspace')
        >>> assert e.edit_text == ".06543"
        >>> e, size = FloatEdit(), (10,)
        >>> e.keypress(size, '5')
        >>> e.keypress(size, '1')
        >>> e.keypress(size, '.')
        >>> e.keypress(size, '5')
        >>> e.keypress(size, '1')
        >>> assert e.value() == Decimal("51.51")
        >>> e, size = FloatEdit(decimalSeparator=":"), (10,)
        Traceback (most recent call last):
            ...
        ValueError: invalid decimalSeparator: :
        >>> e, size = FloatEdit(decimalSeparator=","), (10,)
        >>> e.keypress(size, '5')
        >>> e.keypress(size, '1')
        >>> e.keypress(size, ',')
        >>> e.keypress(size, '5')
        >>> e.keypress(size, '1')
        >>> assert e.edit_text == "51,51"
        >>> e, size = FloatEdit("", "3.1415", preserveSignificance=True), (10,)
        >>> e.keypress(size, 'end')
        >>> e.keypress(size, 'backspace')
        >>> e.keypress(size, 'backspace')
        >>> assert e.edit_text == "3.14"
        >>> assert e.value() == Decimal("3.1400")
        >>> e.keypress(size, '1')
        >>> e.keypress(size, '5')
        >>> e.keypress(size, '9')
        >>> assert e.value() == Decimal("3.1416")
        >>> e, size = FloatEdit("", ""), (10,)
        >>> assert e.value() is None
        >>> e, size = FloatEdit(u"", 10.0), (10,)
        Traceback (most recent call last):
            ...
        ValueError: default: Only 'str', 'int', 'long' or Decimal input allowed
        N)r<   ,zinvalid decimalSeparator: {}r(   r*   r+   r   r)   )significance_decimalSeparatorr0   r1   r-   r.   r/   r   r   floatabsr5   r   r;   r   r%   )r
   r   r   preserveSignificancedecimalSeparatorr6   r   r   r   r      s&   4zFloatEdit.__init__c                 C   s   | j rPd}| jrdj| jd}dd | j | jD dg dd \}}| jrEtt|| jkrEt|dtt|| j   }tt	|}t
|j|t|d	S d
S )z=
        Return the numeric value of self.edit_text.
        z	{ip}.{fp}z{{ip}}.{{fp:<0{sig}d}})sigc                 S   s   g | ]}|qS r   r   ).0vr   r   r   
<listcomp>  s    z#FloatEdit.value.<locals>.<listcomp>r   r+   r)   )ipfpN)r   r>   r1   splitr?   r   r/   r@   r.   roundr   )r
   fmtrH   rI   r   r   r   r9     s    zFloatEdit.value)r(   NTr<   r:   r   r   r   r   r;      s    Mr;   )urwidr   decimalr   r2   r   r'   r;   r   r   r   r   <module>   s   6e