B
    nôb\³G  ã               @   s  d Z ddlmZ ddlZddlmZ ddlmZm	Z	m
Z
mZmZmZmZ ddlmZ ddlmZmZmZmZmZmZmZ ddlmZ ddlmZ dd	lmZmZm Z  dd
l!m"Z# ddl$m%Z% ddl&m'Z'm(Z(m)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S )zTabs widgeté    N)ÚPYQT5)Ú
QByteArrayÚQEventÚ	QMimeDataÚQPointÚQtÚSignalÚSlot)ÚQDrag)ÚQApplicationÚQHBoxLayoutÚQMenuÚQTabBarÚ
QTabWidgetÚQWidgetÚ	QLineEdit)Ú_)Úconfig_shortcut)ÚPY2Úto_binary_stringÚto_text_string)Úicon_manager)Úget_common_path)Úadd_actionsÚcreate_actionÚcreate_toolbuttonc               @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚEditTabNamePopupz)Popup on top of the tab to edit its name.c             C   sœ   |dk	r|n|   ¡ | _|| _|| _d| _tj| dd | j | j	¡ |  
| ¡ trl|  tjtjB tjB ¡ n|  tjtjB ¡ |  d¡ |  dddd¡ dS )z)Popup on top of the tab to edit its name.N)ÚparentFé	   r   )r   ÚmainÚ
split_charÚsplit_indexÚ	tab_indexr   Ú__init__ZeditingFinishedÚconnectÚedit_finishedZinstallEventFilterr   ZsetWindowFlagsr   ZPopupZFramelessWindowHintZNoDropShadowWindowHintZsetFrameZsetTextMargins)Úselfr   r    r!   © r'   ú2lib/python3.7/site-packages/spyder/widgets/tabs.pyr#   '   s     



