B
    nôb\Åš  ã               @   sD  d Z ddlmZm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ZddlZddl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 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&m'Z' ddl(m)Z) dd	l*m+Z+ dd
l,m-Z-m.Z. ddl/m0Z1 ddl2m3Z3m4Z4 ddl5m6Z6 ddl7m8Z8 ddl9m:Z: ddl5m;Z; ddl<m=Z=m>Z> ddl?m@Z@ ddlAmBZB dZCdZDdZEdZFdZGdZHdZIdZJdZKdZLdd„ ZMG dd „ d eƒZNG d!d"„ d"eƒZOG d#d$„ d$e'ƒZPG d%d&„ d&e%ƒZQG d'd(„ d(e%ƒZRG d)d*„ d*e#ƒZSG d+d,„ d,e:ƒZTG d-d.„ d.e'ƒZUG d/d0„ d0e'ƒZVd1d2„ ZWeXd3kr@eWƒ  dS )4zFind in files widgeté    )Úwith_statementÚprint_functionN)Úgetexistingdirectory)ÚQAbstractTextDocumentLayoutÚQTextDocument)ÚQEventÚQMutexÚQMutexLockerÚQSizeÚQtÚQThreadÚSignalÚSlot)ÚQApplicationÚ	QComboBoxÚQHBoxLayoutÚQLabelÚQMessageBoxÚQSizePolicyÚQStyleÚQStyledItemDelegateÚQStyleOptionViewItemÚQTreeWidgetItemÚQVBoxLayoutÚQWidget)Ú_)ÚEXCLUDE_PATTERNS)Úto_text_stringÚPY2)Úicon_manager)Úis_text_fileÚto_unicode_from_fs)Úgetcwd_or_home)ÚPatternComboBox)ÚOneColumnTree)Úregexp_error_msg)Úcreate_toolbuttonÚget_icon)Úget_font)ÚQWaitingSpinnerZonZoffé   é   é   é   é   é<   é   c             C   sN   d}t t|ƒ d }| d tt |¡ƒ… }| tt |¡ƒ d … }|| | S )Nz...g       @)ÚMAX_PATH_LENGTHÚlenÚintÚmathZceilZfloor)ÚtextÚellipsisZpart_lenZ	left_textZ
right_text© r7   ú9lib/python3.7/site-packages/spyder/widgets/findinfiles.pyÚtruncate_path?   s
    r9   c               @   sr   e Zd ZdZeeƒZeeƒZeeƒZ	ee
eƒZeeƒZdd„ Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ Zdd„ ZdS )ÚSearchThreadzFind in files search threadc             C   sl   t  | |¡ tƒ | _d | _d | _d | _d | _d | _d | _	d | _
d | _d | _d | _d| _i | _d| _d| _d S )NTr   F)r   Ú__init__r   ÚmutexÚstoppedÚresultsÚpathlistÚtotal_matchesÚ
error_flagÚrootpathÚexcludeÚtextsÚtext_reÚ	completedÚcase_sensitiveÚis_file)ÚselfÚparentr7   r7   r8   r;   O   s     zSearchThread.__init__c             C   s>   || _ |rt |¡| _|| _|| _|| _d| _d| _|| _	d S )NF)
rB   ÚreÚcompilerC   rD   rE   rH   r=   rF   rG   )rI   ÚpathrH   rC   rD   rE   rG   r7   r7   r8   Ú
initializea   s    zSearchThread.initializec             C   sl   y*g | _ | jr|  | j¡ n|  | j¡ W n& tk
rP   t ¡  tdƒ| _	Y nX |  
¡  | j | j¡ d S )Nz&Unexpected error: see internal console)Ú	filenamesrH   Úfind_string_in_filerB   Úfind_files_in_pathÚ	ExceptionÚ	tracebackÚ	print_excr   rA   ÚstopÚsig_finishedÚemitrF   )rI   r7   r7   r8   Úrunm   s    zSearchThread.runc          	   C   s    t | jƒ d| _W d Q R X d S )NT)r	   r<   r=   )rI   r7   r7   r8   rU   }   s    zSearchThread.stopc             C   sr  | j d krg | _ | j  |¡ xNt |¡D ]>\}}}t| jƒ | jrLdS W d Q R X yðx‚|d d … D ]r}t| jƒ | jr€dS W d Q R X tj ||¡}| j	r¾t
 | j	|tj ¡r¾| |¡ qf|dksÎ|dkrf| |¡ qfW xf|D ]^}t| jƒ | jrüdS W d Q R X tj ||¡}| j	r.t
 | j	|¡r.qât|ƒrâ|  |¡ qâW W q* t
