B
    nôb\ñd  ã               @   sÌ   d Z ddlZddl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 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZmZ ddlmZ dd„ Z dd„ Z!G dd„ deƒZ"dS )zFind/Replace widgeté    N)ÚQtÚQTimerÚSignalÚSlotÚQEvent)ÚQTextCursor)ÚQGridLayoutÚQHBoxLayoutÚQLabelÚQSizePolicyÚQWidget)Ú_)Úconfig_shortcut)Úto_text_string)Úicon_manager)Úregexp_error_msg)Úcreate_toolbuttonÚget_icon)ÚPatternComboBoxc             C   s   | |kS )zReturn True is pos1 > pos2© )Úpos1Úpos2r   r   ú9lib/python3.7/site-packages/spyder/widgets/findreplace.pyÚis_position_sup!   s    r   c             C   s   | |k S )zReturn True is pos1 < pos2r   )r   r   r   r   r   Úis_position_inf%   s    r   c                   sT  e Zd ZdZdddddœZedƒedƒedƒedƒdœZeeƒZ	eƒ Z
eƒ Zd<d
d„Z‡ fdd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zeeƒdd„ ƒZd=dd„Zeƒ dd„ ƒZdd „ Zd!d"„ Zd#d$„ Zd>d%d&„Zeƒ d'd(„ ƒZeƒ d)d*„ ƒZd+d,„ Zd-d.„ Zd/d0„ Zd?d1d2„Z eƒ d@d3d4„ƒZ!eƒ dAd5d6„ƒZ"eƒ dBd7d8„ƒZ#dCd:d;„Z$‡  Z%S )DÚFindReplacezFind widgetz#background-color:rgb(255, 175, 90);Ú z"background-color:rgb(255, 80, 80);)FTNÚregexp_errorz
No matcheszSearch stringzRegular expression errorFc          	      sþ  t  ˆ |¡ |ˆ _d ˆ _d ˆ _tƒ }| dddd¡ ˆ  |¡ tˆ ˆ j	t
 d¡dˆ _| ˆ jdd¡ tˆ tdƒddˆ _ˆ j ‡ fdd„¡ ˆ j ‡ fd	d„¡ ˆ j ¡ j ˆ j¡ tˆ ƒˆ _tˆ ˆ jt
 d
¡dˆ _tˆ ˆ jt
 d¡dˆ _ˆ jj ˆ j¡ ˆ jj ˆ j¡ tˆ tdƒtdƒdˆ _ ˆ j  !d¡ ˆ j j" ‡ fdd„¡ tˆ tdƒtdƒdˆ _#ˆ j# !d¡ ˆ j#j" ‡ fdd„¡ tˆ tdƒtdƒdˆ _$ˆ j$ !d¡ ˆ j$j" ‡ fdd„¡ tˆ tdƒtdƒdˆ _%ˆ j% !d¡ ˆ j%j" ˆ j&¡ t'ƒ }ˆ jˆ jˆ jˆ jˆ jˆ j ˆ j#ˆ j$ˆ j%g	ˆ _(x"ˆ j(dd … D ]}| |¡ q2W | )|dd¡ ttdƒƒ}tˆ dtdƒdˆ _*ˆ j*j+ ‡ fdd„¡ tˆ tdƒt
 d¡ˆ j,dd ˆ _-tˆ td!ƒt
 d¡ˆ j.dd ˆ _/ˆ j/j ˆ j0¡ ˆ j/j ˆ j¡ tˆ td"ƒt
 d¡ˆ j1dd ˆ _2ˆ j2j ˆ j0¡ ˆ j2j ˆ j¡ t'ƒ ˆ _3|ˆ j*ˆ j-ˆ j/ˆ j2g}x|D ]}ˆ j3 |¡ qNW | )ˆ j3dd¡ ˆ j( 4|¡ |ˆ _5ˆ  6¡  ˆ j 7ˆ jˆ j*¡ ˆ  8t9j:t9j;¡ ˆ  <|¡ˆ _=t>ˆ ƒˆ _?ˆ j? @d¡ ˆ j? Ad#¡ ˆ j?jB ˆ jC¡ ˆ j Dˆ ¡ d S )$Nr   ZDialogCloseButton)Ú	triggeredÚiconzSearch stringF)ÚtipÚadjust_to_minimumc                  s   ˆ j dddddS )NF)ÚchangedÚforwardÚrehighlightÚmultiline_replace_check)Úfindr   )Úselfr   r   Ú<lambda>M   s    
