B
    nôb\N  ã               @   sZ  d Z ddlZddlmZ ddlZddlZddlmZm	Z	 ddl
mZmZmZmZmZmZmZmZmZ ddlmZmZmZmZ ddlmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$ ddl%m&Z&m'Z' ddl(m)Z) dd	l*m+Z+ dd
l*m,Z- ddl.m/Z/m0Z0 ddl1m2Z2m3Z3 dNdd„Z4G dd„ deƒZ5dOdd„Z6dd„ Z7da8dd„ Z9dd„ Z:dd„ Z;dPdd„Z<d d!„ Z=d"d#„ Z>d$d%„ Z?dQd'd(„Z@dRd)d*„ZAd+d,„ ZBdddddddejCfd-d.„ZDd/d0„ ZEdSd1d2„ZFd3d4„ ZGd5d6„ ZHdTd7d8„ZId9d:„ ZJdUd;d<„ZKg fd=d>„ZLG d?d@„ d@eƒZMdAdB„ ZNG dCdD„ dDeƒZOG dEdF„ dFe$ƒZPdGdH„ ZQdIdJ„ ZRdVdKdL„ZSdZTeUdMkrVeQƒ  dS )WzQt utilitiesé    N)Úto_qvariantÚfrom_qvariant)	ÚQEventÚQLibraryInfoÚQLocaleÚQObjectÚQtÚQTimerÚQTranslatorÚSignalÚSlot)ÚQIconÚ	QKeyEventÚQKeySequenceÚQPixmap)ÚQActionÚQApplicationÚQHBoxLayoutÚQLabelÚ	QLineEditÚQMenuÚQStyleÚQToolBarÚQToolButtonÚQVBoxLayoutÚQWidget)Úget_image_pathÚrunning_in_mac_app)Úget_shortcut)Úprograms)Úicon_manager)Úget_iconÚget_std_icon)Úis_text_stringÚto_text_stringúnot_found.pngc             C   s   t ƒ }| tt| |ƒƒ¡ |S )z#Return image inside a QLabel object)r   Ú	setPixmapr   r   )ÚnameÚdefaultÚlabel© r*   ú5lib/python3.7/site-packages/spyder/utils/qthelpers.pyÚget_image_label,   s    r,   c               @   s(   e Zd ZdZeeƒZdd„ Zdd„ ZdS )ÚMacApplicationz;Subclass to be able to open external files with our Mac appc             G   s   t j| f|žŽ  d S )N)r   Ú__init__)ÚselfÚargsr*   r*   r+   r.   7   s    zMacApplication.__init__c             C   s2   |  ¡ tjkr&t| ¡ ƒ}| j |¡ t | |¡S )N)	Útyper   ZFileOpenÚstrÚfileÚsig_open_external_fileÚemitr   Úevent)r/   r6   Úfnamer*   r*   r+   r6   :   s    zMacApplication.eventN)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r2   r4   r.   r6   r*   r*   r*   r+   r-   3   s   r-   Té   c             C   s~   t ƒ rt}nt}| ¡ }|dkr4|dgƒ}| d¡ | r@t|ƒ tj dd¡}|dk	rzt	|ƒ}|j
 |j¡ | |d ¡ |S )z³
    Return QApplication instance
    Creates it if it doesn't already exist
    
    test_time: Time to maintain open the application when testing. It's given
    in seconds
    NZSpyderZTEST_CI_WIDGETSiè  )r   r-   r   ÚinstanceZsetApplicationNameÚinstall_translatorÚosÚenvironÚgetr	   ZtimeoutÚconnectÚquitÚstart)Ú	translateZ	test_timeZSpyderApplicationÚappZtest_ciZtimer_shutdownr*   r*   r+   ÚqapplicationA   s    

rG   c             C   s4   t jdkr(t d| ¡rd|  S d|  S nd|  S dS )zBSelect the right file uri scheme according to the operating systemÚntz
^[a-zA-Z]:zfile:///zfile://N)r?   r'   ÚreÚsearch)r7   r*   r*   r+   Úfile_uria   s
    

