o
     JAfO                     @   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
   &/usr/lib/python3.10/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widget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.r0   r2   r
   r
   r   r+   X   r3   zBaseSideBar.update_fontc                 C   r/   )=Update the sidebar text colors, usually after config changes.r0   r2   r
   r
   r   r,   \   r3   zBaseSideBar.update_colorsc                 C   r/   )z,Layout the widget, always using grid layout.r0   r2   r
   r
   r   r   `   r3   zBaseSideBar.gridc                 C   s   | j s|   d| _ d S d S )NT)r'   r   r2   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_forgetr2   r
   r
   r   hide_sidebari   s   

zBaseSideBar.hide_sidebarc                 O   r/   )z8Hook for vertical scrolling for sub-classes to override.r0   r-   argskwargsr
   r
   r   yscroll_eventn   r3   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;   r8   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	   rA   event_generaterG   )r-   rC   
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   )rF   rG   deltar@   )r	   rH   rG   rL   rB   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>rK   c                    s"   t j j|d} j| | d S )N)rI   )	functoolspartialrJ   r)   bind)rI   target_event_namehandlerr2   r
   r   bind_mouse_event   s   z1BaseSideBar.bind_events.<locals>.bind_mouse_event)            z<Button->z<ButtonRelease-z<Bz-Motion>)rQ   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 )NrY   )r   r   r	   r   rG   rC   )rd   last_yr-   rc   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   rE   )r	   rH   rG   re   )rf   r-   rc   r
   r   b1_mouseup_handler   s   z3BaseSideBar.bind_events.<locals>.b1_mouseup_handlerrh   c                    s    d u rd S | j  | j  d S NrG   re   )rd   rf   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afterrk   )auto_scrolling_after_idrd   rf   r-   text_auto_scrollr
   r   rr      s   
z1BaseSideBar.bind_events.<locals>.text_auto_scrollc                    s$    d u r| j jd d S d S )Nr   )rG   r)   rp   re   )rq   rf   r-   rr   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 rj   )r)   ro   re   )rq   r-   r
   r   b1_enter_handler  s   z1BaseSideBar.bind_events.<locals>.b1_enter_handlerz
<B1-Enter>)r?   r	   r)   rP   rD   rM   )	r-   rS   ZbuttonrI   rg   ri   rl   rs   rt   r
   )rq   rd   rf   r-   rc   rr   r   r*      s@   





		zBaseSideBar.bind_eventsN)__name__
__module____qualname____doc__r.   r(   r+   r,   r   r6   r7   r;   r?   rD   rJ   rM   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 rj   )r   r.   changed_callback)r-   rz   r
   r
   r   r.     s   

zEndLineDelegator.__init__Nc                 C   s$   | j ||| | t| j  d S rj   )delegater^   rz   r   )r-   r   charstagsr
   r
   r   r^     s   zEndLineDelegator.insertc                 C   s"   | j || | t| j  d S rj   )r{   deleterz   r   )r-   index1index2r
   r
   r   r~     s   zEndLineDelegator.deleterj   )ru   rv   rw   rx   r.   r^   r~   r
   r
   r
   r   ry   
  s
    
ry   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rp   )superr.   ry   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]   rT   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   r\   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   NSEWr2   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 )r5   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-   r\   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_movetor8   r
   r
   r   r;   g  s   zLineNumbers.yscroll_event)ru   rv   rw   rx   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   r{   r^   r   )r-   r   r|   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   r{   r~   r   )r-   r   r   r   r   r   r
   r
   r   r~     s   

z'WrappedLineHeightChangeDelegator.deleterj   )ru   rv   rw   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   topr{   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   r2   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)   rP   r   ZisAquaTkcontext_menu_eventr2   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tearoffrZ   r[   c                    s    fddS )Nc                      s   j  S rj   )r	   rH   r
   )	eventnamer-   r
   r   <lambda>  s    z@ShellSidebar.context_menu_event.<locals>.mkcmd.<locals>.<lambda>r
   r   r2   r   r   mkcmd  s   z.ShellSidebar.context_menu_event.<locals>.mkcmdZCopyz<<copy>>Znormal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-   rC   ZrmenuZhas_selectionr   r
   r2   r   r     s   

zShellSidebar.context_menu_eventc                 C   s   | j jddtjddd d S )Nr]   r   rT   )r   r   r   r   r   )r   r   r   r   r2   r
   r
   r   r     s   zShellSidebar.gridc                 C   s   | j r	|   d S d S rj   )r'   r   r2   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...rT   r   )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lineinforG   Zprev_newline_tagnamespromptr`   r
   r
   r   r     s.   


zShellSidebar.update_sidebarc                 O   s   |    dS )r<   r@   )r   r8   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 )r4   r   r   )r   c                 3   s    | ]}  |V  qd S rj   )Zmeasure).0charZtk_fontr
   r   	<genexpr>  s    z+ShellSidebar.update_font.<locals>.<genexpr>)rX   r   rU   rV   )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 )r5   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)ru   rv   rw   rx   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   r[   r   c                 s   s    | ]}d | V  qdS )ra   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   r6   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_sidebarrT   F)	verbosityexit)run)rx   
contextlibrN   r   tkinterr   Ztkinter.fontr   Zidlelib.configr   Zidlelib.delegatorr   Zidlelibr   r   r   r   r   contextmanagerr!   r"   ry   r   r   r   r   ru   Zunittestr   Zidlelib.idle_test.htestr   r
   r
   r
   r   <module>   s8    
 GP)p