jk
rh   tdƒ| _dS X q*W dS )NFz.gitz.hgzinvalid regular expressionT)r?   ÚappendÚosÚwalkr	   r<   r=   rM   ÚjoinrC   rK   ÚsearchÚsepÚremover    rP   Úerrorr   rA   )rI   rM   ÚdirsÚfilesÚdÚdirnameÚfÚfilenamer7   r7   r8   rQ      s>    



zSearchThread.find_files_in_pathc             C   sP  d| _ | j |¡ yøxðtt|dƒƒD ]Ü\}}xv| jD ]l\}}t| jƒ | jrXdS W d Q R X |}| j	st| 
¡ }| jr’t ||¡}|d k	r¦P q:| |¡}|dkr:P q:W y| |¡}W n tk
rÐ   |}Y nX | j	sà| 
¡ }| jr\xpt ||¡D ]`}	t| jƒ | jrdS W d Q R X |  jd7  _| j t |¡|d |	 ¡ |	 ¡ |f| j¡ qöW q(| |¡}xž|dkrt| jƒ | jrŠdS W d Q R X |  jd7  _| j t |¡|d ||t|ƒ |f| j¡ x0| jD ]&\}}| ||d ¡}|dkrÖP qÖW qhW q(W W n8 tk
rD }
 z|
j\}}tdƒ| _ W d d }
~
X Y nX d| _d S )NFÚrbéÿÿÿÿr*   z)permission denied errors were encounteredT)rA   Úsig_current_filerW   Ú	enumerateÚopenrD   r	   r<   r=   rG   ÚlowerrE   rK   r]   ÚfindÚdecodeÚUnicodeDecodeErrorÚfinditerr@   Úsig_file_matchÚospÚabspathÚstartÚendr2   ÚIOErrorÚargsr   rF   )rI   ÚfnameÚlinenoÚliner5   ÚencZline_searchÚfoundZline_decÚmatchZxxx_todo_changemeZ_errnoZ	_strerrorr7   r7   r8   rP   ¢   sl    





z SearchThread.find_string_in_filec             C   s   | j | j| j| jfS )N)r>   r?   r@   rA   )rI   r7   r7   r8   Úget_resultsÜ   s    zSearchThread.get_resultsN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚboolrV   Ústrri   Úsig_current_folderÚtupler3   rq   ÚobjectÚsig_out_printr;   rN   rX   rU   rQ   rP   r~   r7   r7   r7   r8   r:   G   s   
!:r:   c                   s‚   e Zd ZdZg df‡ f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dd„ Z‡  ZS )ÚSearchInComboBoxz[
    Non editable combo box handling the path locations of the FindOptions
    widget.
    Nc                sv  t t| ƒ |¡ |  tjtj¡ |  tdƒ¡ |  	d¡ d| _
d | _d | _d | _|  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¡ x|D ]}|  |¡ qBW | j | j¡ |  ¡  | ¡ d S )NzSearch directoryFÚ 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Fileú&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-   é   )Úsuperr‰   r;   ÚsetSizePolicyr   Ú	ExpandingZFixedÚ
setToolTipr   ZsetEditablerM   Úproject_pathÚ	file_pathÚexternal_pathÚaddItemÚsetItemDatar   ÚToolTipRoleÚmodelÚitemÚ
setEnabledÚreplaceZinsertSeparatorÚadd_external_pathZcurrentIndexChangedÚconnectÚpath_selection_changedÚviewZinstallEventFilter)rI   Úexternal_path_historyrJ   ZttiprM   )Ú	__class__r7   r8   r;   å   s<    



zSearchInComboBox.__init__c             C   sd   t  |¡sdS |  |  |¡¡ |  |¡ |  |  ¡ d |tj¡ x|  ¡ t	t
 kr^|  t
¡ qBW 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*   )rr   ÚexistsÚ
removeItemZfindTextr•   r–   Úcountr   r—   ÚMAX_PATH_HISTORYÚEXTERNAL_PATHS)rI   rM   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)Ú.0Úi)rI   r7   r8   ú
<listcomp>"  s   z7SearchInComboBox.get_external_paths.<locals>.<listcomp>)Úranger¦   r¤   )rI   r7   )rI   r8   Úget_external_paths   s    
z#SearchInComboBox.get_external_pathsc             C   s    x|   ¡ tkr|  t¡ qW dS )z5Remove all the external paths listed in the combobox.N)r¤   r¦   r£   )rI   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ÚCWDrM   ÚPROJECTr’   Ú	FILE_PATHr“   r”   )rI   Úidxr7   r7   r8   Úget_current_searchpath*  s    z'SearchInComboBox.get_current_searchpathc             C   s   |   ¡ tkrdS dS dS )z2Returns whether the current search path is a file.TFN)r®   r±   )rI   r7   r7   r8   Úis_file_search9  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®   ÚSELECT_OTHERÚselect_directoryr2   rœ   ÚsetCurrentIndexr¤   r¯   Ú
CLEAR_LISTr   Zquestionr   ZYesZNor­   r¦   r   r§   r”   )rI   r²   r”   Zreplyr7   r7   r8   rž   @  s"    

z'SearchInComboBox.path_selection_changedc             C   s<   |   d¡ t| td ƒ| jƒ}|r.tt |¡ƒ}|   d¡ |S )zSelect directoryFT)Ú&_SearchInComboBox__redirect_stdio_emitr   r   rM   r!   rr   rs   )rI   Ú	directoryr7   r7   r8   r¶   V  s    

z!SearchInComboBox.select_directoryc             C   sf   |dk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¯   rr   rs   )rI   rM   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	showPopupÚminr¤   r·   r˜   Úindexr   ÚeventFilter)rI   ÚwidgetÚeventrÀ   Z	new_indexr7   r7   r8   rÁ   p  s    

zSearchInComboBox.eventFilterc             C   sJ   |   ¡ }x<|dk	rDy|j |¡ W n tk
r>   |  ¡ }Y q
X P q
W dS )zð
        Searches through the parent tree to see if it is possible to emit the
        redirect_stdio signal.
        This logic allows to test the SearchInComboBox select_directory method
        outside of the FindInFiles plugin.
        N)rJ   Zredirect_stdiorW   ÚAttributeError)rI   ÚvaluerJ   r7   r7   r8   Z__redirect_stdio_emit€  s    
z&SearchInComboBox.__redirect_stdio_emit)r   r€   r   r‚   r;   rœ   r¬   r­   r³   r´   r   rž   r¶   r»   rÁ   r¹   Ú__classcell__r7   r7   )r¡   r8   r‰   à   s   ,r‰   c               @   s¦   e Zd ZdZdZedƒZeƒ Zeƒ Z	dd„ Z
eeƒdd„ ƒZdd	„ Zd
d„ Zd dd„Zedd„ ƒZdd„ Zedd„ ƒZdd„ Zdd„ Zedd„ ƒZdd„ Zdd„ ZdS )!ÚFindOptionszFind widget with optionsz"background-color:rgb(255, 80, 80);zRegular expression errorc                s  t  ˆ |¡ t|ttfƒs |g}t|ttfƒs4|g}t|
ttfƒsH|
g}
|ˆ _tƒ }tˆ |tdƒƒˆ _	t
ˆ tdƒtdƒdˆ _t
ˆ tdƒtdƒdˆ _ˆ j d¡ ˆ j |	¡ ˆ j d¡ ˆ j |¡ dˆ _t
ˆ ˆ jd	ˆ _ˆ j d¡ ˆ j |¡ t
ˆ td
ƒt d¡‡ fdd„tdƒddˆ _ˆ jj ˆ j¡ t
ˆ tdƒt d¡‡ fdd„tdƒddˆ _ˆ j d¡ x0ˆ j	ˆ jˆ jˆ jˆ jˆ jgD ]}| |¡ q†W tƒ }tˆ |tdƒƒˆ _|d k	râ|dkrâ|ˆ j ¡ k râˆ j |¡ t
ˆ tdƒtdƒdˆ _ˆ j d¡ ˆ j |¡ t tdƒƒ}| !ˆ j¡ x"|ˆ jˆ jgD ]}| |¡ q:W tƒ }t tdƒƒ}t"|
|ƒˆ _#| |¡ | ˆ j#¡ ˆ j	j$ ‡ fdd„¡ ˆ jj$ ‡ fdd„¡ t%ƒ }| &dddd¡ | '|¡ | '|¡ | '|¡ |fˆ _ˆ  |¡ ˆ  (|¡ ˆ  )t*j+t*j,¡ d S )NzSearch patternz
regexp.svgzRegular expression)ÚiconÚtipzupper_lower.pngzCase SensitiveTr7   )ZtoggledZSearchrm   c                  s
   ˆ j  ¡ S )N)rm   rW   r7   )rI   r7   r8   Ú<lambda>¾  s    z&FindOptions.__init__.<locals>.<lambda>zStart search)r5   rÈ   Z	triggeredrÉ   Ztext_beside_iconZStoprU   c                  s
   ˆ j  ¡ S )N)rU   rW   r7   )rI   r7   r8   rÊ   Ä  s    zStop searchFzExclude patternr   zExclude:z
Search in:c                s
   ˆ j  ¡ S )N)rm   rW   )Úvalid)rI   r7   r8   rÊ   é  s    c                s
   ˆ j  ¡ S )N)rm   rW   )rË   )rI   r7   r8   rÊ   ê  s    )-r   r;   Ú
isinstanceÚlistr†   Úsupported_encodingsr   r#   r   Úsearch_textr&   r'   Úedit_regexpÚcase_buttonZsetCheckableZ
setCheckedÚmore_widgetsÚtoggle_more_optionsÚmore_optionsÚimarÈ   Ú	ok_buttonÚclickedr   Úupdate_combosÚstop_buttonrš   Ú	addWidgetÚexclude_patternr¤   r·   Úexclude_regexpr   ZsetBuddyr‰   Úpath_selection_comborË   r   ÚsetContentsMarginsÚ	addLayoutÚ	setLayoutr   r   r   ZMinimum)rI   rJ   rÏ   Úsearch_text_regexprC   Úexclude_idxrÜ   rÎ   rÔ   rG   r    Zhlayout1rÂ   Zhlayout2Zexclude_labelZhlayout3Zsearch_on_labelZvlayoutr7   )rI   r8   r;   ™  s”    












zFindOptions.__init__c             C   s   xH| j D ]>}x8t| ¡ ƒD ](}|r*|  ¡ s.|s| |¡ ¡  |¡ qW qW |rbt d¡}t	dƒ}nt d¡}t	dƒ}| j
 |¡ | j
 |¡ d S )NZoptions_lesszHide advanced optionsZoptions_morezShow advanced options)rÒ   r«   r¤   Ú	isVisibleZitemAtrÂ   Z
setVisiblerÕ   rÈ   r   rÔ   ZsetIconr‘   )rI   ÚstateÚlayoutrÀ   rÈ   rÉ   r7   r7   r8   rÓ   ÷  s    


zFindOptions.toggle_more_optionsc             C   s$   | j  ¡ j ¡  | j ¡ j ¡  d S )N)rÏ   ÚlineEditZreturnPressedrW   rÛ   )rI   r7   r7   r8   rØ     s    zFindOptions.update_combosc             C   s,   |r| j  |¡ | j  ¡  ¡  | j  ¡  d S )N)rÏ   Zadd_textræ   Z	selectAllZsetFocus)rI   r5   r7   r7   r8   Úset_search_text
  s    zFindOptions.set_search_textFc                sj  ˆ j  ¡ }ˆ j ¡ }ˆ j ¡ }|rŒ‡ fdd„tˆ j ¡ ƒD ƒ}‡ fdd„tˆ j ¡ ƒD ƒ}ˆ j ¡ }ˆ j	 
¡ }ˆ j ¡ }	||||||	||fS ˆ j ¡  d¡ ˆ j ¡  d¡ ˆ j d¡ ˆ j d¡ tˆ j ¡ ƒ}
|
sÚdS y|
 d¡dfg}W n\ tk
rJ   g }x@ˆ jD ]6}y| |
 |¡|f¡ W n tk
r>   Y nX qW Y nX tˆ j ¡ ƒ}|sndd„ |D ƒ}ˆ j	 ¡ }ˆ j	 ¡ }|s¦dd„ | d	¡D ƒ}d
 |¡}|rüt|ƒ}|ròˆ j ¡ }| ˆ j¡ ˆ jd t|ƒ }ˆ j |¡ dS t |¡}|rZt|d d ƒ}|rLˆ j ¡  ˆ j¡ ˆ jd t|ƒ }ˆ j |¡ dS dd„ |D ƒ}||||||fS )zGet optionsc                s   g | ]}t ˆ j |¡ƒ‘qS r7   )r   rÏ   r§   )r¨   rÀ   )rI   r7   r8   rª     s   z+FindOptions.get_options.<locals>.<listcomp>c                s   g | ]}t ˆ j |¡ƒ‘qS r7   )r   rÛ   r§   )r¨   rÀ   )rI   r7   r8   rª     s   rŠ   Nzutf-8c             S   s    g | ]}|d    ¡ |d f‘qS )r   r*   )rl   )r¨   r5   r7   r7   r8   rª   <  s    c             S   s&   g | ]}|  ¡ d krt |  ¡ ¡‘qS )rŠ   )ÚstripÚfnmatchÚ	translate)r¨   r™   r7   r7   r8   rª   B  s   ú,ú|z: r   c             S   s"   g | ]}t  |d  ¡|d f‘qS )r   r*   )rK   rL   )r¨   Úxr7   r7   r8   rª   \  s    )rÐ   Z	isCheckedrÜ   rÑ   r«   rÏ   r¤   rÛ   r®   rÝ   r¬   rÔ   ræ   ZsetStyleSheetr‘   r   ÚcurrentTextÚencodeÚUnicodeEncodeErrorrÎ   rY   ro   r´   r³   Úsplitr\   r%   ÚREGEX_INVALIDÚREGEX_ERRORrK   rL   )rI   Zto_saverE   Z
exclude_rerG   rÏ   rC   râ   Zpath_historyrÔ   ZutextrD   r{   Zfile_searchrM   ÚitemsZ	error_msgZexclude_editZtooltipr7   )rI   r8   Úget_options  st    












zFindOptions.get_optionsc             C   s   | j jS )N)rÝ   rM   )rI   r7   r7   r8   rM   `  s    zFindOptions.pathc             C   s   t  |¡| j_d S )N)rr   rs   rÝ   rM   )rI   rº   r7   r7   r8   Úset_directoryd  s    zFindOptions.set_directoryc             C   s   | j jS )N)rÝ   r’   )rI   r7   r7   r8   r’   g  s    zFindOptions.project_pathc             C   s   | j  |¡ d S )N)rÝ   r»   )rI   rM   r7   r7   r8   r»   k  s    zFindOptions.set_project_pathc             C   s   | j  d ¡ d S )N)rÝ   r»   )rI   r7   r7   r8   Údisable_project_searchn  s    z"FindOptions.disable_project_searchc             C   s   | j jS )N)rÝ   r“   )rI   r7   r7   r8   r“   q  s    zFindOptions.file_pathc             C   s   || j _d S )N)rÝ   r“   )rI   rM   r7   r7   r8   Úset_file_pathu  s    zFindOptions.set_file_pathc             C   sz   |  ¡ tj@ }|  ¡ tj@ }| ¡ tjtjfkr<| j ¡  n:| ¡ tj	krj|rj|rj|  
¡ j |  ¡  ¡ nt | |¡ dS )z"Reimplemented to handle key eventsN)Z	modifiersr   ZControlModifierZShiftModifierr½   Z	Key_EnterZ
Key_Returnrm   rW   ZKey_FrJ   Ztoggle_visibilityrã   r   ÚkeyPressEvent)rI   rÃ   ZctrlÚshiftr7   r7   r8   rù   x  s    zFindOptions.keyPressEventN)F)r   r€   r   r‚   rò   r   ró   r   rm   rU   r;   r   rƒ   rÓ   rØ   rç   rõ   ÚpropertyrM   rö   r’   r»   r÷   r“   rø   rù   r7   r7   r7   r8   rÇ   ‘  s$   ^
PrÇ   c               @   s<   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ÚLineMatchItemc             C   s.   || _ || _|| _t | ||  ¡ gtj¡ d S )N)ry   Úcolnor}   r   r;   Ú__repr__ÚType)rI   rJ   ry   rý   r}   r7   r7   r8   r;   †  s
    zLineMatchItem.__init__c             C   s4   t | jƒ ¡ }tƒ }t dƒ}| | ¡ | j| j|¡S )NzI<b>{1}</b> ({2}): <span style='font-family:{0};font-size:75%;'>{3}</span>)r   r}   Úrstripr(   ÚformatZfamilyry   rý   )rI   r}   ZfontÚ_strr7   r7   r8   rþ     s    zLineMatchItem.__repr__c             C   s   |   ¡ S )N)rþ   )rI   r7   r7   r8   Ú__unicode__•  s    zLineMatchItem.__unicode__c             C   s   |   ¡ S )N)rþ   )rI   r7   r7   r8   Ú__str__˜  s    zLineMatchItem.__str__c             C   s   | j |j k S )N)ry   )rI   rí   r7   r7   r8   Ú__lt__›  s    zLineMatchItem.__lt__c             C   s   | j |j kS )N)ry   )rI   rí   r7   r7   r8   Ú__ge__ž  s    zLineMatchItem.__ge__N)	r   r€   r   r;   rþ   r  r  r  r  r7   r7   r7   r8   rü   …  s   rü   c               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚFileMatchItemc             C   sV   || _ t |¡| _tdƒ}| t |¡t |¡¡}t | ||gtj	¡ |  