z&FindReplace.__init__.<locals>.<lambda>c                  s   ˆ j dddddS )NFT)r"   r#   r$   r%   )r&   r   )r'   r   r   r(   R   s    
ZArrowUpZ	ArrowDownz
regexp.svgzRegular expression)r   r    Tc                s   ˆ   ¡ S )N)r&   )Ústate)r'   r   r   r(   f   s    zupper_lower.pngzCase Sensitivec                s   ˆ   ¡ S )N)r&   )r)   )r'   r   r   r(   l   s    zwhole_words.pngzWhole wordsc                s   ˆ   ¡ S )N)r&   )r)   )r'   r   r   r(   r   s    zhighlight.pngzHighlight matchesé   zReplace with:zReplace string)r!   r    c                s   ˆ j ddS )NT)Úfocus_replace_text)Úreplace_find)r   )r'   r   r   r(   ˆ   s    zReplace/find nextZDialogApplyButton)Útextr   r   Ztext_beside_iconzReplace selectionzReplace alliè  )Er   Ú__init__Úenable_replaceÚeditorÚis_code_editorr   ZsetContentsMarginsZ	setLayoutr   ÚhideÚimar   Zclose_buttonZ	addWidgetr   r   Úsearch_textÚreturn_shift_pressedZconnectÚreturn_pressedÚlineEditZ
textEditedÚtext_has_been_editedr
   Únumber_matches_textÚfind_previousZprevious_buttonÚ	find_nextZnext_buttonZclickedÚupdate_search_combor   Ú	re_buttonZsetCheckableZtoggledÚcase_buttonÚwords_buttonÚhighlight_buttonÚtoggle_highlightingr	   ÚwidgetsZ	addLayoutÚreplace_textZvalidr,   Zreplace_buttonÚreplace_find_selectionZreplace_sel_buttonÚupdate_replace_comboÚreplace_find_allZreplace_all_buttonZreplace_layoutÚextendÚreplace_widgetsÚhide_replaceZsetTabOrderZsetSizePolicyr   Z	ExpandingZFixedÚcreate_shortcutsÚ	shortcutsr   Úhighlight_timerZsetSingleShotZsetIntervalZtimeoutÚhighlight_matchesZinstallEventFilter)r'   Úparentr/   ZglayoutZhlayoutÚwidgetZreplace_withrB   r   )r'   r   r.   :   s¾    










zFindReplace.__init__c                sˆ   |  ¡ tjkrv| ¡ }| ¡ tj@ }|tjkrH|r>| j 	¡  n
| j
 	¡  |tjkrv| j ¡ rn| j | j ¡ ¡ |  ¡  tt| ƒ ||¡S )zðEvent filter for search_text widget.

        Emits signals when presing Enter and Shift+Enter.
        This signals are used for search forward and backward.
        Also, a crude hack to get tab working in the Find/Replace boxes.
        )Útyper   ZKeyPressÚkeyZ	modifiersr   ZShiftModifierZ
Key_Returnr5   Úemitr6   ZKey_Tabr4   ZhasFocusrC   Zset_current_textÚcurrentTextZfocusNextChildÚsuperr   ÚeventFilter)r'   rO   ZeventrQ   Úshift)Ú	__class__r   r   rU   ´   s    



