a
     ³ŠaÄÀ  ã                   @   sF  d Z ddlZddlZddlZddlmZ ddl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m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 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,m-Z- ddl.m/Z/ ddl0m1Z1m2Z2 ddl3m4Z4 ddl5m6Z6 e&dƒZ7e2j8Z9dZ:dZ;dZ<dZ=dZ>dZ?dZ@dZAdZBdZCdZDG dd„ dƒZEG dd„ dƒZFG dd „ d ƒZGG d!d"„ d"ƒZHG d#d$„ d$ƒZIG d%d&„ d&ƒZJd'd(„ ZKG d)d*„ d*eƒZLG d+d,„ d,eƒZMG d-d.„ d.e"ƒZNG d/d0„ d0e"ƒZOG d1d2„ d2e ƒZPG d3d4„ d4e6ƒZQG d5d6„ d6e(ƒZRd7d8„ ZSeTd9krBeSƒ  dS ):z
Find in files widget.
é    N)Úgetexistingdirectory)ÚQEventÚQMutexÚQMutexLockerÚQSizeÚQtÚQThreadÚSignalÚSlot)ÚQAbstractTextDocumentLayoutÚQTextDocument)ÚQApplicationÚ	QComboBoxÚQHBoxLayoutÚQInputDialogÚQLabelÚQMessageBoxÚQSizePolicyÚQStyleÚQStyledItemDelegateÚQStyleOptionViewItemÚQTreeWidgetItem)Úon_conf_change)Úget_translation)ÚPluginMainWidget)Úget_font)Úis_text_fileÚto_unicode_from_fs)Úregexp_error_msg)ÚSpyderPaletteÚQStylePalette)ÚPatternComboBox)ÚOneColumnTreeZspyderZonZoffé   é   é   é   é   é<   é   é
   c                   @   s(   e Zd ZdZdZdZdZdZdZdZ	dS )	ÚFindInFilesWidgetActionsÚfind_actionZmax_results_actionZtoggle_case_actionZtoggle_exclude_case_actionZ togle_use_regex_on_exlude_actionZtoggle_more_options_actionZ!toggle_use_regex_on_search_actionN)
Ú__name__Ú
__module__Ú__qualname__ÚFindÚ
MaxResultsÚ
ToggleCaseÚToggleExcludeCaseÚToggleExcludeRegexÚToggleMoreOptionsÚToggleSearchRegex© r7   r7   úAlib/python3.9/site-packages/spyder/plugins/findinfiles/widgets.pyr+   @   s   r+   c                   @   s   e Zd ZdZdZdS )ÚFindInFilesWidgetToolbarsZexclude_toolbarÚlocation_toolbarN)r-   r.   r/   ÚExcludeÚLocationr7   r7   r7   r8   r9   M   s   r9   c                   @   s   e Zd ZdZdS )Ú$FindInFilesWidgetMainToolbarSectionsÚmain_sectionN©r-   r.   r/   ÚMainr7   r7   r7   r8   r=   R   s   r=   c                   @   s   e Zd ZdZdS )Ú'FindInFilesWidgetExcludeToolbarSectionsr>   Nr?   r7   r7   r7   r8   rA   V   s   rA   c                   @   s   e Zd ZdZdS )Ú(FindInFilesWidgetLocationToolbarSectionsr>   Nr?   r7   r7   r7   r8   rB   Z   s   rB   c                   @   s$   e Zd ZdZdZdZdZdZdZdS )ÚFindInFilesWidgetToolbarItemsZpattern_comboÚsearch_in_labelÚexclude_labelZexclude_pattern_comboZstretcher_1Zsearch_in_comboN)	r-   r.   r/   ÚSearchPatternComboÚSearchInLabelÚExcludeLabelÚExcludePatternComboÚ
Stretcher1ÚSearchInCombor7   r7   r7   r8   rC   ^   s   rC   c                 C   sN   d}t t|ƒ d }| d tt |¡ƒ… }| tt |¡ƒ d … }|| | S )Nú...g       @)ÚMAX_PATH_LENGTHÚlenÚintÚmathZceilZfloor)ÚtextÚellipsisZpart_lenZ	left_textZ
right_textr7   r7   r8   Útruncate_pathi   s
    rS   c                       sœ   e Zd ZdZeeƒZeeƒZeeƒZ	ee
