o
    QEcO                     @   s  d Z ddlZddlZddlZddlZddlmZ ddlm	Z	 ddl
mZ ddlmZ dd Zd	d
 Zdd Zdd Zejdd ZG dd dZG dd deZG dd deZG dd deZG dd deZdd ZedkrddlmZ edd d!d" dd#lmZ ee dS dS )$zLine numbering implementation for IDLE as an extension.
Includes BaseSideBar which can be extended for other sidebar based extensions
    N)Font)idleConf)	Delegator)macosxc                 C   s   |  |}|rtt|S dS )z7Return the line number of an index in a Tk text widget.N)indexintfloat)textr   Z
text_index r
   Lib\idlelib\sidebar.py
get_lineno   s   
r   c                 C   s
   t | dS )z7Return the number of the last line in a Tk text widget.zend-1c)r   r	   r
   r
   r   get_end_linenumber   s   
r   c                 C   s*   |  | d| dd}|r|d S dS )z@Display height, in lines, of a logical line in a Tk text widget.z
 linestartz lineendZdisplaylinesr   )count)r	   r   resr
   r
   r   get_displaylines   s
   r   c                 C   s   |   }|dkr|  }n|dkr|  }ntd| tt| jj|d | d| dg}tt| jj|d | d| dg}||fS )z;Get the total padding of a Tk widget, including its border.packgridzUnsupported geometry manager: padxZborderpady)	Zwinfo_managerZ	pack_infoZ	grid_info
ValueErrorsummaptkZgetintZcget)ZwidgetZmanagerinfor   r   r
   r
   r   get_widget_padding!   s"   



r   c              	   c   s<    | j tjd zd V  W | j tjd d S | j tjd w )Nstate)	configurer   ZNORMALDISABLEDr   r
   r
   r   temp_enable_text_widget;   s
   "r    c                   @   sx   e Zd Z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dd Zdd Zdd ZdS )BaseSideBarz%A base class for sidebars using Text.c                 C   sB   || _ |j| _|j| _d| _|  | _|   |   | 	  d S NF)
editwin
text_frameparentr	   is_showninit_widgetsmain_widgetbind_eventsupdate_fontupdate_colors)selfr#   r
   r
   r   __init__F   s   