zFindReplace.eventFilterc             C   sh   t | jdd|d}t | jdd|d}t | jdd|d}t | jdd|d}t | jdd| d}|||||gS )z Create shortcuts for this widgetr   z	Find next)ÚcontextÚnamerN   zFind previousz	Find textzReplace textzhide find and replace)r   r;   r:   ÚshowÚshow_replacer2   )r'   rN   ZfindnextZfindprevZ
togglefindZtogglereplacer2   r   r   r   rJ   Í   s    



zFindReplace.create_shortcutsc             C   s   dd„ | j D ƒS )zæ
        Returns shortcut data, a list of tuples (shortcut, text, default)
        shortcut (QShortcut or QAction instance)
        text (string): action/shortcut description
        default (string): default key sequence
        c             S   s   g | ]
}|j ‘qS r   )Údata)Ú.0Zscr   r   r   ú
<listcomp>å   s    z1FindReplace.get_shortcut_data.<locals>.<listcomp>)rK   )r'   r   r   r   Úget_shortcut_dataÞ   s    zFindReplace.get_shortcut_datac             C   s   | j  ¡ j ¡  d S )N)r4   r7   ÚreturnPressedrR   )r'   r   r   r   r<   ç   s    zFindReplace.update_search_comboc             C   s   | j  ¡ j ¡  d S )N)rC   r7   r`   rR   )r'   r   r   r   rE   ê   s    z FindReplace.update_replace_comboc             C   sR   | j rN| jd  ¡ r&|  ¡  |  ¡  n(|  ¡  tt| j 	¡ ƒƒdkrN| j
 ¡  d S )Nr   )r/   rH   Ú	isVisiblerI   r2   r[   Úlenr   r4   rS   rC   ÚsetFocus)r'   r   r   r   Útoggle_replace_widgetsí   s    
z"FindReplace.toggle_replace_widgetsc             C   s$   | j dk	r |r|  ¡  n|  ¡  dS )z*Toggle the 'highlight all results' featureN)r0   rM   Úclear_matches)r'   r)   r   r   r   rA   ø   s    

zFindReplace.toggle_highlightingTc             C   sú   t  | ¡ | j d¡ |  ¡  | jdk	rö|rB| jd  ¡ rB|  ¡  | j 	¡ }|s`t
| ¡ ƒdkrìd}|s¨d}y&| j ¡ }| tj¡ t| ¡ ƒ}W n tk
r¦   Y nX |r¶| j ¡ rº|rÞ| j |¡ | j ¡  ¡  |  ¡  n| j ¡  ¡  | j ¡  dS )zOverrides Qt MethodTNr   r*   F)r   rZ   Úvisibility_changedrR   Úchange_number_matchesr0   rH   ra   rI   Úget_selected_textrb   Ú
splitlinesÚ
textCursorZselectr   ZWordUnderCursorr   ÚselectedTextÚAttributeErrorr4   rS   ZsetEditTextr7   Z	selectAllÚrefreshrc   )r'   rI   r-   ZhighlightedÚcursorr   r   r   rZ     s0    




zFindReplace.showc             C   sN   x| j D ]}| ¡  qW t | ¡ | j d¡ | jdk	rJ| j ¡  |  ¡  dS )zOverrides Qt MethodFN)rH   r2   r   rf   rR   r0   rc   re   )r'   rO   r   r   r   r2   $  s    


zFindReplace.hidec             C   s(   | j dd x| jD ]}|  ¡  qW dS )zShow replace widgetsF)rI   N)rZ   rH   )r'   rO   r   r   r   r[   /  s    zFindReplace.show_replacec             C   s   x| j D ]}| ¡  qW dS )zHide replace widgetsN)rH   r2   )r'   rO   r   r   r   rI   5  s    zFindReplace.hide_replacec             C   sR   |   ¡ r| jdk	r|  ¡  dS | jdk	}x| jD ]}| |¡ q0W |rN|  ¡  dS )zRefresh widgetN)ÚisHiddenr0   re   rB   Z
setEnabledr&   )r'   r)   rO   r   r   r   rm   :  s    