d|¡ d S )Nz)<b>{0}</b><br><small><em>{1}</em></small>r   )Úsortingrr   Úbasenamerf   r   r  rd   r   r;   rÿ   r‘   )rI   rJ   rf   r  Ztitle_formatÚtitler7   r7   r8   r;   £  s    zFileMatchItem.__init__c             C   s"   | j d tkr| j|jk S dS d S )NÚstatusF)r  ÚONrf   )rI   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 )Nr  F)r  r  rf   )rI   rí   r7   r7   r8   r  ·  s    zFileMatchItem.__ge__N)r   r€   r   r;   r  r  r7   r7   r7   r8   r  ¢  s   r  c               @   s$   e Zd Zdd„ Zdd„ Zdd„ ZdS )ÚItemDelegatec             C   s   t  | |¡ d S )N)r   r;   )rI   rJ   r7   r7   r8   r;   ¿  s    zItemDelegate.__init__c       	      C   sÀ   t |ƒ}|  ||¡ |jd kr&t ¡ n|j ¡ }tƒ }| d¡ | |j¡ d|_| 	t
j||¡ t ¡ }| t
j|¡}| ¡  | | ¡ ¡ | | | ¡  ¡¡ | ¡  ||¡ | ¡  d S )Nr   rŠ   )r   ÚinitStyleOptionrÂ   r   Ústyler   ZsetDocumentMarginÚsetHtmlr5   ZdrawControlr   ZCE_ItemViewItemr   ZPaintContextZsubElementRectZSE_ItemViewItemTextZsaverê   ZtopLeftZsetClipRectZ
translatedZdocumentLayoutZdrawZrestore)	rI   ZpainterÚoptionrÀ   Úoptionsr  ÚdocZctxZtextRectr7   r7   r8   ÚpaintÂ  s     

