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