zFindReplace.refreshc             C   sª   || _ yddlm} W n tk
r2   tdƒ}Y nX | j t||ƒ ¡ | j t||ƒ ¡ ddl	m
} t||ƒ| _| j | j¡ |rŽ|  ¡  |  ¡ r¦|dk	r¦|  ¡  dS )z|
        Set associated editor/web page:
            codeeditor.base.TextEditBaseWidget
            browser.WebView
        r   )ÚQWebEngineViewN)Ú
CodeEditor)r0   Zqtpy.QtWebEngineWidgetsrp   ÚImportErrorrP   r?   Z
setVisibleÚ
isinstancer=   Z$spyder.widgets.sourcecode.codeeditorrq   r1   r@   rm   ro   re   )r'   r0   rm   rp   rq   r   r   r   Ú
set_editorF  s    zFindReplace.set_editorc             C   s*   | j ddddd}| j ¡  | j ¡  |S )zFind next occurrenceFT)r"   r#   r$   r%   )r&   r0   rc   r4   Zadd_current_text)r'   r)   r   r   r   r;   ]  s
    


zFindReplace.find_nextc             C   s    | j ddddd}| j ¡  |S )zFind previous occurrenceF)r"   r#   r$   r%   )r&   r0   rc   )r'   r)   r   r   r   r:   f  s    

zFindReplace.find_previousc             C   s   | j dddd dS )zFind text has been edited (this slot won't be triggered when 
        setting the search pattern combo box text programmatically)T)r"   r#   Ústart_highlight_timerN)r&   )r'   r-   r   r   r   r8   n  s    z FindReplace.text_has_been_editedc             C   sD   | j r@| j ¡ r@| j ¡ }| j ¡ }| j ¡ }| jj|||d dS )zHighlight found results)ÚwordsÚregexpN)	r1   r@   Ú	isCheckedr4   rS   r?   r=   r0   Zhighlight_found_results)r'   r-   rv   rw   r   r   r   rM   s  s    



zFindReplace.highlight_matchesc             C   s   | j r| j ¡  dS )zClear all highlighted matchesN)r1   r0   Zclear_found_results)r'   r   r   r   re   |  s    zFindReplace.clear_matchesc             C   s¤  |r0| j d  ¡ r0tt| j ¡ ƒ ¡ ƒdkr0dS | j ¡ }t|ƒdkrt| j 	¡  
d¡ | jsh| j d¡ |  ¡  dS | j ¡ }| j ¡ }| j ¡ }	| jj||||||	d}
| j|
 }| j|
 }|
sî|	rît|ƒ}|rî| jd }| jd d | }| j 	¡  
|¡ | j |¡ | jrN|
rN|s(| jjsV| j ¡  |rD| j ¡  n|  ¡  n|  ¡  | jj|||	d}t| jd	ƒrŠ| jj|||	d}nd}| j||d
 |
S dS )zCall the find functionr   r*   Nr   )Úcaserv   rw   r   z: )ry   rw   Úget_match_number)Úcurrent_matchÚtotal_matches)rH   ra   rb   r   r0   rh   ri   r4   rS   r7   ZsetStyleSheetr1   Z	find_textrg   r>   rx   r?   r=   ÚSTYLEÚTOOLTIPr   Z
setToolTipZfound_resultsrL   ÚstopÚstartrM   re   Zget_number_matchesÚhasattrrz   )r'   r"   r#   r$   ru   r%   r-   ry   rv   rw   ÚfoundZ
stylesheetZtooltipZ	error_msgZnumber_matchesZmatch_numberr   r   r   r&     sP    