ƒZee
e
ƒZee
ƒZdZdZd‡ 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dd„ Z‡  ZS )ÚSearchThreadzFind in files search thread.r   é	   Nc                    s„   t ƒ  |¡ tƒ | _d | _|| _|| _d | _d | _d | _	d | _
d | _d | _d | _d | _d| _d| _d| _i | _d| _g | _g | _d S )NTr   F)ÚsuperÚ__init__r   ÚmutexÚstoppedÚsearch_textÚ
text_colorÚpathlistÚtotal_matchesÚ
error_flagÚrootpathÚexcludeÚtextsÚtext_reÚ	completedÚcase_sensitiveÚis_fileÚresultsÚ	num_filesÚfilesÚpartial_results)ÚselfÚparentrZ   r[   ©Ú	__class__r7   r8   rW   ~   s(    zSearchThread.__init__c                 C   s>   || _ |rt |¡| _|| _|| _|| _d| _d| _|| _	d S )NF)
r_   ÚreÚcompiler`   ra   rb   re   rY   rc   rd   )rj   Úpathre   r`   ra   rb   rd   r7   r7   r8   Ú
initialize•   s    zSearchThread.initializec                 C   sj   z*g | _ | jr|  | j¡ n|  | j¡ W n$ tyN   t ¡  tdƒ| _	Y n0 |  
¡  | j | j¡ d S )Nz&Unexpected error: see internal console)Ú	filenamesre   Úfind_string_in_filer_   Úfind_files_in_pathÚ	ExceptionÚ	tracebackÚ	print_excÚ_r^   ÚstopÚsig_finishedÚemitrc   ©rj   r7   r7   r8   Úrun¡   s    zSearchThread.runc                 C   s4   t | jƒ d| _W d   ƒ n1 s&0    Y  d S ©NT)r   rX   rY   r|   r7   r7   r8   ry   ±   s    zSearchThread.stopc              
   C   sö  | j d u rg | _ | j  |¡ t |¡D ]¸\}}}t| jƒ( | jrVW d   ƒ  dS W d   ƒ n1 sj0    Y  zD|d d … D ]ž}t| jƒ, | jr°W d   ƒ  W  dS W d   ƒ n1 sÄ0    Y  tj ||¡}| j	rt
 | j	|tj ¡r| |¡ q„|dks|dkr„| |¡ q„|D ]Ž}t| jƒ. | jrVW d   ƒ  W  dS W d   ƒ n1 sl0    Y  tj ||¡}| j	r t
 | j	|¡r q(t|ƒr(|  |¡ q(W q& t
jyÞ   tdƒ| _Y  dS 0 q&| jrò|  ¡  dS )NFz.gitz.hgzinvalid regular expressionT)r\   ÚappendÚosÚwalkr   rX   rY   rp   Újoinr`   rn   ÚsearchÚsepÚremover   rs   Úerrorrx   r^   ri   Úprocess_results)rj   rp   Údirsrh   ÚdÚdirnameÚfÚfilenamer7   r7   r8   rt   µ   sD    
04ÿ6

zSearchThread.find_files_in_pathc              
   C   sÌ  d| _ | j |¡ zrtt|dƒƒD ]\\}}| jD ]–\}}t| jƒ, | jrdW d   ƒ   W dS W d   ƒ n1 sx0    Y  |}| j	s”| 
¡ }| jr´t ||¡}|d urÊ qÌq4| |¡}|dkr4 qÌq4z| |¡}W n tyð   |}Y n0 | j	s| 
¡ }| jr8t ||¡D ]}	t| jƒ. | jrFW d   ƒ   W dS W d   ƒ n1 s\0    Y  |  jd7  _|	 ¡ |	 ¡  }
}z4t|d |
…  |¡ƒ}|t||
|…  |¡ƒ }W n tyÖ   |
}|}Y n0 | j t |¡|d |||f¡ t| jƒd| j kr|  ¡  | j| jk r|  jd7  _qq$| |¡}|dkr$t| jƒ, | jrrW d   ƒ  W dS W d   ƒ n1 sˆ0    Y  |  jd7  _z,t|d |…  |¡ƒ}|t| |¡ƒ }W n$ tyð   |}|t|ƒ }Y n0 | j t |¡|d |||f¡ t| jƒd| j krL|  ¡  | j| jk rL|  jd7  _| jD ]*\}}| ||d ¡}|dkrR qBqRqBq$W n: tyÀ } z |j\}}tdƒ| _ W Y d }~n
d }~0 0 d| _ d S )NFÚrbéÿÿÿÿr#   r$   z)permission denied errors were encounteredT)!r^   Úsig_current_filer{   Ú	enumerateÚopenra   r   rX   rY   rd   Úlowerrb   rn   rƒ   ÚfindÚdecodeÚUnicodeDecodeErrorÚfinditerr]   ÚstartÚendrN   ri   r   ÚospÚabspathÚpowerr‡   Ú	max_powerÚIOErrorÚargsrx   rc   )rj   ÚfnameÚlinenoÚlinerQ   ÚencZline_searchÚfoundZline_decÚmatchZbstartZbendr—   r˜   Zxxx_todo_changemeZ_errnoZ	_strerrorr7   r7   r8   rs   Û   sš    4

6
ü
4ü

 z SearchThread.find_string_in_filec                 C   sì   g }| j }| jD ]h}|\}}}}}|| jvrR| j |¡ | j |¡ |  jd7  _|  |||¡}|||||f}	| |	¡ qd| j }
| j}|dkrœt	dƒ}n0t	dƒ}t	dƒ}|dkr¼|d7 }d||||f }|
| }
g | _| j
 ||
¡ d	S )
aT  
        Process all matches found inside a file.

        Creates the necessary files and emits signal for the creation of file
        item.

        Creates the necessary data for lines found and emits signal for the
        creation of line items in batch.

        Creates the title based on the last entry of the lines batch.
        r#   ú'%s' - r   úString not foundz
matches inÚfileÚsz%d %s %d %sN)r]   ri   rh   r   Úsig_file_matchr{   rg   Útruncate_resultrZ   rx   Úsig_line_match)rj   ÚitemsZnum_matchesÚresultrŒ   r    ÚcolnoÚ	match_endr¡   ÚitemÚtitleZnb_filesrQ   Ztext_matchesZ
text_filesr7   r7   r8   r‡   2  s2    



ÿzSearchThread.process_resultsc                    sÚ  d}d}d}dddddd	œ‰ ‡ fd
d„}t |ƒ}|d|… |||… ||d…   }}	}
t|ƒ|kr t|ƒt|	ƒ d }| d¡}t|ƒ}|dkrÀ|d }t|ƒ|krº||| d…  }|g}|
 d¡}
t|
ƒ}|dkr|
d }
t|
ƒ|kr|
d|… | }
|
g}
|dd… }|
dd… }
t|ƒ|k r8|g| }t|
ƒ|k rP|
|g }
d |¡}d |
¡}
t|ƒ|kr‚||dd…  }t|
ƒ|kr |
dd… | }
d}| | j¡}||ƒ}||
ƒ}
||	ƒ}	| ||	|
¡}|S )zU
        Shorten text on line to display the match within `max_line_length`.
        rL   éP   é(   z&amp;z&quot;z&apos;z&gt;z&lt;)ú&ú"ú'ú>ú<c                    s   d  ‡ fdd„| D ƒ¡S )zProduce entities within text.Ú c                 3   s   | ]}ˆ   ||¡V  qd S ©N)Úget)Ú.0Úc©Zhtml_escape_tabler7   r8   Ú	<genexpr>o  ó    zDSearchThread.truncate_result.<locals>.html_escape.<locals>.<genexpr>)r‚   )rQ   r¾   r7   r8   Úhtml_escapem  s    z1SearchThread.truncate_result.<locals>.html_escapeNr$   ú r#   r   éüÿÿÿr%   iâÿÿÿé   z5<span style="color:{0}">{{0}}<b>{{1}}</b>{{2}}</span>)ÚstrrN   Úsplitr‚   Úformatr[   )rj   r¡   r—   r˜   rR   Zmax_line_lengthZmax_num_char_fragmentrÁ   Úleftr¤   ÚrightÚoffsetZnum_left_wordsZnum_right_wordsZline_match_formatZ
trunc_liner7   r¾   r8   rª   ]  s^    û(






zSearchThread.truncate_resultc                 C   s   | j | j| j| jfS rº   )rf   r\   r]   r^   r|   r7   r7   r8   Úget_results¥  s    zSearchThread.get_results)N)r-   r.   r/   Ú__doc__r	   Úboolrz   rÅ   r   Zsig_current_folderÚobjectr©   r«   Zsig_out_printr›   rœ   rW   rq   r}   ry   rt   rs   r‡   rª   rË   Ú__classcell__r7   r7   rl   r8   rT   q   s$   
&W+HrT   c                       sŒ   e Zd ZdZeeƒZg ddf‡ fdd„	Zdd„ Zdd„ Z	d	d
„ Z
dd„ Zdd„ Zdd„ Zeƒ dd„ ƒZeƒ dd„ ƒZdd„ Zdd„ Z‡  ZS )ÚSearchInComboBoxz[
    Non editable combo box handling the path locations of the FindOptions
    widget.
    Nc                    s|  t ƒ  |¡ |  tjtj¡ |  tdƒ¡ |  d¡ d| _	d | _
d | _d | _|d urZ|| _|  tdƒ¡ d}|  d|tj¡ |  tdƒ¡ tdƒ}|  d	|tj¡ |  ¡  d	d¡ d¡ |  td
ƒ dd¡¡ tdƒ}|  d|tj¡ |  d¡ |  tdƒ¡ tdƒ}|  d|tj¡ |  tdƒ¡ tdƒ}|  d|tj¡ |  d¡ |D ]}|  |¡ qJ| j | j¡ |  ¡  | ¡ d S )NzSearch directoryFr¹   zCurrent working directoryzFSearch in all files and directories present on the current Spyder pathr   ZProjectzSSearch in all files and directories present on the current project path (if opened)r#   ZFiler´   zSearch in current opened filer$   é   zSelect other directoryz1Search in other folder present on the file systemr%   zClear this listz#Clear the list of other directoriesr&   é   )rV   rW   ZsetSizePolicyr   Z	ExpandingZFixedÚ
setToolTiprx   ZsetEditablerp   Úproject_pathÚ	file_pathÚexternal_pathÚIDÚaddItemÚsetItemDatar   ÚToolTipRoleÚmodelr°   Ú
setEnabledÚreplaceZinsertSeparatorÚadd_external_pathZcurrentIndexChangedÚconnectÚpath_selection_changedÚviewZinstallEventFilter)rj   Zexternal_path_historyrk   Úid_Zttiprp   rl   r7   r8   rW   ´  s@    


zSearchInComboBox.__init__c                 C   s`   t  |¡sdS |  |  |¡¡ |  |¡ |  |  ¡ d |tj¡ |  ¡ t	t
 kr\|  t
¡ q@dS )a@  
        Adds an external path to the combobox if it exists on the file system.
        If the path is already listed in the combobox, it is removed from its
        current position and added back at the end. If the maximum number of
        paths is reached, the oldest external path is removed from the list.
        Nr#   )r™   ÚexistsÚ