rK   c             C   sH   t dkr2tƒ }| dt ¡  ¡  t tj¡¡r2|a t dk	rD|  	t ¡ dS )z2Install Qt translator to the QApplication instanceNZqt_)
ÚQT_TRANSLATORr
   Úloadr   Úsystemr'   r   ÚlocationZTranslationsPathZinstallTranslator)ZqappZqt_translatorr*   r*   r+   r>   o   s    r>   c             C   s   t t| ƒ}tt |¡d tƒS )zReturn keybindingr   )Úgetattrr   r   ZkeyBindingsr2   )ÚattrZksr*   r*   r+   Ú
keybinding{   s    
rR   c             C   s€   |   d¡rFtjdkr:|   d¡r,| dd … } qF| dd … } n| dd … } |  dtj¡} t | ¡r||d ksxt | ¡d |kr|| S d S )	Nzfile://rH   zfile:///é   é   é   z%5Cé   )Ú
startswithr?   r'   ÚreplaceÚsepÚospÚexistsÚsplitext)ÚpathÚextlistr*   r*   r+   Ú_process_mime_path   s    



r_   c             C   sŽ   g }|   ¡ rDxt|  ¡ D ](}tt| ¡ ƒ|ƒ}|dk	r| |¡ qW n>|  ¡ r‚x4t|  ¡ ƒ ¡ D ] }t||ƒ}|dk	r^| |¡ q^W |rŠ|S dS )zR
    Extract url list from MIME data
    extlist: for example ('.py', '.pyw')
    N)	ZhasUrlsZurlsr_   r$   ZtoStringÚappendZhasTextÚtextÚ
splitlines)Úsourcer^   ZpathlistÚurlr]   Zrawpathr*   r*   r+   Úmimedata2url’   s    
re   c             C   s(   |   ¡ |  ¡ |  ¡ |  ¡ |  ¡ |  ¡ fS )z'Convert QKeyEvent instance into a tuple)r1   ÚkeyÚ	modifiersra   ZisAutoRepeatÚcount)r6   r*   r*   r+   Úkeyevent2tuple¦   s    ri   c             C   s   t | Ž S )z'Convert tuple into a QKeyEvent instance)r   )Z
past_eventr*   r*   r+   Útuple2keyevent¬   s    rj   c             C   s^   t | tƒr$| \}}}}}}t| ƒ} n|  ¡ }|  ¡ }|  ¡ }|tj@ }|tj@ }| ||||fS )N)	Ú
isinstanceÚtuplerj   ra   rg   rf   r   ZControlModifierZShiftModifier)r6   Ú_rf   rg   ra   ZctrlÚshiftr*   r*   r+   Úrestore_keyevent±   s    



ro   Fc	       
      C   sÄ   t | ƒ}	|dk	r|	 |¡ |dk	r<t|ƒr2t|ƒ}|	 |¡ |dk	sL|dk	rb|	 |dkr\|n|¡ |rr|	 tj¡ |	 	|¡ |dk	r|	j
 |¡ |dk	r®|	j |¡ |	 d¡ |dk	rÀ|	 |¡ |	S )zCreate a QToolButtonNT)r   ZsetTextr#   r!   ÚsetIconÚ
setToolTipÚsetToolButtonStyler   ÚToolButtonTextBesideIconÚsetAutoRaiseZclickedrB   ÚtoggledÚsetCheckableÚsetShortcut)
Úparentra   ÚshortcutÚiconÚtipru   Ú	triggeredÚ	autoraiseÚtext_beside_iconÚbuttonr*   r*   r+   Úcreate_toolbutton¾   s(    




r€   c             C   s@   |dkr|   ¡ }t|ƒ}| | ¡ | |¡ |r<| tj¡ |S )z3Create a QToolButton directly from a QAction objectN)rx   r   ZsetDefaultActionrt   rr   r   rs   )Úactionr}   r~   rx   r   r*   r*   r+   Úaction2buttonØ   s    

r‚   c             C   s,   | dk	r(x| D ]}|dk	r|  |¡ qW dS )zEnable/disable actionsN)Z
setEnabled)ÚactionsÚenabler   r*   r*   r+   Útoggle_actionsä   s    
r…   c
             C   s  t || ƒ}
|dk	r|
j |¡ |dk	r<|
j |¡ |
 d¡ |dk	r^t|ƒrTt|ƒ}|
 |¡ |dk	rz|
 |¡ |
 	|¡ |dk	r|
 
t|ƒ¡ |dk	r¢|
 |¡ tjdkròd|