zFindReplace.findc             C   sH  | j dk	rDt| j ¡ ƒ}t| j ¡ ƒ}d}| j ¡ rhyt |¡}| 	|d¡ W n tj
k
rf   dS X | j ¡ }d}d}x¤|r:t| j  ¡ ƒ}	|rš|n| ¡ }
|rª|	n|	 ¡ }|dkræ| j  ¡ }|rÒ|
|krÒn| jddddsäP n(t| |¡ƒdkrún| jddddsP d}d}| j  d¡}|}| j  ¡ }| ¡  n^| j  d¡}t||t|ƒ t|ƒ d ƒrjd}|rˆ||ks†t||ƒrˆP ||kr”P |}|dkr¶| ¡  | |¡ n&t| ¡ ƒ}	| ¡  | | 	||	¡¡ |  ¡ r| j  ¡ }| | ¡ tj¡ | | ¡ tj ¡ nP |s~P q~W |dk	r4| !¡  |rD| j "¡  dS )	zReplace and findNr   TF)r"   r#   r$   r   rn   r*   )#r0   r   rC   rS   r4   r=   rx   ÚreÚcompileÚsubÚerrorr>   rh   ÚlowerZhas_selected_textr&   rb   ÚfindallZget_positionrj   ÚbeginEditBlockr   r   ÚremoveSelectedTextÚ
insertTextrk   r;   ZsetPositionZselectionStartr   Z
MoveAnchorZselectionEndZ
KeepAnchorÚendEditBlockrc   )r'   r+   Úreplace_allrC   r4   Ú
re_patternry   Úfirstrn   ZseltxtZcmptxt1Zcmptxt2Zhas_selectedÚwrappedZpositionZ	position0Z	position1Zfound_cursorr   r   r   r,   ¸  s„    















zFindReplace.replace_findc             C   s   | j |dd dS )z)Replace and find all matching occurrencesT)r   N)r,   )r'   r+   r   r   r   rF     s    zFindReplace.replace_find_allc          
   C   sX  | j dk	rTt| j ¡ ƒ}t| j ¡ ƒ}| j ¡ }| j ¡ }|rFtj	n
tj
tj	B }d}| j ¡ rf|}nt |¡}t |¡}|rŠdj|d}ytj||d}| |d¡ W n$ tjk
rÌ }	 zdS d}	~	X Y nX t| j  ¡ ƒ}
| ||
¡}||
kr8| j  ¡ }| ¡  | ¡  | j ¡ s&t dd|¡}| |¡ | ¡  |rJ| j ¡  n
| j  ¡  dS )z)Replace and find in the current selectionNz\b{pattern}\b)Úpattern)Úflagsr   z\\(?![nrtf])(.)z\1)r0   r   rC   rS   r4   r>   rx   r?   rƒ   Ú	MULTILINEÚ
IGNORECASEr=   ÚescapeÚformatr„   r…   r†   rh   rj   r‰   rŠ   r‹   rŒ   rc   )r'   r+   rC   r4   ry   rv   Zre_flagsrŽ   r‘   ÚeZselected_textZreplacementrn   r   r   r   rD     s>    







z"FindReplace.replace_find_selectionr   c             C   s^   |r(|r(d  |tdƒ|¡}| j |¡ n2|rJd  |tdƒ¡}| j |¡ n| j tdƒ¡ dS )z)Change number of match and total matches.z{} {} {}Zofz{} {}Zmatchesz
no matchesN)r–   r   r9   ZsetText)r'   r{   r|   Zmatches_stringr   r   r   rg   D  s    z!FindReplace.change_number_matches)F)T)T)TTTFT)FF)F)F)r   r   )&Ú__name__Ú
__module__Ú__qualname__Ú__doc__r}   r   r~   r   Úboolrf   r5   r6   r.   rU   rJ   r_   r<   rE   rd   r   rA   rZ   r2   r[   rI   rm   rt   r;   r:   r8   rM   re   r&   r,   rF   rD   rg   Ú__classcell__r   r   )rW   r   r   *   sP   
z		
#
		 
6Y+r   )#r›   rƒ   Zqtpy.QtCorer   r   r   r   r   Z
qtpy.QtGuir   Zqtpy.QtWidgetsr   r	   r
   r   r   Zspyder.config.baser   Zspyder.config.guir   Zspyder.py3compatr   Zspyder.utilsr   r3   Zspyder.utils.miscr   Zspyder.utils.qthelpersr   r   Zspyder.widgets.comboboxesr   r   r   r   r   r   r   r   Ú<module>   s   