removeItemZfindTextrØ   rÙ   Úcountr   rÚ   ÚMAX_PATH_HISTORYÚEXTERNAL_PATHS©rj   rp   r7   r7   r8   rÞ   ã  s    

z"SearchInComboBox.add_external_pathc                    s   ‡ fdd„t tˆ  ¡ ƒD ƒS )z<Returns a list of the external paths listed in the combobox.c                    s   g | ]}t ˆ  |¡ƒ‘qS r7   )rÅ   ÚitemText)r¼   Úir|   r7   r8   Ú
<listcomp>ô  s   ÿz7SearchInComboBox.get_external_paths.<locals>.<listcomp>)Úrangerç   rå   r|   r7   r|   r8   Úget_external_pathsò  s    
ÿz#SearchInComboBox.get_external_pathsc                 C   s   |   ¡ tkr|  t¡ q dS )z5Remove all the external paths listed in the combobox.N)rå   rç   rä   r|   r7   r7   r8   Úclear_external_paths÷  s    z%SearchInComboBox.clear_external_pathsc                 C   s<   |   ¡ }|tkr| jS |tkr$| jS |tkr2| jS | jS dS )zh
        Returns the path corresponding to the currently selected item
        in the combobox.
        N)ÚcurrentIndexÚCWDrp   ÚPROJECTrÔ   Ú	FILE_PATHrÕ   rÖ   ©rj   Úidxr7   r7   r8   Úget_current_searchpathü  s    z'SearchInComboBox.get_current_searchpathc                 C   sB   |dur0t ||  ¡ d ƒ}|ttfv r*tn|}nt}|  |¡ dS )z(Set the current index of this combo box.Nr#   )Úminrå   Ú
CLEAR_LISTÚSELECT_OTHERrð   ÚsetCurrentIndex)rj   Úindexr7   r7   r8   Úset_current_searchpath_index  s
    z-SearchInComboBox.set_current_searchpath_indexc                 C   s   |   ¡ tkrdS dS dS )z2Returns whether the current search path is a file.TFN)rï   rò   r|   r7   r7   r8   Úis_file_search  s    zSearchInComboBox.is_file_searchc                 C   s°   |   ¡ }|tkrN|  ¡ }t|ƒdkrB|  |¡ |  |  ¡ d ¡ q¬|  t¡ n^|tkr”t	 