zItemDelegate.paintc             C   sL   t |ƒ}|  ||¡ tƒ }| |j¡ | |j ¡ ¡ t| 	¡ | 
¡  ¡ ƒS )N)r   r  r   r  r5   ZsetTextWidthZrectÚwidthr
   Z
idealWidthÚsizeZheight)rI   r  rÀ   r  r  r7   r7   r8   ÚsizeHintÚ  s    zItemDelegate.sizeHintN)r   r€   r   r;   r  r  r7   r7   r7   r8   r  ¾  s   r  c               @   s^   e Zd Zdd„ Zdd„ Zdd„ Zeeƒdd„ ƒZd	d
„ Z	dd„ Z
dd„ Zeeeƒdd„ ƒZdS )ÚResultsBrowserc             C   sœ   t  | |¡ d | _d | _d | _d | _d | _i | _d | _d | _	|  
d¡ |  t¡ |  d¡ d | _|  dtj¡ |  t| ƒ¡ |  d¡ |  ¡ j | j¡ d S )NrŠ   Fr   )r$   r;   rÏ   r>   r@   rA   rF   r  Údatarb   Ú	set_titleÚset_sortingÚOFFÚsetSortingEnabledZ
root_itemsZsortByColumnr   ZAscendingOrderZsetItemDelegater  ZsetUniformRowHeightsÚheaderZsectionClickedr   Úsort_section)rI   rJ   r7   r7   r8   r;   æ  s"    