zEditTabNamePopup.__init__c             C   s`   |  ¡ tjkr |  ¡  | ¡ ¡r<|  ¡ tjkrR| ¡ tj	krR|  
¡  |  d¡ dS t | ||¡S )z2Catch clicks outside the object and ESC key press.FT)Útyper   ZMouseButtonPressZgeometryÚcontainsÚ	globalPosZKeyPressÚkeyr   Z
Key_EscapeÚhideÚsetFocusr   ÚeventFilter)r&   ÚwidgetÚeventr'   r'   r(   r/   M   s    
zEditTabNamePopup.eventFilterc             C   s¦   |   d¡ || _| j |¡}| dddd¡ |  | ¡ ¡ |  | j | 	¡ ¡¡ | j 
|¡}| dd¡}| jr€| | j¡| j }|  |¡ |  ¡  |  ¡ s¢|  ¡  dS )zActivate the edit tab.Té   éþÿÿÿéÿÿÿÿú&Ú N)r.   r"   r   ZtabRectZadjustZsetFixedSizeÚsizeZmoveZmapToGlobalZtopLeftÚtabTextÚreplacer    Úsplitr!   ZsetTextZ	selectAllZ	isVisibleÚshow)r&   ÚindexZrectÚtextr'   r'   r(   Úedit_tab[   s    

zEditTabNamePopup.edit_tabc             C   sL   |   ¡  t| jtƒrH| jdkrHt|  ¡ ƒ}| j | j|¡ | jj 	|¡ dS )zOn clean exit, update tab name.r   N)
r-   Ú
isinstancer"   Úintr   r=   r   Z
setTabTextÚsig_change_nameÚemit)r&   Ztab_textr'   r'   r(   r%   {   s
    zEditTabNamePopup.edit_finishedN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r#   r/   r>   r%   r'   r'   r'   r(   r   $   s
   & r   c               @   s^   e Zd ZdZeeefeeefƒZeeƒZddd„Z	dd„ Z
d	d
„ Zdd„ Zdd„ Zdd„ ZdS )ÚTabBarz*Tabs base class with drag and drop supportFr6   r   c             C   sr   t  | |¡ || _tjdkr&|  d¡ tƒ | _|  d¡ |  	d¡ |  
d¡ || _| jrht| ||ƒ| _nd | _d S )NÚdarwinz
plugin-tabT)r   r#   ÚancestorÚsysÚplatformÚsetObjectNamer   Ú_TabBar__drag_start_posZsetAcceptDropsÚsetUsesScrollButtonsZ
setMovableÚrename_tabsr   Útab_name_editor)r&   r   rI   rO   r    r!   r'   r'   r(   r#   Œ   s    





zTabBar.__init__c             C   s,   |  ¡ tjkrt| ¡ ƒ| _t | |¡ dS )zReimplement Qt methodN)Úbuttonr   Ú
LeftButtonr   ÚposrM   r   ÚmousePressEvent)r&   r1   r'   r'   r(   rT   ¤   s    zTabBar.mousePressEventc             C   s   t  | |¡ dS )zOverride Qt methodN)r   ÚmouseMoveEvent)r&   r1   r'   r'   r(   rU   ª   s    zTabBar.mouseMoveEventc             C   sL   |  ¡ }t| ¡ ƒ}d|kr<t| d¡ƒt| jƒkr<| ¡  t 	| |¡ dS )zOverride Qt methodz	parent-idN)
ÚmimeDataÚlistÚformatsr@   ÚdataÚidrI   ÚacceptProposedActionr   ÚdragEnterEvent)r&   r1   rV   rX   r'   r'   r(   r\   Å   s    zTabBar.dragEnterEventc             C   sª   |  ¡ }t| d¡ƒ}|  | ¡ ¡}|dkr4|  ¡ }t| d¡ƒt| ƒkr|t| d¡ƒ}| jt	ttf  
|||¡ | ¡  n||krš| j 
||¡ | ¡  t | |¡ dS )zOverride Qt methodzsource-indexr4   z	tabbar-idztabwidget-idN)rV   r@   rY   ÚtabAtrS   ÚcountrZ   r   Úsig_move_tabÚstrrB   r[   r   Ú	dropEvent)r&   r1   rV   Ú
index_fromÚindex_toÚtabwidget_fromr'   r'   r(   ra   Ð   s    
zTabBar.dropEventc             C   sR   | j dkrB| ¡ t tj¡krB|  | ¡ ¡}|dkrN| j |¡ nt	 
| |¡ dS )z2Override Qt method to trigger the tab name editor.Tr   N)rO   Zbuttonsr   ZMouseButtonsrR   r]   rS   rP   r>   r   ÚmouseDoubleClickEvent)r&   r1   r<   r'   r'   r(   re   æ   s    
zTabBar.mouseDoubleClickEventN)Fr6   r   )rC   rD   rE   rF   r   r@   r`   r_   rA   r#   rT   rU   r\   ra   re   r'   r'   r'   r(   rG   ‡   s    
rG   c               @   sj   e Zd ZdZeeƒZddd„Zdd„ Zdd	„ Z	e
jfd
d„Zdd„ Zdd„ Zdd„ Zddd„Zdd„ ZdS )ÚBaseTabsz.TabWidget with context menu and corner widgetsNFc             C   sþ   t  | |¡ |  d¡ tjdkr*|  d¡ i | _|| _|d krZt| ƒ| _	|r`t
| j	|ƒ n|| _	|d krli }| tjg ¡ | tjg ¡ t| t d¡tdƒd| _t| ƒ| _| j | j¡ | j | jj¡ | jj | j¡ |tj  | jg7  < |  |¡ d S )NTrH   z
plugin-tabZ
browse_tabzBrowse tabs)ÚiconÚtip)r   r#   rN   rJ   rK   rL   Úcorner_widgetsÚmenu_use_tooltipsr   Úmenur   Ú
setdefaultr   ÚTopLeftCornerÚTopRightCornerr   Úimarg   r   Zbrowse_buttonÚbrowse_tabs_menuZsetMenuZsetPopupModeZInstantPopupZaboutToShowr$   Úupdate_browse_tabs_menuÚset_corner_widgets)r&   r   Úactionsrk   ri   rj   r'   r'   r(   r#   ø   s0    




zBaseTabs.__init__c          	      s  ˆ j  ¡  g }g }x\tˆ  ¡ ƒD ]L}ˆ jr:tˆ  |¡ƒ}ntˆ  |¡ƒ}| |¡ t	 
|¡r | t	 |¡¡ q W d}t|ƒt|ƒkr²t|ƒ}|dkršd}nt|ƒd }|dkr²d}xdt|ƒD ]X\}}tˆ ||d… ˆ  |¡|f‡ fdd„	ˆ  |¡d}| |ˆ  ¡ k¡ ˆ j  |¡ q¼W dS )zUpdate browse tabs menuNr2   é   c                s
   ˆ   |¡S )N)ÚsetCurrentIndex)Ústater<   )r&   r'   r(   Ú<lambda>9  s    z2BaseTabs.update_browse_tabs_menu.<locals>.<lambda>)rg   Ztoggledrh   )rp   ÚclearÚranger^   rj   r   Ú
tabToolTipr8   ÚappendÚospÚisfileÚdirnameÚlenr   Ú	enumerater   ÚtabIconZ
setCheckedÚcurrentIndexZ	addAction)r&   ÚnamesZdirnamesr<   r=   ÚoffsetÚcommonZ
tab_actionr'   )r&   r(   rq     s2    


z BaseTabs.update_browse_tabs_menuc             C   sÖ   t |tƒst‚tdd„ |D ƒƒs$t‚| j |¡ x t| j ¡ ƒD ]Ž\}}tƒ }| 	¡  |  
|¡}|rl| ¡  |  ||¡ tƒ }| dddd¡ x,|D ]$}t |tƒr®| |¡ q”| |¡ q”W | |¡ | ¡  q@W dS )zà
        Set tabs corner widgets
        corner_widgets: dictionary of (corner, widgets)
        corner: Qt.TopLeftCorner or Qt.TopRightCorner
        widgets: list of widgets (may contains integers to add spacings)
        c             s   s   | ]}|t jt jfkV  qd S )N)r   rm   rn   )Ú.0r,   r'   r'   r(   ú	<genexpr>G  s   z.BaseTabs.set_corner_widgets.<locals>.<genexpr>r   N)r?   ÚdictÚAssertionErrorÚallri   ÚupdaterW   Úitemsr   r-   ZcornerWidgetÚcloseÚsetCornerWidgetr   ZsetContentsMarginsr@   Z
addSpacingZ	addWidgetZ	setLayoutr;   )r&   ri   ÚcornerÚwidgetsZcwidgetZprev_widgetZclayoutr0   r'   r'   r(   rr   ?  s&    



zBaseTabs.set_corner_widgetsc             C   s    |   || j |g ¡| i¡ d S )N)rr   ri   Úget)r&   r   r   r'   r'   r(   Úadd_corner_widgets[  s    zBaseTabs.add_corner_widgetsc             C   s2   |   |  ¡  | ¡ ¡¡ | jr.| j | ¡ ¡ dS )zOverride Qt methodN)ru   ÚtabBarr]   rS   rk   Zpopupr+   )r&   r1   r'   r'   r(   ÚcontextMenuEvent_  s    zBaseTabs.contextMenuEventc             C   sP   |  ¡ tjkr@|  ¡  | ¡ ¡}|dkr@| j |¡ | ¡  dS t	 
| |¡ dS )zOverride Qt methodr   N)rQ   r   Z	MidButtonr“   r]   rS   Úsig_close_tabrB   Zacceptr   rT   )r&   r1   r<   r'   r'   r(   rT   e  s    zBaseTabs.mousePressEventc             C   s¸   |  ¡ tj@ }| ¡ }d}|r¤|  ¡ dkr¤|  ¡ }|tjkrl|dkrT|  |d ¡ n|  |  ¡ d ¡ d}n8|tjkr¤||  ¡ d k r–|  |d ¡ n
|  d¡ d}|s´t	 
| |¡ dS )zOverride Qt methodFr   r2   TN)Z	modifiersr   ZControlModifierr,   r^   r‚   Z
Key_PageUpru   ZKey_PageDownr   ÚkeyPressEvent)r&   r1   Zctrlr,   Zhandledr<   r'   r'   r(   r–   o  s"    


zBaseTabs.keyPressEventr2   c             C   sb   |dkr&|   ¡ |  ¡ d kr&|d }n.|dk rH|   ¡ dkrH|  ¡ | }n|   ¡ | }|  |¡ dS )zCtrl+Tabr   r2   N)r‚   r^   ru   )r&   Zdeltar<   r'   r'   r(   Útab_navigate…  s    
zBaseTabs.tab_navigatec          	   C   sz   |dk	}|r| j  |¡ yt | |¡ | j |¡ W n@ tk
rt   t| |t d¡t	dƒd}|  
|rj|nd¡ Y nX dS )zASetting Tabs close function
        None -> tabs are not closableNZ	fileclosezClose current tab)Z	triggeredrg   rh   )r•   r$   r   ZsetTabsClosableZtabCloseRequestedÚAttributeErrorr   ro   rg   r   rŽ   )r&   Úfuncrv   Zclose_buttonr'   r'   r(   Úset_close_function  s    zBaseTabs.set_close_function)NNNF)r2   )rC   rD   rE   rF   r   r@   r•   r#   rq   rr   r   rn   r’   r”   rT   r–   r—   rš   r'   r'   r'   r(   rf   ô   s    
"$


rf   c               @   s^   e Zd ZdZeeeƒZeƒ ZeeeeeƒZ	ddd„Z
eeeƒdd	„ ƒZeeeeƒd
d„ ƒZdS )ÚTabsz>BaseTabs widget with movable tabs and tab navigation shortcutsNFr6   r   c	       
         sº   t  ˆ |||||¡ tˆ ||||d}	|	j ˆ j¡ |	jtttf  ˆ j¡ ˆ  	|	¡ t
‡ fdd„dd|d t
‡ fdd„dd|d t
‡ fd	d„dd
|d t
‡ fdd„dd|d d S )N)rO   r    r!   c                  s
   ˆ   d¡S )Nr2   )r—   r'   )r&   r'   r(   rw   ·  s    zTabs.__init__.<locals>.<lambda>Zeditorzgo to next file)ÚcontextÚnamer   c                  s
   ˆ   d¡S )Nr4   )r—   r'   )r&   r'   r(   rw   ¹  s    zgo to previous filec                  s   ˆ j  ˆ  ¡ ¡S )N)r•   rB   r‚   r'   )r&   r'   r(   rw   »  s    zclose file 1c                  s   ˆ j  ˆ  ¡ ¡S )N)r•   rB   r‚   r'   )r&   r'   r(   rw   ½  s    zclose file 2)rf   r#   rG   r_   r$   Úmove_tabr`   r@   Úmove_tab_from_another_tabwidgetZ	setTabBarr   )