zBaseSideBar.__init__c                 C      t )z<Initialize the sidebar's widgets, returning the main widget.NotImplementedErrorr,   r
   r
   r   r'   T      zBaseSideBar.init_widgetsc                 C   r.   );Update the sidebar text font, usually after config changes.r/   r1   r
   r
   r   r*   X   r2   zBaseSideBar.update_fontc                 C   r.   )=Update the sidebar text colors, usually after config changes.r/   r1   r
   r
   r   r+   \   r2   zBaseSideBar.update_colorsc                 C   r.   )z,Layout the widget, always using grid layout.r/   r1   r
   r
   r   r   `   r2   zBaseSideBar.gridc                 C   s   | j s|   d| _ d S d S )NT)r&   r   r1   r
   r
   r   show_sidebard   s   
zBaseSideBar.show_sidebarc                 C   s   | j r| j  d| _ d S d S r"   )r&   r(   Zgrid_forgetr1   r
   r
   r   hide_sidebari   s   

zBaseSideBar.hide_sidebarc                 O   r.   )z8Hook for vertical scrolling for sub-classes to override.r/   r,   argskwargsr
   r
   r   yscroll_eventn   r2   zBaseSideBar.yscroll_eventc                 O   s   | j jj|  | j|i |S )mRedirect vertical scrolling to the main editor text widget.

        The scroll bar is also updated.
        )r#   vbarsetr:   r7   r
   r
   r   redirect_yscroll_eventr   s   z"BaseSideBar.redirect_yscroll_eventc                 C   s   | j   dS )z8Redirect focus-in events to the main editor text widget.break)r	   	focus_setr,   eventr
   r
   r   redirect_focusin_eventz   s   
z"BaseSideBar.redirect_focusin_eventc                 C   s"   | j   | j j|d|jd dS )z<Redirect mouse button events to the main editor text widget.r   xyr?   )r	   r@   event_generaterF   )r,   rB   
event_namer
   r
   r   redirect_mousebutton_event   s   
z&BaseSideBar.redirect_mousebutton_eventc                 C   s   | j jdd|j|jd dS )z7Redirect mouse wheel events to the editwin text widget.<MouseWheel>r   )rE   rF   deltar?   )r	   rG   rF   rK   rA   r
   r
   r   redirect_mousewheel_event   s   
z%BaseSideBar.redirect_mousewheel_eventc           	         sp  j jd< jdj jdj fdd}dD ]5}d| dd	| dd
| dfD ]}|||d q1d| dd| dfD ]}||d| dd qFqd d d  fddfdd}jd| fdd}jd| fdd}jd|  fdd fdd}jd|  fdd }jd!| d S )"NZyscrollcommandz	<FocusIn>rJ   c                    s"   t j j|d} j| | d S )N)rH   )	functoolspartialrI   r(   bind)rH   target_event_nameZhandlerr1   r
   r   bind_mouse_event   s   z1BaseSideBar.bind_events.<locals>.bind_mouse_event)            z<Button->z<ButtonRelease-z<Bz-Motion>)rP   z<Double-Button-z<Triple-Button-c                    sz   t  jd|  }t|g\}} jddd  jd| d|d  d  jd||kr3|n|d  d dS )	z6Helper function for drag and selection event handlers.@0,sel1.0endz.0   insertN)r   r	   sortedZ
tag_removeZtag_addZmark_set)Zy_coordlinenoab)r,   
start_liner
   r   %drag_update_selection_and_insert_mark   s    zFBaseSideBar.bind_events.<locals>.drag_update_selection_and_insert_markc                    s0   t tjd| j | j | j d S )NrW   )r   r   r	   r   rF   rB   )rb   last_yr,   ra   r
   r   b1_mousedown_handler   s   z5BaseSideBar.bind_events.<locals>.b1_mousedown_handlerz
<Button-1>c                    s    d d  j jdd| jd d S )N<ButtonRelease-1>r   rD   )r	   rG   rF   rc   )rd   r,   ra   r
   r   b1_mouseup_handler   s   z3BaseSideBar.bind_events.<locals>.b1_mouseup_handlerrf   c                    s    d u rd S | j  | j  d S NrF   rc   )rb   rd   r
   r   b1_drag_handler   s   z0BaseSideBar.bind_events.<locals>.b1_drag_handlerz<B1-Motion>c                     s   } | du rj   d dS | dk r"jd|  d |  n| j  kr;jd|  j   d |  j d dS )z6Mimic Text auto-scrolling when dragging outside of it.Nr   Zpixelsr[   2   )r(   after_cancelr	   Zyview_scrollZwinfo_heightafterri   )auto_scrolling_after_idrb   rd   r,   text_auto_scrollr
   r   rp      s   
z1BaseSideBar.bind_events.<locals>.text_auto_scrollc                    s$    d u r| j jd d S d S )Nr   )rF   r(   rn   rc   )ro   rd   r,   rp   r
   r   b1_leave_handler   s
   z1BaseSideBar.bind_events.<locals>.b1_leave_handlerz
<B1-Leave>c                    s     d urj   d  d S d S rh   )r(   rm   rc   )ro   r,   r
   r   b1_enter_handler  s   z1BaseSideBar.bind_events.<locals>.b1_enter_handlerz
<B1-Enter>)r>   r	   r(   rO   rC   rL   )	r,   rQ   ZbuttonrH   re   rg   rj   rq   rr   r
   )ro   rb   rd   r,   ra   rp   r   r)      s@   





		zBaseSideBar.bind_eventsN)__name__
__module____qualname____doc__r-   r'   r*   r+   r   r5   r6   r:   r>   rC   rI   rL   r)   r
   r
   r
   r   r!   D   s    r!   c                   @   s,   e Zd ZdZdd Zd	ddZd	ddZdS )
EndLineDelegatorz}Generate callbacks with the current end line number.

    The provided callback is called after every insert and delete.
    c                 C   s   t |  || _d S rh   )r   r-   changed_callback)r,   rx   r
   r
   r   r-     s   

zEndLineDelegator.__init__Nc                 C   s$   | j ||| | t| j  d S rh   )delegater\   rx   r   )r,   r   charstagsr
   r
   r   r\     s   zEndLineDelegator.insertc                 C   s"   | j || | t| j  d S rh   )ry   deleterx   r   )r,   index1index2r
   r
   r   r|     s   zEndLineDelegator.deleterh   )rs   rt   ru   rv   r-   r\   r|   r
   r
   r
   r   rw   
  s
    
rw   c                       sP   e Zd ZdZ fddZdd Zdd Zdd	 Zd
d Zdd Z	dd Z
  ZS )LineNumbersz(Line numbers support for editor windows.c                    s0   t  | t| j}| jjj|| jjd d S )Nrn   )superr-   rw   update_sidebar_textr#   perinsertfilterafterZundo)r,   r#   Zend_line_delegator	__class__r
   r   r-     s
   


zLineNumbers.__init__c              	   C   s   t | j\}}tj| jdtjd|ddd| _| jjtjd d| _	t
| jd | _t| j | jddd	 W d    n1 sAw   Y  | jjd
d
d | jjd	tjd t| j}| | | jS )Nr[   rR   r   )widthwrapr   r   borderwidthhighlightthicknessr   r   r\   1
linenumberF)	takefocusZexportselection)Zjustify)r   r	   r   Textr%   NONEsidebar_textconfigr   prev_endtype_sidebar_width_typer    r\   Z
tag_configZRIGHTr   r   )r,   Z_padxr   rZ   r
   r
   r   r'   '  s    

zLineNumbers.init_widgetsc                 C   s   | j jddtjd d S )Nr[   r   rowcolumnsticky)r   r   r   NSEWr1   r
   r
   r   r   :  s   zLineNumbers.gridc                 C   s   t | jdd}|| jd< d S )NmainEditorWindowfont)r   GetFontr	   r   )r,   r   r
   r
   r   r*   =  s   zLineNumbers.update_fontc                 C   s:   t t  d}|d }|d }| jj|||||d dS )r4   r   
foreground
background)ZfgbgZselectforegroundZselectbackgroundZinactiveselectbackgroundN)r   GetHighlightCurrentThemer   r   )r,   colorsr   r   r
   r
   r   r+   A  s   
zLineNumbers.update_colorsc                 C   s   || j krdS tt|tt| j  }|r+tt| jd }|| }| || jd< t| j7 || j krTdt	
dgttt| j d |d }| jd|d n| j|d  dd W d   n1 sjw   Y  || _ dS )	z
        Perform the following action:
        Each line sidebar_text contains the linenumber for that line
        Synchronize with editwin.text so that both sidebar_text and
        editwin.text contain the same number of linesNr   
 r[   zend -1cr   z.0 -1c)r   lenstrr   r   r   r   r    join	itertoolschainr   ranger\   r|   )r,   rZ   Zwidth_differenceZ	cur_widthZ	new_widthZnew_textr
   r
   r   r   L  s$   



zLineNumbers.update_sidebar_textc                 O   s   | j |d  dS )Nr   r?   )r   Zyview_movetor7   r
   r
   r   r:   g  s   zLineNumbers.yscroll_event)rs   rt   ru   rv   r-   r'   r   r*   r+   r   r:   __classcell__r
   r
   r   r   r     s    	r   c                   @   s(   e Zd Zdd ZdddZdddZdS )	 WrappedLineHeightChangeDelegatorc                 C   s   t |  || _dS )z
        callback - Callable, will be called when an insert, delete or replace
                   action on the text widget may require updating the shell
                   sidebar.
        N)r   r-   callback)r,   r   r
   r
   r   r-   m  s   

z)WrappedLineHeightChangeDelegator.__init__Nc                 C   sL   d|v}|rt | |}| j||| |r t | |}||kr d S |   d S )Nr   )r   ry   r\   r   )r,   r   rz   r{   is_single_linebefore_displaylinesafter_displaylinesr
   r
   r   r\   v  s   

z'WrappedLineHeightChangeDelegator.insertc                 C   sf   |d u r|d }t | |t | |k}|rt| |}| j|| |r-t| |}||kr-d S |   d S )Nz+1c)r   r   ry   r|   r   )r,   r}   r~   r   r   r   r
   r
   r   r|     s   

z'WrappedLineHeightChangeDelegator.deleterh   )rs   rt   ru   r-   r\   r|   r
   r
   r
   r   r   l  s    
	r   c                       sl   e Zd ZdZ fddZdd Z fddZdd	 Zd
d Zdd Z	dd Z
dd Zdd Zdd Z  ZS )ShellSidebarz0Sidebar for the PyShell window, for prompts etc.c                    sz   d | _ i | _t | t| j}| jjj}|j	| j
ur/|j	| jjjur/|j	}|j	| jjjus$| jjj||d d| _d S )Nr   T)canvasline_promptsr   r-   r   change_callbackr#   r   topry   r	   Zbottomr   r&   )r,   r#   Zchange_delegatordr   r
   r   r-     s   

zShellSidebar.__init__c                 C   s.   t j| jddddd| _|   |   | jS )N   r   F)r   r   r   r   )r   ZCanvasr%   r   update_sidebarr   r1   r
   r
   r   r'     s   
zShellSidebar.init_widgetsc                    s*   t    | jt rdnd| j d S )Nz
<Button-2>z
<Button-3>)r   r)   r(   rO   r   ZisAquaTkcontext_menu_eventr1   r   r
   r   r)     s
   
zShellSidebar.bind_eventsc                    sz   t j jdd}t jdd} fdd}|jd|d|r!d	nd
d |jd|d|r/d	nd
d ||j|j	 dS )Nr   )ZtearoffrX   rY   c                    s    fddS )Nc                      s   j  S rh   )r	   rG   r
   )	eventnamer,   r
   r   <lambda>  s    z@ShellSidebar.context_menu_event.<locals>.mkcmd.<locals>.<lambda>r
   r   r1   r   r   mkcmd  s   z.ShellSidebar.context_menu_event.<locals>.mkcmdZCopyz<<copy>>ZnormalZdisabled)ZlabelZcommandr   zCopy with promptsz<<copy-with-prompts>>r?   )
r   ZMenur(   boolr	   Ztag_nextrangeZadd_commandZtk_popupZx_rootZy_root)r,   rB   ZrmenuZhas_selectionr   r
   r1   r   r     s   

zShellSidebar.context_menu_eventc                 C   s   | j jddtjddd d S )Nr[   r   rR   )r   r   r   r   r   )r   r   r   r   r1   r
   r
   r   r     s   zShellSidebar.gridc                 C   s   | j r	|   d S d S rh   )r&   r   r1   r
   r
   r   r     s   zShellSidebar.change_callbackc                 C   s   | j }|j}| j}i  }| _|tj |d}|ddd dkr+|| d}|	| }d ur{|d }|| d}d|v rEdnd	|v rKd
nd }	|	rh|j
d|tj|	| j| jd d t||}
|	||
< || d}|	| }d us4d S d S )Nz@0,0.r[   0z+1line linestartz linestart -1cconsolez>>>stdinz...rR   r   )Zanchorr	   r   fillz+1line)r	   Z	tag_namesr   r   r|   r   ZALLr   splitZ	dlineinfoZcreate_textZNWr   r   r   )r,   r	   Ztext_tagnamesr   r   r   ZlineinforF   Zprev_newline_tagnamespromptr^   r
   r
   r   r     s.   


zShellSidebar.update_sidebarc                 O   s   |    dS )r;   r?   )r   r7   r
   r
   r   r:     s   zShellSidebar.yscroll_eventc                    s\   t | jdd}t| j|d t fdddD }| jj|d d d	 || _|   d
S )r3   r   r   )r   c                 3   s    | ]}  |V  qd S rh   )Zmeasure).0charZtk_fontr
   r   	<genexpr>  s    z+ShellSidebar.update_font.<locals>.<genexpr>)rV   r   rS   rT   )r   N)	r   r   r	   r   maxr   r   r   r   )r,   r   Z
char_widthr
   r   r   r*     s   zShellSidebar.update_fontc                 C   sT   t t  d}t t  d}|d }|d }||f| _| jj|d |   dS )r4   r   r   r   r   )r   N)r   r   r   r   r   r   r   )r,   Zlinenumbers_colorsZprompt_colorsr   r   r
   r
   r   r+     s   
zShellSidebar.update_colors)rs   rt   ru   rv   r-   r'   r)   r   r   r   r   r:   r*   r+   r   r
   r
   r   r   r     s    		r   c              	   C   s   ddl m} t| }t|}|jtjtjdd |jddd |j	ddd t
|dd}tj|d	d
tj|d}|jddtjd ||}t||_t|}|  |dddd tddD  d S )Nr   )Dummy_editwinT)Zsider   expandr[   )Zweightr   r   P      )r   Zheightr   r   r   rY   r   c                 s   s    | ]}d | V  qdS )r_   Nr
   )r   ir
   r
   r   r     s    z._linenumbers_drag_scrolling.<locals>.<genexpr>e   )Zidlelib.idle_test.test_sidebarr   r   ZToplevelZFramer   ZLEFTZBOTHZrowconfigureZcolumnconfigurer   r   r   r   r   r   Z	Scrollbarr<   r   r5   r\   r   r   )r%   r   Ztoplevelr$   r   r	   r#   Zlinenumbersr
   r
   r   _linenumbers_drag_scrolling  s   

&r   __main__)r   zidlelib.idle_test.test_sidebarrR   F)	verbosityexit)run)rv   
contextlibrM   r   Ztkinterr   Ztkinter.fontr   Zidlelib.configr   Zidlelib.delegatorr   Zidlelibr   r   r   r   r   contextmanagerr    r!   rw   r   r   r   r   rs   Zunittestr   Zidlelib.idle_test.htestr   r
   r
   r
   r   <module>   s8    
 GP)p