| tdƒtdƒt	jt	jB ¡}|t	jkrˆ|  ¡  |  t¡ n|tkr¬t|  |¡ƒ| _dS )z7Handles when the current index of the combobox changes.r   r#   zClear other directoriesz3Do you want to clear the list of other directories?N)rï   rø   Úselect_directoryrN   rÞ   rù   rå   rð   r÷   r   Zquestionrx   ZYesZNorî   rç   rÅ   ré   rÖ   )rj   rô   rÖ   Zreplyr7   r7   r8   rà     s$    

ý
z'SearchInComboBox.path_selection_changedc                 C   s@   | j  d¡ t| td ƒ| jƒ}|r0tt |¡ƒ}| j  d¡ |S )zSelect directoryFT)Úsig_redirect_stdio_requestedr{   r   rx   rp   r   r™   rš   ©rj   Z	directoryr7   r7   r8   rý   2  s    ýz!SearchInComboBox.select_directoryc                 C   sf   |du r<d| _ |  ¡  td¡ d¡ |  ¡ tkrb|  t¡ n&t 	|¡}|| _ |  ¡  td¡ d¡ dS )z}
        Sets the project path and disables the project search in the combobox
        if the value of path is None.
        Nr   FT)
rÔ   rÛ   r°   rñ   rÜ   rï   rù   rð   r™   rš   rè   r7   r7   r8   Úset_project_pathA  s    
z!SearchInComboBox.set_project_pathc                 C   sž   |  ¡ tjkr| ¡ tjkr|  ¡  ¡  ¡ }|t	krŒ|  
|¡ |  ¡  t|  ¡ d |ƒ}|t	k rddn|}|  ¡  |  ¡  |d¡¡ |  |¡ dS t | ||¡S )z;Used to handle key events on the QListView of the combobox.r#   r   T)Útyper   ZKeyPressÚkeyr   Z
Key_Deleterá   rï   Úrowrç   rä   Z	showPopuprö   rå   rù   rÛ   rú   r   ÚeventFilter)rj   ÚwidgetZeventrú   Z	new_indexr7   r7   r8   r  P  s    

zSearchInComboBox.eventFilter)r-   r.   r/   rÌ   r	   rÍ   rþ   rW   rÞ   rí   rî   rõ   rû   rü   r
   rà   rý   r   r  rÏ   r7   r7   rl   r8   rÐ   «  s   /


rÐ   c                       sF   e Zd Zd‡ fdd„	Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Z‡  Z	S )ÚLineMatchItemNc                    s:   || _ || _|| _|| _|| _tƒ  ||  ¡ gtj	¡ d S rº   )
r    r®   r¤   r[   ÚfontrV   rW   Ú__repr__r   ÚType)rj   rk   r    r®   r¤   r  r[   rl   r7   r8   rW   c  s    zLineMatchItem.__init__c                 C   s0   t | jƒ ¡ }d}| | j ¡ | j| j|| j¡S )Nz{<!-- LineMatchItem --><p style="color:'{4}';"><b>{1}</b> ({2}): <span style='font-family:{0};font-size:75%;'>{3}</span></p>)	rÅ   r¤   ÚrstriprÇ   r  Zfamilyr    r®   r[   )rj   r¤   Ú_strr7   r7   r8   r  l  s
    ÿzLineMatchItem.__repr__c                 C   s   |   ¡ S rº   ©r  r|   r7   r7   r8   Ú__unicode__u  s    zLineMatchItem.__unicode__c                 C   s   |   ¡ S rº   r  r|   r7   r7   r8   Ú__str__x  s    zLineMatchItem.__str__c                 C   s   | j |j k S rº   ©r    ©rj   Úxr7   r7   r8   Ú__lt__{  s    zLineMatchItem.__lt__c                 C   s   | j |j kS rº   r  r  r7   r7   r8   Ú__ge__~  s    zLineMatchItem.__ge__)N)
r-   r.   r/   rW   r  r  r  r  r  rÏ   r7   r7   rl   r8   r  a  s    ÿ		r  c                       s.   e Zd Zd‡ fdd„	Zdd„ Zdd„ Z‡  ZS )	ÚFileMatchItemNc                    sT   || _ t |¡| _d}| t |¡t |¡|¡}tƒ  ||gtj	¡ |  
d|¡ d S )Nzq<!-- FileMatchItem --><b style="color:{2}">{0}</b>&nbsp;&nbsp;&nbsp;<small style="color:{2}"><em>{1}</em></small>r   )Úsortingr™   ÚbasenamerŒ   rÇ   rŠ   rV   rW   r   r	  rÓ   )rj   rk   rŒ   r  r[   Ztitle_formatr±   rl   r7   r8   rW   „  s    þzFileMatchItem.__init__c                 C   s"   | j d tkr| j|jk S dS d S ©NÚstatusF©r  ÚONrŒ   r  r7   r7   r8   r  •  s    zFileMatchItem.__lt__c                 C   s"   | j d tkr| j|jkS dS d S r  r  r  r7   r7   r8   r  ›  s    zFileMatchItem.__ge__)N)r-   r.   r/   rW   r  r  rÏ   r7   r7   rl   r8   r  ‚  s   r  c                       s,   e Zd Z‡ fdd„Zdd„ Zdd„ Z‡  ZS )ÚItemDelegatec                    s   t ƒ  |¡ d | _d S rº   )rV   rW   Z_margin)rj   rk   rl   r7   r8   rW   ¤  s    zItemDelegate.__init__c           
      C   sÆ   t |ƒ}|  ||¡ |jd u r&t ¡ n|j ¡ }tƒ }|j}| |¡ | d¡ d|_| 	t