zResultsBrowser.__init__c             C   s@   | j  t|  ¡ ƒ¡}|dk	r<|\}}}|  ¡ j ||| j¡ dS )zDouble-click eventN)r  ÚgetÚidZcurrentItemrJ   Z	edit_gotorW   rÏ   )rI   r™   Zitemdatarf   ry   rý   r7   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  r  ZsetSectionsClickabler  )rI   Úflagr7   r7   r8   r     s    
zResultsBrowser.set_sortingc             C   s   |   d¡ d S )NT)r  )rI   r²   r7   r7   r8   r    s    zResultsBrowser.sort_sectionc             C   s   |   |¡ dS )zClick eventN)r"  )rI   r™   r7   r7   r8   r×   	  s    zResultsBrowser.clickedc             C   sV   |   ¡  |  d¡ d| _i | _i | _|  t¡ || _d| }tdƒ}|  	|| ¡ d S )NFr   z'%s' - zString not found)
Úclearr  Ú	num_filesr  rb   r  r  rÏ   r   r  )rI   rÏ   r
  r5   r7   r7   r8   Úclear_title  s    

zResultsBrowser.clear_titlec                sà  d}d}d}dddddd	œ‰ ‡ fd
d„}t r:t|dd}n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 rJ|g| }t|
ƒ|k rb|
|g }
d |¡}d |
¡}
t|ƒ|kr”||dd …  }t|
ƒ|kr²|
d d… | }
d}||ƒ}||
ƒ}
||	ƒ}	| ||	|
¡}|S )Nz...éP   é(   z&amp;z&quot;z&apos;z&gt;z&lt;)r‹   ú"ú'ú>ú<c                s   d  ‡ fdd„| D ƒ¡S )zProduce entities within text.rŠ   c             3   s   | ]}ˆ   ||¡V  qd S )N)r   )r¨   Úc)Úhtml_escape_tabler7   r8   ú	<genexpr>(  s    zFResultsBrowser.truncate_result.<locals>.html_escape.<locals>.<genexpr>)r\   )r5   )r.  r7   r8   Úhtml_escape&  s    z3ResultsBrowser.truncate_result.<locals>.html_escapeÚutf8)Úencodingr+   ú r*   r   éüÿÿÿr,   iâÿÿÿé   z{0}<b>{1}</b>{2})r   r   r2   rñ   r\   r  )rI   rz   rt   ru   r6   Zmax_line_lengthZmax_num_char_fragmentr0  Úleftr}   ÚrightÚoffsetZnum_left_wordsZnum_right_wordsZline_match_formatZ
trunc_liner7   )r.  r8   Útruncate_result  s^    (






zResultsBrowser.truncate_resultc             C   sê   |\}}}}}|| j krHt| || jƒ}| d¡ || j |< |  jd7  _| j}	d|	 }
| j}|dkrntdƒ}n0tdƒ}tdƒ}|dkrŽ|d7 }d	||||f }|  |
| ¡ | j | }|  |||¡}t	||||ƒ}|||f| j
t|ƒ< d
S )z"Real-time update of search resultsTr*   z'%s' - r   zString not foundz
matches inÚfileÚsz%d %s %d %sN)rb   r  r  ZsetExpandedr%  rÏ   r   r  r9  rü   r  r!  )rI   r>   Znum_matchesrf   ry   rý   Z	match_endrz   Z	file_itemrÏ   r
  Znb_filesr5   Ztext_matchesZ