_|	tjkrÔ|dk	rÌ||
_qðd|
_n|dk	ræ|
 |¡ |
 |	¡ n|dk	r|
 |¡ |
 |	¡ |
S )zCreate a QActionNTÚdarwinZmissing)ÚSpyderActionr|   rB   ru   rv   r#   r!   rp   rq   ZsetStatusTipÚsetDatar   ZsetMenuRoleÚsysÚplatformZ_shown_shortcutr   ZWidgetShortcutrw   ZsetShortcutContext)rx   ra   ry   rz   r{   ru   r|   ÚdataZmenuroleÚcontextr   r*   r*   r+   Úcreate_actionì   s<    











r   c             C   s"   |   |  ¡ dt||d  ¡ dS )z>Add the shortcut associated with a given action to its tooltipz (%s))rŒ   r'   N)rq   ZtoolTipr   )r   rŒ   r'   r*   r*   r+   Úadd_shortcut_to_tooltip  s    rŽ   c          	   C   s$  d}t |  ¡ ƒ}|r(|d }| ¡ r(d}xö|D ]î}|dkr`|dk	r`|dkrT|  ¡  n
|  |¡ n¸t|tƒrŒ|dkr~|  |¡ n|  ||¡ nŒt|t	ƒrt|t
ƒrØt| tƒs¶t| tƒsØy
|j}W n tk
rÖ   w.Y nX |dkry|  |¡ W n tk
r   w.Y nX n|  ||¡ |}q.W dS )z%Add actions to a QMenu or a QToolBar.Néÿÿÿÿ)Úlistrƒ   ZisSeparatorZaddSeparatorZinsertSeparatorrk   r   ZaddMenuZ
insertMenur   r‡   r   Úno_icon_actionÚRuntimeErrorZ	addActionZinsertAction)Útargetrƒ   Zinsert_beforeZprevious_actionZtarget_actionsr   r*   r*   r+   Úadd_actions  s:    






r”   c             C   s   t |  dtj¡tƒS )z$Get QTreeWidgetItem user role stringr   )r   r‹   r   ÚUserRoler$   )Úitemr*   r*   r+   Úget_item_user_textE  s    r—   c             C   s   |   dtjt|ƒ¡ dS )z$Set QTreeWidgetItem user role stringr   N)rˆ   r   r•   r   )r–   ra   r*   r*   r+   Úset_item_user_textJ  s    r˜   c                s$   t ƒ ‡ fdd„ƒ}t| ||||dS )zCreate bookmark actionc                  s
   t  ˆ ¡S )N)r   Z