j||¡ t ¡ }| t
j|d ¡}	| ¡  | |	 ¡ ¡ | |	 |	 ¡  ¡¡ | ¡  ||¡ | ¡  d S )Nr   r¹   )r   ÚinitStyleOptionr  r   Ústyler   rQ   ÚsetHtmlZsetDocumentMarginZdrawControlr   ZCE_ItemViewItemr   ZPaintContextZsubElementRectZSE_ItemViewItemTextZsaveÚ	translateZtopLeftZsetClipRectZ
translatedZdocumentLayoutZdrawZrestore)
rj   ZpainterÚoptionrú   Úoptionsr  ÚdocrQ   ÚctxZtextRectr7   r7   r8   Úpaint¨  s(    ÿ

ÿzItemDelegate.paintc                 C   sX   t |ƒ}|  ||¡ tƒ }| |j¡ | |j ¡ ¡ tt	| 
¡ ƒt	| ¡  ¡ ƒƒ}|S rº   )r   r  r   r  rQ   ZsetTextWidthZrectÚwidthr   rO   Z
idealWidthÚsizeZheight)rj   r   rú   r!  r"  r&  r7   r7   r8   ÚsizeHintÄ  s    zItemDelegate.sizeHint)r-   r.   r/   rW   r$  r'  rÏ   r7   r7   rl   r8   r  ¢  s   r  c                       sŽ   e Zd ZeeeeeeƒZeƒ Zd‡ fdd„	Zdd„ Z	dd„ Z
eeƒd	d
„ ƒZdd„ Zdd„ Zeeƒdd„ ƒZeeeƒdd„ ƒZdd„ Z‡  ZS )ÚResultsBrowserNéè  c                    sÀ   t ƒ  |¡ d | _d | _|| _d | _d | _d | _i | _t	ƒ | _
d | _d | _d | _|| _|  d¡ |  t¡ |  d¡ |  t| ƒ¡ |  d¡ |  dtj¡ | jd d… | _|  ¡ j | j¡ d S )Nr¹   FTr   r$   )rV   rW   rZ   rf   Úmax_resultsr]   r^   rc   r  r   r  Údatarh   Z
root_itemsr[   Ú	set_titleÚset_sortingÚOFFÚsetSortingEnabledZsetItemDelegater  ZsetUniformRowHeightsZsortByColumnr   ZAscendingOrderZcommon_actionsÚheaderZsectionClickedrß   Úsort_section)rj   rk   r[   r*  rl   r7   r8   rW   Ò  s*    



zResultsBrowser.__init__c                 C   sF   | j  t|  ¡ ƒ¡}|durB|\}}}}| j ||| j||| ¡ dS )zDouble-click event.N)r+  r»   ÚidZcurrentItemÚsig_edit_goto_requestedr{   rZ   )rj   r°   ZitemdatarŒ   r    r®   Zcolendr7   r7   r8   Ú	activatedð  s    ÿzResultsBrowser.activatedc                 C   s    || j d< |  ¡  |tk¡ dS )z/Enable result sorting after search is complete.r  N)r  r0  ZsetSectionsClickabler  )rj   Úflagr7   r7   r8   r-  ø  s    
zResultsBrowser.set_sortingc                 C   s   |   d¡ d S r~   )r/  ró   r7   r7   r8   r1  ý  s    zResultsBrowser.sort_sectionc                 C   s   |   |¡ dS )zClick event.N)r4  )rj   r°   r7   r7   r8   Úclicked  s    zResultsBrowser.clickedc                 C   s^   t ƒ | _|  ¡  |  d¡ d| _i | _i | _|  t¡ || _	d| }t
dƒ}|  || ¡ d S )NFr   r¥   r¦   )r   r  Úclearr/  rg   r+  rh   r-  r.  rZ   rx   r,  )rj   rZ   r±   rQ   r7   r7   r8   Úclear_title  s    