text_filesr™   r7   r7   r8   Úappend_result^  s,    





zResultsBrowser.append_resultN)r   r€   r   r;   r"  r  r   r3   r  r×   r&  r9  r†   r<  r7   r7   r7   r8   r  å  s   Er  c               @   sB   e Zd ZdZdd„ Zeeƒddd„ƒZdd„ Zd	d
„ Z	dd„ Z
dS )ÚFileProgressBarz$Simple progress spinner with a labelc             C   sh   t  | |¡ t| ƒ| _t| dd| _| j d¡ | j d¡ tƒ }| 	| j¡ | 	| j¡ |  
|¡ d S )NF)ZcenterOnParenté   r+   )r   r;   r   Ústatus_textr)   ÚspinnerZsetNumberOfLinesZsetInnerRadiusr   rÚ   rà   )rI   rJ   rå   r7   r7   r8   r;   €  s    
zFileProgressBar.__init__Fc             C   s:   t |ƒ}|stdƒ |¡}ntdƒ |¡}| j |¡ d S )Nz Scanning: {0}z# Searching for files in folder: {0})r9   r   r  r?  ÚsetText)rI   rM   Úfolderr5   Z
status_strr7   r7   r8   Úset_label_pathŒ  s
    zFileProgressBar.set_label_pathc             C   s   | j  tdƒ¡ d S )Nz  Searching for files...)r?  rA  r   )rI   r7   r7   r8   Úreset•  s    zFileProgressBar.resetc             C   s   t  | |¡ | j ¡  dS )z-Override show event to start waiting spinner.N)r   Ú	showEventr@  rt   )rI   rÃ   r7   r7   r8   rE  ˜  s    zFileProgressBar.showEventc             C   s   t  | |¡ | j ¡  dS )z,Override hide event to stop waiting spinner.N)r   Ú	hideEventr@  rU   )rI   rÃ   r7   r7   r8   rF    s    zFileProgressBar.hideEventN)F)r   r€   r   r‚   r;   r   r„   rC  rD  rE  rF  r7   r7   r7   r8   r=  }  s   r=  c            	   @   s`   e Zd ZdZeƒ Zdded dddddg f	dd	„Zd
d„ Zdd„ Z	ddd„Z
dd„ Zdd„ ZdS )ÚFindInFilesWidgetz
    Find in files widget
    rŠ   Fr   N)zutf-8z
iso-8859-1Úcp1252Tc             C   sâ   t  | |¡ |  tdƒ¡ d | _t| ƒ| _| j ¡  t| ||||||||	|
ƒ
| _	| j	j
 | j
¡ | j	j | j¡ t| ƒ| _tƒ }| | j¡ tƒ }| ¡ \}}}}| |d||¡ | | j	¡ | |¡ | | j¡ |  |¡ d S )NzFind in filesr   )r   r;   ZsetWindowTitler   Úsearch_threadr=  Ú
status_barÚhiderÇ   Úfind_optionsrm   r   rU   Ústop_and_reset_threadr  Úresult_browserr   rÚ   r   ZgetContentsMarginsrÞ   rß   rà   )rI   rJ   rÏ   rá   rC   râ   rÜ   rÎ   rÔ   rG   r    Zhlayoutrå   r6  Z_xr7  Zbottomr7   r7   r8   r;   ©  s,    




zFindInFilesWidget.__init__c             C   s   | j  |¡ dS )zSet search patternN)rL  rç   )rI   r5   r7   r7   r8   rç   Ï  s    z!FindInFilesWidget.set_search_textc                sê   ˆ j  ¡ }|dkrdS ˆ jdd tˆ ƒˆ _ˆ jj ˆ j¡ ˆ jj ‡ fdd„¡ ˆ jj	 ‡ fdd„¡ ˆ jj
 ˆ jj¡ ˆ jj dd„ ¡ ˆ j ¡  ˆ j ˆ j j ¡ ¡ ˆ jj|Ž  ˆ j ¡  ˆ j j d¡ ˆ j j d¡ ˆ j ¡  dS )	zCall the find functionNT)Úignore_resultsc                s   ˆ j j| ddS )NF)rB  )rJ  rC  )rí   )rI   r7   r8   rÊ   Ü  s    z(FindInFilesWidget.find.<locals>.<lambda>c                s   ˆ j j| ddS )NT)rB  )rJ  rC  )rí   )rI   r7   r8   rÊ   ß  s    c             S   s   t j t| ƒd ¡S )NÚ
)ÚsysÚstdoutÚwriter„   )rí   r7   r7   r8   rÊ   å  s    F)rL  rõ   rM  r:   rI  rV   r   Úsearch_completeri   r…   rq   rN  r<  rˆ   rJ  rD  r&  rÏ   rî   rN   rt   rÖ   rš   rÙ   Úshow)rI   r  r7   )rI   r8   rm   Ó  s,    





zFindInFilesWidget.findc             C   sR   | j dk	rN| j  ¡ r<|r(| j j | j¡ | j  ¡  | j  ¡  | j  d¡ d| _ dS )z'Stop current search thread and clean-upN)rI  Z	isRunningrV   Z
disconnectrT  rU   ÚwaitZ	setParent)rI   rO  r7   r7   r8   rM  ð  s    



z'FindInFilesWidget.stop_and_reset_threadc             C   s   | j dd dS )z'Perform actions before widget is closedT)rO  N)rM  )rI   r7   r7   r8   Úclosing_widgetü  s    z FindInFilesWidget.closing_widgetc             C   sˆ   | j  t¡ | jj d¡ | jj d¡ | j ¡  | j  	¡  | j
dkrJdS | j ¡  | j
 ¡ }|  ¡  |dk	r„|\}}}}| j  ¡  dS )z"Current search thread has finishedTFN)rN  r  r  rL  rÖ   rš   rÙ   rJ  rK  Z	expandAllrI  rV   rW   r~   rM  rU  )rI   rF   r|   r>   r?   ZnbrA   r7   r7   r8   rT     s    




z!FindInFilesWidget.search_complete)F)r   r€   r   r‚   r   rV   r   r;   rç   rm   rM  rW  rT  r7   r7   r7   r8   rG  £  s    
rG  c              C   sœ   ddl m}  ddlm} | ƒ }tdƒ}| dd¡ | ¡  |tƒ||tƒƒ|||tƒƒƒ||||tƒƒƒƒg}x|D ]}|jj	 
|¡ qtW t | ¡ ¡ dS )zRun Find in Files widget testr   )Úqapplication)rd   Ni€  ià  )Úspyder.utils.qthelpersrX  Úos.pathrd   rG  ZresizerU  Ú__file__rL  rÝ   rœ   rQ  ÚexitZexec_)rX  rd   ZapprÂ   Zexternal_pathsrM   r7   r7   r8   Útest  s    

r]  Ú__main__)Yr‚   Z
__future__r   r   ré   rZ   rZ  rM   rr   rK   rQ  r4   rS   Zqtpy.compatr   Z
qtpy.QtGuir   r   Zqtpy.QtCorer   r   r	   r
   r   r   r   r   Zqtpy.QtWidgetsr   r   r   r   r   r   r   r   r   r   r   r   Zspyder.config.baser   Zspyder.config.mainr   Zspyder.py3compatr   r   Zspyder.utilsr   rÕ   Zspyder.utils.encodingr    r!   Zspyder.utils.miscr"   Zspyder.widgets.comboboxesr#   Zspyder.widgets.onecolumntreer$   r%   rY  r&   r'   Zspyder.config.guir(   Zspyder.widgets.waitingspinnerr)   r  r  r¯   r°   r±   rµ   r¸   r¦   r1   r¥   r9   r:   r‰   rÇ   rü   r  r  r  r=  rG  r]  r   r7   r7   r7   r8   Ú<module>   sf   (8  2 u' &n