start_filer*   )rd   r*   r+   Úopen_urlR  s    z(create_bookmark_action.<locals>.open_url)ry   rz   r|   )r   r   )rx   rd   Útitlerz   ry   r™   r*   )rd   r+   Úcreate_bookmark_actionO  s    
r›   c             C   sP   g }xF|D ]>\}}}d}|dkr.t  |¡s.d}|r
t| ||ƒ}| |¡ q
W |S )zt
    Create bookmark actions depending on module installation:
    bookmarks = ((module_name, url, title), ...)
    TZ	winpythonF)r   Zis_module_installedr›   r`   )rx   Z	bookmarksrƒ   rf   rd   rš   Z
create_actZactr*   r*   r+   Úcreate_module_bookmark_actionsZ  s    
rœ   c                sT   t |ƒrt|ƒ}tjdkr&|dk	r&|‰ t ˆ ¡}|dk	rPt| ||‡ fdd„dS dS )zCreate action to run a programrH   Nc                  s
   t  ˆ ¡S )N)r   Zrun_programr*   )r'   r*   r+   Ú<lambda>v  s    z'create_program_action.<locals>.<lambda>)rz   r|   )r#   r!   r?   r'   r   Zfind_programr   )rx   ra   r'   rz   Znt_namer]   r*   )r'   r+   Úcreate_program_actionm  s    
rž   c                s<   t |ƒrt|ƒ}t ˆˆ¡r8t| ||‡ ‡‡fdd„dS dS )z.Create action to run a GUI based Python scriptc                  s   t  ˆˆˆ ¡S )N)r   Zrun_python_scriptr*   )r0   ÚmoduleÚpackager*   r+   r     s    z-create_python_script_action.<locals>.<lambda>)rz   r|   N)r#   r!   r   Zpython_script_existsr   )rx   ra   rz   r    rŸ   r0   r*   )r0   rŸ   r    r+   Úcreate_python_script_actiony  s
    r¡   c               @   s0   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zd
S )ÚDialogManagerz‡
    Object that keep references to non-modal dialog boxes for another QObject,
    typically a QMainWindow or any kind of QWidget
    c             C   s   t  | ¡ i | _d S )N)r   r.   Údialogs)r/   r*   r*   r+   r.   ˆ  s    
zDialogManager.__init__c                s”   xŽt ˆ j ¡ ƒD ].}t| ¡ ƒt| ¡ ƒkr| ¡  | ¡  P qW | ¡  |ˆ jt|ƒ< |j 	t|ƒf‡ fdd„	¡ |j
 	t|ƒf‡ fdd„	¡ dS )zYGeneric method to show a non-modal dialog and keep reference
        to the Qt C++ objectc                s
   ˆ   | ¡S )N)Údialog_finished)Úeid)r/   r*   r+   r   ™  s    z$DialogManager.show.<locals>.<lambda>c                s
   ˆ   | ¡S )N)r¤   )r¥   )r/   r*   r+   r   ›  s    N)r   r£   Úvaluesr$   ZwindowTitleÚshowZraise_ÚidZacceptedrB   Zrejected)r/   ÚdialogÚdlgr*   )r/   r+   r§   Œ  s    
zDialogManager.showc             C   s   | j  |¡S )zManage non-modal dialog boxes)r£   Úpop)r/   Z	dialog_idr*   r*   r+   r¤     s    zDialogManager.dialog_finishedc             C   s$   xt | j ¡ ƒD ]}| ¡  qW dS )zClose all opened dialog boxesN)r   r£   r¦   Zreject)r/   rª   r*   r*   r+   Ú	close_all¡  s    zDialogManager.close_allN)r8   r9   r:   r;   r.   r§   r¤   r¬   r*   r*   r*   r+   r¢   ƒ  s
   r¢   c             C   s8   t  | ¡d }| d¡r$|dd… }td| t d¡ƒS )zReturn file type iconrV   Ú.Nz%s.pngZFileIcon)rZ   r\   rW   r!   Úimarz   )r7   Zextr*   r*   r+   Úget_filetype_icon§  s    
r¯   c                   s8   e Zd ZdZ‡ fdd„Z‡ fdd„Zedd„ ƒZ‡  ZS )r‡   z>Spyder QAction class wrapper to handle cross platform patches.c                sˆ   t t| ƒj||Ž d| _tjdkr~t||Ž| _| j tƒ ¡ | jj	 
| j	¡ | jj 
| j¡ | jj 
| j¡ | jj 
| j¡ n| | _dS )z>Spyder QAction class wrapper to handle cross platform patches.Nr†   )Úsuperr‡   r.   Ú_action_no_iconr‰   rŠ   r   rp   r   r|   rB   ru   ÚchangedÚhovered)r/   r0   Úkwargs)Ú	__class__r*   r+   r.   ²  s    
zSpyderAction.__init__c                s@   t tˆƒ ˆ¡‰ tˆ dƒr8ˆdkr8‡‡ ‡‡fdd„}|S ˆ S dS )zAIntercept method calls and apply to both actions, except signals.Ú__call__)r|   ru   r²   r³   c                 s:   ˆ| |Ž}ˆdkr6ˆj d }tt|ƒ ˆ¡}|| |Ž |S )N)rp   r±   )Ú__dict__r°   r   Ú__getattribute__)r0   r´   ÚresultZaction_no_iconZattr_no_icon)rµ   rQ   r'   r/   r*   r+   ÚnewfuncÇ  s    


z.SpyderAction.__getattribute__.<locals>.newfuncN)r°   r‡   r¸   Úhasattr)r/   r'   rº   )rµ   )rQ   r'   r/   r+   r¸   Á  s
    zSpyderAction.__getattribute__c             C   s   | j S )z"Return the action without an Icon.)r±   )r/   r*   r*   r+   r‘   Ó  s    zSpyderAction.no_icon_action)	r8   r9   r:   r;   r.   r¸   Úpropertyr‘   Ú__classcell__r*   r*   )rµ   r+   r‡   ¯  s   r‡   c               @   s   e Zd ZdZdd„ ZdS )ÚShowStdIconsz'
    Dialog showing standard icons
    c       
      C   sØ   t  | |¡ tƒ }d}d}x–ttƒD ]Š}| d¡r$|dkr@tƒ }tƒ }t|ƒ}tƒ }	|	 	| 
dd¡¡ | |	¡ | t| dd¡ƒ¡ | |¡ |d | }|dkr$| |¡ q$W |  |¡ |  d¡ |  tdƒ¡ d S )	Né   r   ZSP_é    Ú rV   zStandard Platform IconsZTitleBarMenuButton)r   r.   r   Údirr   rW   r   r"   r   r&   ZpixmapÚ	addWidgetr   rX   Ú	addLayoutZ	setLayoutZsetWindowTitleZsetWindowIcon)
r/   rx   ÚlayoutZrow_nbZcindexZchildZ
col_layoutZicon_layoutrz   r)   r*   r*   r+   r.   Ý  s*    




zShowStdIcons.__init__N)r8   r9   r:   r;   r.   r*   r*   r*   r+   r¾   Ù  s   r¾   c              C   s(   t ƒ } tdƒ}| ¡  t |  ¡ ¡ dS )z!
    Show all standard Icons
    N)rG   r¾   r§   r‰   ÚexitZexec_)rF   r©   r*   r*   r+   Úshow_std_iconsõ  s    rÇ   c          
   C   sp   ddddddddddœ	}t ƒ  ¡  d	¡}d
tj|f }||krl|| \}}|  ¡  ¡ }|| | }t|dƒS dS )a«  
    Return a spacing (int) or None if we don't have the appropriate metrics
    to calculate the spacing.

    We're trying to adapt the spacing below the tools_layout spacing so that
    the main_widget has the same vertical position as the editor widgets
    (which have tabs above).

    The required spacing is

        spacing = tabbar_height - tools_height + offset

    where the tabbar_heights were empirically determined for a combination of
    operating systems and styles. Offsets were manually adjusted, so that the
    heights of main_widgets and editor widgets match. This is probably
    caused by a still not understood element of the layout and style metrics.
    )rÀ   r   )é   r<   )é   r   )é   r   )é&   éþÿÿÿ)é   r   )é   r   )	z	nt.fusionznt.windowsvistaznt.windowsxpz
nt.windowszposix.breezezposix.oxygenzposix.qtcurvezposix.windowszposix.fusionr'   z%s.%sr   N)rG   Zstyler¼   r?   r'   ZsizeHintZheightÚmax)Útools_layoutZmetricsZ
style_namerf   Ztabbar_heightÚoffsetZtools_heightÚspacingr*   r*   r+   Úcalc_tools_spacingÿ  s     rÓ   c             C   sP   t ƒ }| dddd¡ t| ƒ}|dk	r0| |¡ | | ¡ |dk	rL| |¡ |S )a“  
    Returns a layout for a set of controls above a main widget. This is a
    standard layout for many plugin panes (even though, it's currently
    more often applied not to the pane itself but with in the one widget
    contained in the pane.

    tools_layout: a layout containing the top toolbar
    main_widget: the main widget. Can be None, if you want to add this
        manually later on.
    r   N)r   ZsetContentsMarginsrÓ   Z
setSpacingrÄ   rÃ   )rÐ   Zmain_widgetrÅ   rÒ   r*   r*   r+   Úcreate_plugin_layout'  s    


rÔ   Ú__main__)r%   )Tr<   )N)NNNNNNTF)TFN)N)NN)NN)N)Vr;   r?   Úos.pathr]   rZ   rI   r‰   Zqtpy.compatr   r   Zqtpy.QtCorer   r   r   r   r   r	   r
   r   r   Z
qtpy.QtGuir   r   r   r   Zqtpy.QtWidgetsr   r   r   r   r   r   r   r   r   r   r   Zspyder.config.baser   r   Zspyder.config.guir   Zspyder.utilsr   r    r®   Zspyder.utils.icon_managerr!   r"   Zspyder.py3compatr#   r$   r,   r-   rG   rK   rL   r>   rR   r_   re   ri   rj   ro   r€   r‚   r…   ZWindowShortcutr   rŽ   r”   r—   r˜   r›   rœ   rž   r¡   r¢   r¯   r‡   r¾   rÇ   rÓ   rÔ   ZMENU_SEPARATORr8   r*   r*   r*   r+   Ú<module>   sh   ,4

 
  

+
&


$*
(