zResultsBrowser.clear_titlec                 C   sJ   t | jƒ| jk rFt| || j| jƒ| j|< | j|  d¡ |  jd7  _dS )zReal-time update of file items.Tr#   N)	rN   r+  r*  r  r  r[   rh   ZsetExpandedrg   )rj   rŒ   r7   r7   r8   Úappend_file_result  s    ÿ
z!ResultsBrowser.append_file_resultc                 C   sÌ   t | jƒ| jkr,|  tdƒ¡ | j ¡  dS | jt | jƒ }|t |ƒk rT|d|… }|  d¡ |  |¡ |D ]P}|\}}}}}	| j 	|d¡}
|
rlt
|
|||| j| jƒ}||||	f| jt|ƒ< ql|  d¡ dS )zReal-time update of line items.z<Maximum number of results reached! Try narrowing the search.NFT)rN   r+  r*  r,  rx   Úsig_max_results_reachedr{   ZsetUpdatesEnabledrh   r»   r  r  r[   r2  )rj   r¬   r±   Z	availabler°   rŒ   r    r®   r¡   r¯   Z	file_itemr7   r7   r8   Úappend_result  s$    



ÿzResultsBrowser.append_resultc                 C   s
   || _ dS )z%Set maximum amount of results to add.N)r*  ©rj   Úvaluer7   r7   r8   Úset_max_results3  s    zResultsBrowser.set_max_results)Nr)  )r-   r.   r/   r	   rÅ   rO   r3  r:  rW   r4  r-  r
   r1  r6  r8  rÎ   r9  r;  r>  rÏ   r7   r7   rl   r8   r(  Î  s   


r(  c                       s<  e Zd ZdZdZdej› dZedƒZ	e
eeeeeƒZe
ƒ Ze
ƒ Zd=‡ fdd„	Zd	d
„ Zdd„ Zdd„ Zdd„ Zedddd„ ƒZedddd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zd>d!d"„Zed#d$„ ƒZed%d&„ ƒZed'd(„ ƒZ d)d*„ Z!d+d,„ Z"d-d.„ Z#d/d0„ Z$d1d2„ Z%d3d4„ Z&d5d6„ Z'd7d8„ Z(d9d:„ Z)d?d;d<„Z*‡  Z+S )@ÚFindInFilesWidgetz
    Find in files widget.
    Tzbackground-color:ú;zRegular expression errorNc           
         s@  t ƒ j|||d ˆ  dt¡ ˆ  dt¡ ˆ  d¡ˆ _ˆ  d¡ˆ _d ˆ _dˆ _	d ˆ _
d ˆ _ˆ  dd¡}ˆ  dg ¡}ˆ  d	¡}t|ttfƒs|g}t|ttfƒs¤|g}t|ttfƒs¸|g}tˆ |td
ƒtjdˆ _ttdƒƒˆ _tjˆ j_ttdƒƒˆ _tjˆ j_t|ˆ tjdˆ _tˆ |tdƒtjdˆ _tˆ ˆ jˆ  d¡dˆ _ ˆ j !ˆ j¡ ˆ  dd ¡}|d urŒ|dkrŒ|ˆ j "¡ k rŒˆ j #|¡ ˆ  dd ¡}ˆ j $|¡ t%ƒ }	|	 &ˆ j ¡ ˆ  '|	¡ ˆ jj( )ˆ j(¡ ˆ jj* )‡ fdd„¡ ˆ jj* )‡ fdd„¡ ˆ j j+ )ˆ j+¡ ˆ j j, )ˆ j,¡ ˆ j j, )ˆ j-¡ ˆ jj. )ˆ j/¡ d S )N)rk   r[   Ú
hist_limitÚsupported_encodingsFrZ   r¹   Úpath_historyr`   zSearch pattern)râ   z
Search in:zExclude:zExclude patternr*  )r[   r*  Úexclude_indexr   Úsearch_in_indexc                    s   ˆ   ¡ S rº   ©r“   ©Úvalidr|   r7   r8   Ú<lambda>¬  rÀ   z,FindInFilesWidget.__init__.<locals>.<lambda>c                    s   ˆ   ¡ S rº   rF  rG  r|   r7   r8   rI  ­  rÀ   )0rV   rW   Úset_confÚMAIN_TEXT_COLORræ   Úget_confr[   rB  Úsearch_threadÚrunningÚmore_options_actionÚextras_toolbarÚ
isinstanceÚlistÚtupler!   rx   rC   rF   Úsearch_text_editr   rD   rG   r×   rE   rH   rÐ   rK   Úpath_selection_comborI   Úexclude_pattern_editr(  Úresult_browserZsetBuddyrå   rù   rû   r   Z	addWidgetZ	setLayoutrþ   rß   rH  r3  r:  Ú_stop_and_reset_threadZsig_resizedÚ_update_size)
rj   ÚnameÚpluginrk   rZ   rC  r`   Zexclude_idxrE  Zlayoutrl   r|   r8   rW   `  sŽ    
ü

þüýÿÿ
ÿÿÿÿzFindInFilesWidget.__init__c                 C   s   t dƒS )Nr0   )rx   r|   r7   r7   r8   Ú	get_title¸  s    zFindInFilesWidget.get_titlec                 C   s   | j S rº   )rT  r|   r7   r7   r8   Úget_focus_widget»  s    z"FindInFilesWidget.get_focus_widgetc              	      s  ˆ j tjtdƒtdƒˆ  d¡dˆ  d¡ddˆ _ˆ j tjtdƒtdƒˆ  d¡dˆ  d¡ddˆ _ˆ j tj	td	ƒtd
ƒˆ  d¡ˆ j
ddˆ _ˆ j tjtdƒtdƒˆ  d¡dˆ  d¡ddˆ _ˆ j tjtdƒtdƒˆ  d¡dˆ  d¡ddˆ _ˆ j tjtdƒtdƒˆ  d¡dˆ  d¡ddˆ _ˆ j tjtdƒtdƒd‡ fdd„	dˆ _ˆ  ¡ }ˆ jˆ jˆ jˆ jˆ jfD ]}ˆ j||tjd qbˆ  tj¡ˆ _ˆ  ¡ }tj|_ ˆ j!ˆ j"ˆ j|fD ]}ˆ j|ˆ jt#jd q¬ˆ  tj$¡}ˆ j%ˆ j&fD ]}ˆ j||t'jd qàˆ  (¡ }ˆ j)ˆ j|d d S )NzRegular expressionZregexTZsearch_text_regexp)rQ   ÚtipÚiconZtoggledÚinitialr   zCase sensitiveZformat_letter_caserd   z&Find in fileszSearch text in multiple filesr“   F)rQ   r^  r_  Ú	triggeredZregister_shortcutZexclude_regexpzExclude case sensitiveZexclude_case_sensitiveúShow advanced optionsÚoptions_moreÚmore_optionszSet maximum number of resultsc                    s   ˆ   ¡ S rº   )r>  )r  r|   r7   r8   rI  ø  rÀ   z)FindInFilesWidget.setup.<locals>.<lambda>)rQ   r^  ra  )ÚtoolbarZsection)Úmenu)N)*Zcreate_actionr+   r6   rx   Úcreate_iconrL  Úsearch_regexp_actionr3   Úcase_actionr0   r“   r,   r4   Úexclude_regexp_actionr2   Zexclude_case_actionr5   rO  r1   Zset_max_results_actionZget_main_toolbarrT  Zadd_item_to_toolbarr=   r@   Zcreate_toolbarr9   r;   rP  Zcreate_stretcherrC   rJ   r×   rE   rV  rA   r<   rD   rU  rB   Zget_options_menuZadd_item_to_menu)rj   re  r°   Z	stretcherr:   rf  r7   r|   r8   Úsetup¾  sÀ    ù	ù	úù	ù	ù	üþý
ÿÿý
ÿý
þzFindInFilesWidget.setupc                 C   s>   | j  |  | jrdnd¡¡ | jr:| jr:| j | j ¡ ¡ d S )Nry   r“   )r,   ÚsetIconrg  rN  rP  rO  Ú
setVisibleÚ	isCheckedr|   r7   r7   r8   Úupdate_actions$  s    
ÿÿz FindInFilesWidget.update_actionsrd  )r   c                 C   sp   | j  | j ¡ ¡ |r*|  d¡}tdƒ}n|  d¡}tdƒ}| jrN| j |¡ | jrl| j 	|¡ | j 
|¡ d S )NZoptions_lesszHide advanced optionsrc  rb  )rV  ÚsetMinimumWidthrT  r%  rg  rx   rP  rm  rO  rl  rÓ   )rj   r=  r_  r^  r7   r7   r8   Úon_more_options_update,  s    ÿ


z(FindInFilesWidget.on_more_options_updater*  c                 C   s   | j  |¡ d S rº   )rW  r>  r<  r7   r7   r8   Úon_max_results_update?  s    z'FindInFilesWidget.on_max_results_updatec                 C   s   | j  | ¡ ¡ d S rº   )rV  rp  r%  )rj   r&  Zold_sizer7   r7   r8   rY  E  s    zFindInFilesWidget._update_sizec                 C   sì  | j  ¡ }| j ¡ }| j ¡ }| j ¡  d¡ | j ¡  d¡ | j d¡ | j d¡ t	| j 
¡ ƒ}|sldS z| d¡dfg}W nN tyÎ   g }| jD ]0}z| | |¡|f¡ W q˜ tyÆ   Y q˜0 q˜Y n0 t	| j 
¡ ƒ}|sðdd„ |D ƒ}| j ¡ }| j ¡ }	|s(dd„ | d¡D ƒ}
d |
¡}|r~t|ƒ}|rt| j ¡ }| | j¡ | jd	 t	|ƒ }| j |¡ dS t |¡}|rÜt|d
 d
 ƒ}|rÎ| j ¡  | j¡ | jd	 t	|ƒ }| j |¡ dS dd„ |D ƒ}|	|||||fS )z%
        Get search options.
        r¹   Nzutf-8c                 S   s    g | ]}|d    ¡ |d f‘qS ©r   r#   )r’   )r¼   rQ   r7   r7   r8   rë   g  rÀ   z2FindInFilesWidget._get_options.<locals>.<listcomp>c                 S   s&   g | ]}|  ¡ d krt |  ¡ ¡‘qS )r¹   )ÚstripÚfnmatchr  )r¼   r°   r7   r7   r8   rë   m  s   þú,ú|z: r   c                 S   s"   g | ]}t  |d  ¡|d f‘qS rs  )rn   ro   )r¼   r  r7   r7   r8   rë   ˆ  rÀ   )rh  rn  rj  ri  rT  ÚlineEditZsetStyleSheetrV  rÓ   rÅ   ÚcurrentTextÚencodeÚUnicodeEncodeErrorrB  r   r•   rU  rü   rõ   rÆ   r‚   r   ÚREGEX_INVALIDÚREGEX_ERRORrn   ro   )rj   rb   Z
exclude_rerd   Zutextra   r¢   r`   Zfile_searchrp   r¬   Z	error_msgZexclude_editZtooltipr7   r7   r8   Ú_get_optionsH  sb    