r&   r   rs   rk   ri   rj   rO   r    r!   Ztab_barr'   )r&   r(   r#   ¨  s$    


zTabs.__init__c             C   s€   | j  ||¡ |  |¡|  |¡ }}|  |¡|  |¡ }}|  ¡ }|  |¡ |  ||||¡ |  	||¡ |  
|¡ | j ¡  dS )zMove tab inside a tabwidgetN)Ú	move_datarB   rz   r8   r   r0   ZcurrentWidgetZ	removeTabZ	insertTabZsetTabToolTipZsetCurrentWidgetÚmove_tab_finished)r&   rb   rc   rh   r=   rg   r0   Zcurrent_widgetr'   r'   r(   rž   À  s    

zTabs.move_tabc             C   s   | j  |tt| ƒƒ||¡ dS )z$Move tab from a tabwidget to anotherN)r_   rB   r   rZ   )r&   rd   rb   rc   r'   r'   r(   rŸ   Ð  s    	z$Tabs.move_tab_from_another_tabwidget)NNNFFr6   r   )rC   rD   rE   rF   r   r@   r    r¡   r`   r_   r#   r	   rž   rŸ   r'   r'   r'   r(   r›   ¡  s   
   
r›   ).rF   Úos.pathÚpathr|   rJ   Zqtpyr   Zqtpy.QtCorer   r   r   r   r   r   r	   Z
qtpy.QtGuir
   Zqtpy.QtWidgetsr   r   r   r   r   r   r   Zspyder.config.baser   Zspyder.config.guir   Zspyder.py3compatr   r   r   Zspyder.utilsr   ro   Zspyder.utils.miscr   Zspyder.utils.qthelpersr   r   r   r   rG   rf   r›   r'   r'   r'   r(   Ú<module>   s"   $$cm .