ÿ



ÿzFindInFilesWidget._get_optionsc                    s¾   ˆ   d¡}‡ fdd„tˆ j ¡ ƒD ƒ}‡ fdd„tˆ j ¡ ƒD ƒ}ˆ j ¡ }ˆ  d|¡ ˆ  d|d|… ¡ ˆ  d|d|… ¡ ˆ  d|| d… ¡ ˆ  d	ˆ j ¡ ¡ ˆ  d
ˆ j ¡ ¡ dS )zW
        Extract search options from widgets and set the corresponding option.
        rA  c                    s   g | ]}t ˆ j |¡ƒ‘qS r7   )rÅ   rT  ré   ©r¼   rú   r|   r7   r8   rë   ‘  s   ÿz5FindInFilesWidget._update_options.<locals>.<listcomp>c                    s   g | ]}t ˆ j |¡ƒ‘qS r7   )rÅ   rV  ré   r  r|   r7   r8   rë   “  s   ÿrC  rZ   Nr`   rD  rE  )	rL  rì   rT  rå   rV  rU  rí   rJ  rï   )rj   rA  Zsearch_textsZexcludesrC  r7   r|   r8   Ú_update_optionsŒ  s$    

ÿ
ÿ

ÿ
ÿz!FindInFilesWidget._update_optionsc                 C   sf   | j  t¡ | j  ¡  | jdu r$dS | j ¡  | j ¡ }|  ¡  |durR| j  	¡  |  
¡  |  ¡  dS )z5
        Current search thread has finished.
        N)rW  r-  r  Z	expandAllrM  rz   r{   rË   rX  ÚshowÚstop_spinnerro  )rj   rc   r£   r7   r7   r8   Ú_handle_search_complete   s    




z)FindInFilesWidget._handle_search_completeFc                 C   sh   | j durN| j  ¡ r<|r(| j j | j¡ | j  ¡  | j  ¡  | j  d¡ d| _ d| _|  	¡  |  
¡  dS )z(Stop current search thread and clean-up.NF)rM  Z	isRunningrz   Z
disconnectZsearch_completery   ÚwaitZ	setParentrN  r‚  ro  )rj   Úignore_resultsr7   r7   r8   rX  ²  s    

ÿ

z(FindInFilesWidget._stop_and_reset_threadc                 C   s   | j jS )zReturn the current path.)rU  rp   r|   r7   r7   r8   rp   Å  s    zFindInFilesWidget.pathc                 C   s   | j jS )z Return the current project path.)rU  rÔ   r|   r7   r7   r8   rÔ   Ê  s    zFindInFilesWidget.project_pathc                 C   s   | j jS )zReturn the current file path.©rU  rÕ   r|   r7   r7   r8   rÕ   Ï  s    zFindInFilesWidget.file_pathc                 C   s   t  |¡| j_dS )z‘
        Set directory as current path.

        Parameters
        ----------
        directory: str
            Directory path string.
        N)r™   rš   rU  rp   rÿ   r7   r7   r8   Úset_directoryÔ  s    	zFindInFilesWidget.set_directoryc                 C   s   | j  |¡ dS )z
        Set path as current project path.

        Parameters
        ----------
        path: str
            Project path string.
        N©rU  r   rè   r7   r7   r8   r   ß  s    	z"FindInFilesWidget.set_project_pathc                 C   s   | j  d¡ dS )z(Disable project search path in combobox.Nrˆ  r|   r7   r7   r8   Údisable_project_searchê  s    z(FindInFilesWidget.disable_project_searchc                 C   s   || j _dS )z‡
        Set path as current file path.

        Parameters
        ----------
        path: str
            File path string.
        Nr†  rè   r7   r7   r8   Úset_file_pathî  s    	zFindInFilesWidget.set_file_pathc                 C   s,   |r| j  |¡ | j  ¡  ¡  | j  ¡  dS )a  
        Set current search text.

        Parameters
        ----------
        text: str
            Search string.

        Notes
        -----
        If `text` is empty, focus will be given to the search lineedit and no
        search will be performed.
        N)rT  Zadd_textrx  Z	selectAllZsetFocus)rj   rQ   r7   r7   r8   Úset_search_textù  s    z!FindInFilesWidget.set_search_textc                 C   s   | j r|  ¡  n|  ¡  dS )zÂ
        Start/stop find action.

        Notes
        -----
        If there is no search running, this will start the search. If there is
        a search running, this will stop it.
        N)rN  ry   r—   r|   r7   r7   r8   r“     s    	
zFindInFilesWidget.findc                 C   s   |   ¡  dS )zStop find thread.N)rX  r|   r7   r7   r8   ry     s    zFindInFilesWidget.stopc                 C   s¶   |   ¡ }|du rdS | jdd | j ¡ }|  ¡  d| _|  ¡  t| || jƒ| _	| j	j
 | j¡ | j	j | jj¡ | j	j | jj¡ | j |¡ | j	j|   ¡ Ž  | j	 ¡  |  ¡  dS )zStart find thread.NT)r…  )r~  rX  rT  ry  r€  rN  Zstart_spinnerrT   r[   rM  rz   rß   rƒ  r©   rW  r9  r«   r;  r8  rq   r—   ro  )rj   r!  rZ   r7   r7   r8   r—     s(    
ÿÿ
zFindInFilesWidget.startc                 C   s   | j  |¡ dS )zf
        Parameters
        ----------
        path: str
            Path to add to combobox.
        N)rU  rÞ   rè   r7   r7   r8   rÞ   ;  s    z#FindInFilesWidget.add_external_pathc                    s–   |du r†t ˆ ƒ}| d¡ | ˆ  ¡ ¡ | tdƒ¡ | t j¡ | dd¡ | 	d¡ | 
ˆ  d¡¡ |j ‡ fdd„¡ | ¡  nˆ  d|¡ dS )	zó
        Set maximum amount of results to add to the result browser.

        Parameters
        ----------
        value: int, optional
            Number of results. If None an input dialog will be used.
            Default is None.
        NFzSet maximum number of results: r#   i'  r*  c                    s   ˆ   d| ¡S )Nr*  )rJ  )r=  r|   r7   r8   rI  ]  rÀ   z3FindInFilesWidget.set_max_results.<locals>.<lambda>)r   ZsetModalZsetWindowTitleZget_nameZsetLabelTextrx   ZsetInputModeZIntInputZsetIntRangeZ
setIntStepZsetIntValuerL  ZintValueSelectedrß   r  rJ  )rj   r=  Zdialogr7   r|   r8   r>  D  s    



ÿ
z!FindInFilesWidget.set_max_results)NNN)F)N),r-   r.   r/   rÌ   ZENABLE_SPINNERr   ZCOLOR_ERROR_2r|  rx   r}  r	   rÅ   rO   r3  rz   r:  rW   r\  r]  rk  ro  r   rq  rr  rY  r~  r€  rƒ  rX  Úpropertyrp   rÔ   rÕ   r‡  r   r‰  rŠ  r‹  r“   ry   r—   rÞ   r>  rÏ   r7   r7   rl   r8   r?  8  sJ   Xf

D



	r?  c            	      C   sÎ   ddl m}  ddl}ddlm} ddlm} |ƒ }|ƒ }d|_td|d}d|_| 	¡  | 
¡  | dd	¡ | ¡  | tƒ| | tƒƒ| | | tƒƒƒ| | | | tƒƒƒƒg}|D ]}| |¡ q¬| | ¡ ¡ dS )
z(
    Run Find in Files widget test.
    r   )rŠ   N)Ú	MagicMock)ÚqapplicationZfind_in_files)r[  i€  ià  )Úos.pathrŠ   ÚsysZunittest.mockr  Zspyder.utils.qthelpersrŽ  ZCONF_SECTIONr?  Ú_setuprk  Zresizer  Ú__file__rÞ   ÚexitZexec_)	rŠ   r  r  rŽ  ZappZplugin_mockr  Zexternal_pathsrp   r7   r7   r8   Útestd  s*    
ür”  Ú__main__)UrÌ   ru  rP   r€   r  rp   r™   rn   rv   Zqtpy.compatr   Zqtpy.QtCorer   r   r   r   r   r   r	   r
   Z
qtpy.QtGuir   r   Zqtpy.QtWidgetsr   r   r   r   r   r   r   r   r   r   r   Zspyder.api.config.decoratorsr   Zspyder.api.translationsr   Zspyder.api.widgets.main_widgetr   Zspyder.config.guir   Zspyder.utils.encodingr   r   Zspyder.utils.miscr   Zspyder.utils.paletter   r    Zspyder.widgets.comboboxesr!   Zspyder.widgets.onecolumntreer"   rx   ZCOLOR_TEXT_1rK  r  r.  rð   rñ   rò   rø   r÷   rç   rM   ræ   ZEXTRA_BUTTON_PADDINGr+   r9   r=   rA   rB   rC   rS   rT   rÐ   r  r  r  r(  r?  r”  r-   r7   r7   r7   r8   Ú<module>   sp   (4  < 7! ,j    0!
