U
    Pem                     @   s  d Z d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 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mZmZmZm Z m!Z! ddl"Z#ddl$m%Z% ddl&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3 ddl4m4Z4 eZdZ5dZ6edkrvzddl7m8Z8m9Z9m:Z: dZ6W n* e;k
rt   e:d e:d Y nX dd Z<G dd de=Z>G dd  d e>Z?G d!d" d"eZ@G d#d$ d$e@ZAG d%d& d&eZBG d'd( d(eBZCG d)d* d*eBZDG d+d, d,eZEG d-d. d.eEZFG d/d0 d0eEZGG d1d2 d2eEZHeId3krdd4lJmKZK dd5lLmLZL ddlMZMddlNZNeOeMPd6ZQG d7d8 d8eKZReR S  dS )9a	  
FileChooser
===========

The FileChooser module provides various classes for describing, displaying and
browsing file systems.

Simple widgets
--------------

There are two ready-to-use widgets that provide views of the file system. Each
of these present the files and folders in a different style.

The :class:`FileChooserListView` displays file entries as text items in a
vertical list, where folders can be collapsed and expanded.

.. image:: images/filechooser_list.png

The :class:`FileChooserIconView` presents icons and text from left to right,
wrapping them as required.

.. image:: images/filechooser_icon.png

They both provide for scrolling, selection and basic user interaction.
Please refer to the :class:`FileChooserController` for details on supported
events and properties.

Widget composition
------------------

FileChooser classes adopt a
`MVC <https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller>`_
design. They are exposed so that you to extend and customize your file chooser
according to your needs.

The FileChooser classes can be categorized as follows:

* Models are represented by concrete implementations of the
  :class:`FileSystemAbstract` class, such as the :class:`FileSystemLocal`.

* Views are represented by the :class:`FileChooserListLayout` and
  :class:`FileChooserIconLayout` classes. These are used by the
  :class:`FileChooserListView` and :class:`FileChooserIconView` widgets
  respectively.

* Controllers are represented by concrete implementations of the
  :class:`FileChooserController`, namely the :class:`FileChooser`,
  :class:`FileChooserIconView` and :class:`FileChooserListView` classes.

This means you can define your own views or provide :class:`FileSystemAbstract`
implementations for alternative file systems for use with these widgets.
The :class:`FileChooser` can be used as a controller for handling multiple,
synchronized views of the same path. By combining these elements, you can add
your own views and file systems and have them easily interact with the existing
components.

Usage example
-------------

main.py

.. include:: ../../examples/RST_Editor/main.py
    :literal:

editor.kv

.. highlight:: kv

.. include:: ../../examples/RST_Editor/editor.kv
    :literal:

.. versionadded:: 1.0.5

.. versionchanged:: 1.2.0

    In the chooser template, the `controller` is no longer a direct reference
    but a weak-reference. If you are upgrading, you should change the notation
    `root.controller.xxx` to `root.controller().xxx`.

)	FileChooserListViewFileChooserIconViewFileChooserListLayoutFileChooserIconLayoutFileChooserFileChooserControllerFileChooserProgressBaseFileSystemAbstractFileSystemLocal    )ref)time)DEFAULT_FONT)string_types)Factory)Clock)Builder)Logger)platform)FloatLayout)RelativeLayout)ScreenManagerScreen)StringPropertyListPropertyBooleanPropertyObjectPropertyNumericPropertyAliasPropertyNlistdir)basenamejoinsepnormpath
expanduseraltsep
splitdriverealpathgetsizeisdirabspathisfiledirnamefnmatch)BZKBZMBZGBZTBFwin)FILE_ATTRIBUTE_HIDDENGetFileAttributesExWerrorTz(filechooser: win32file module is missingz7filechooser: we cannot check if a file is hidden or notc                    s,   t  fdd| D t  fdd| D  S )Nc                 3   s   | ]}  |r|V  qd S Nis_dir.0f
filesystem 8/tmp/pip-unpacked-wheel-xzebddm3/kivy/uix/filechooser.py	<genexpr>   s     
 z-alphanumeric_folders_first.<locals>.<genexpr>c                 3   s   | ]}  |s|V  qd S r4   r5   r7   r:   r<   r=   r>      s     
 )sorted)filesr;   r<   r:   r=   alphanumeric_folders_first   s    rA   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   zClass for implementing a File System view that can be used with the
    :class:`FileChooser <FileChooser>`.

    .. versionadded:: 1.8.0
    c                 C   s   dS )z7Return the list of files in the directory `fn`
        Nr<   selffnr<   r<   r=   r      s    zFileSystemAbstract.listdirc                 C   s   dS )z+Return the size in bytes of a file
        Nr<   rB   r<   r<   r=   r(      s    zFileSystemAbstract.getsizec                 C   s   dS )z*Return True if the file is hidden
        Nr<   rB   r<   r<   r=   	is_hidden   s    zFileSystemAbstract.is_hiddenc                 C   s   dS )zIReturn True if the argument passed to this method is a directory
        Nr<   rB   r<   r<   r=   r6      s    zFileSystemAbstract.is_dirN__name__
__module____qualname____doc__r   r(   rE   r6   r<   r<   r<   r=   r      s
   r   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r	   z`Implementation of :class:`FileSystemAbstract` for local files.

    .. versionadded:: 1.8.0
    c                 C   s   t |S r4   r   rB   r<   r<   r=   r      s    zFileSystemLocal.listdirc                 C   s   t |S r4   )r(   rB   r<   r<   r=   r(      s    zFileSystemLocal.getsizec                 C   sV   t dkrHtsdS zt|d t@ W S  tk
rF   td|  Y dS X t|dS )Nr0   Fr
   zunable to access to <%s>T.)	r   _have_win32filer2   r1   r3   r   	exceptionr    
startswithrB   r<   r<   r=   rE      s    zFileSystemLocal.is_hiddenc                 C   s   t |S r4   )r)   rB   r<   r<   r=   r6      s    zFileSystemLocal.is_dirNrF   r<   r<   r<   r=   r	      s
   r	   c                       sX   e Zd ZdZedZedZedZdd Z	 fddZ
 fd	d
Z fddZ  ZS )r   zBase for implementing a progress view. This view is used when too many
    entries need to be created and are delayed over multiple frames.

    .. versionadded:: 1.2.0
     r
      c                 G   s   | j r| j   dS )z:Cancel any action from the FileChooserController.
        N)parentcancel)rC   largsr<   r<   r=   rR      s    zFileChooserProgressBase.cancelc                    s$   | j |j r tt| | dS d S NT)collide_pointpossuperr   on_touch_downrC   touch	__class__r<   r=   rX      s    z%FileChooserProgressBase.on_touch_downc                    s$   | j |j r tt| | dS d S rT   )rU   rV   rW   r   on_touch_moverY   r[   r<   r=   r]      s    z%FileChooserProgressBase.on_touch_movec                    s$   | j |j r tt| | dS d S rT   )rU   rV   rW   r   on_touch_uprY   r[   r<   r=   r^      s    z#FileChooserProgressBase.on_touch_up)rG   rH   rI   rJ   r   pathr   indextotalrR   rX   r]   r^   __classcell__r<   r<   r[   r=   r      s   r   c                   @   s   e Zd ZdS )FileChooserProgressN)rG   rH   rI   r<   r<   r<   r=   rc      s   rc   c                   @   sJ   e Zd ZdZdZdZe ZdddZdd Z	d	d
 Z
dd ZdddZdS )FileChooserLayoutzFBase class for file chooser layouts.

    .. versionadded:: 1.9.0
    Z	undefinedon_entry_addedon_entries_clearedon_subentry_to_entryon_remove_subentry	on_submitNc                 C   s   d S r4   r<   rC   noderQ   r<   r<   r=   rf     s    z FileChooserLayout.on_entry_addedc                 C   s   d S r4   r<   rC   r<   r<   r=   rg     s    z$FileChooserLayout.on_entries_clearedc                 C   s   d S r4   r<   rC   subentryentryr<   r<   r=   rh     s    z&FileChooserLayout.on_subentry_to_entryc                 C   s   d S r4   r<   rn   r<   r<   r=   ri   
  s    z$FileChooserLayout.on_remove_subentryc                 C   s   d S r4   r<   rC   selectedrZ   r<   r<   r=   rj     s    zFileChooserLayout.on_submit)N)N)rG   rH   rI   rJ   VIEWNAME
__events__r   
controllerrf   rg   rh   ri   rj   r<   r<   r<   r=   rd      s   
rd   c                       s0   e Zd ZdZdZdZ fddZdd Z  ZS )r   zHFile chooser layout using a list view.

    .. versionadded:: 1.9.0
    listFileListEntryc                    s$   t t| jf | | d| j d S Nrg   )rW   r   __init__fbindscroll_to_toprC   kwargsr[   r<   r=   ry     s    zFileChooserListLayout.__init__c                 G   s   d| j j_d S Ng      ?idsZ
scrollviewZscroll_yrC   argsr<   r<   r=   r{     s    z#FileChooserListLayout.scroll_to_top	rG   rH   rI   rJ   rs   _ENTRY_TEMPLATEry   r{   rb   r<   r<   r[   r=   r     s
   r   c                       s0   e Zd ZdZdZdZ fddZdd Z  ZS )r   zIFile chooser layout using an icon view.

    .. versionadded:: 1.9.0
    ZiconFileIconEntryc                    s$   t t| jf | | d| j d S rx   )rW   r   ry   rz   r{   r|   r[   r<   r=   ry   *  s    zFileChooserIconLayout.__init__c                 G   s   d| j j_d S r~   r   r   r<   r<   r=   r{   .  s    z#FileChooserIconLayout.scroll_to_topr   r<   r<   r[   r=   r   !  s
   r   c                       s  e Zd ZdZdZeedZedZ	e
g ZedZeeZe
g ZedZe
g ZedZedZedddZeeZe
dd	d
gddZee edZeeZdZdZdZ  fddZ! fddZ" fddZ#dd Z$dd Z%dd Z&dCddZ'dd Z(dd Z)dd  Z*dDd!d"Z+d#d$ Z,d%d& Z-d'd( Z.d)d* Z/d+d, Z0d-d. Z1d/d0 Z2d1d2 Z3d3d4 Z4d5d6 Z5d7d8 Z6d9d: Z7d;d< Z8dEd=d>Z9d?d@ Z:dAdB Z;  Z<S )Fr   a`  Base for implementing a FileChooser. Don't use this class directly, but
    prefer using an implementation such as the :class:`FileChooser`,
    :class:`FileChooserListView` or :class:`FileChooserIconView`.

    :Events:
        `on_entry_added`: entry, parent
            Fired when a root-level entry is added to the file list. If you
            return True from this event, the entry is not added to FileChooser.
        `on_entries_cleared`
            Fired when the the entries list is cleared, usually when the
            root is refreshed.
        `on_subentry_to_entry`: entry, parent
            Fired when a sub-entry is added to an existing entry or
            when entries are removed from an entry e.g. when
            a node is closed.
        `on_submit`: selection, touch
            Fired when a file has been selected with a double-tap.
    N)Z	baseclass/FT)Z	allownonezutf-8latin1cp1252)
deprecatedre   c                    st   d | _ tt| jf | g | _| j}|d| j | jg| _|d| j	 | j
}|d| |d| |d| |  d S )N	selectionr_   filtersrootpath)	_progressrW   r   ry   _itemsrz   _update_item_selectionr_   _previous_path_save_previous_path_trigger_update)rC   r}   rz   updater[   r<   r=   ry     s    



zFileChooserController.__init__c                    s*   | j |j sd S | jrdS tt| |S rT   )rU   rV   disabledrW   r   rX   rY   r[   r<   r=   rX   %  s
    z#FileChooserController.on_touch_downc                    s*   | j |j sd S | jrdS tt| |S rT   )rU   rV   r   rW   r   r^   rY   r[   r<   r=   r^   -  s
    z!FileChooserController.on_touch_upc                 G   s   | j D ]}|j| jk|_qd S r4   r   r_   r   rr   )rC   r   itemr<   r<   r=   r   5  s    
z,FileChooserController._update_item_selectionc                 C   s    | j | | j dd  | _ d S )N)r   append)rC   instancevaluer<   r<   r=   r   9  s    z)FileChooserController._save_previous_pathc                 G   s*   | j }|d kr t| j }| _ |  d S r4   )_update_files_evr   create_trigger_update_files)rC   r   evr<   r<   r=   r   =  s    
z%FileChooserController._trigger_updatec                 C   s   | j r| j d|| d S Nrf   layoutdispatchrk   r<   r<   r=   rf   D  s    z$FileChooserController.on_entry_addedc                 C   s   | j r| j d d S rx   r   rm   r<   r<   r=   rg   H  s    z(FileChooserController.on_entries_clearedc                 C   s   | j r| j d|| d S Nrh   r   rn   r<   r<   r=   rh   L  s    z*FileChooserController.on_subentry_to_entryc                 C   s   | j r| j d|| d S Nri   r   rn   r<   r<   r=   ri   P  s    z(FileChooserController.on_remove_subentryc                 C   s   | j r| j d|| d S Nrj   r   rq   r<   r<   r=   rj   T  s    zFileChooserController.on_submitc                 C   s   d|j kr|jdkrdS | j|j}| j}|rH|rH|jrH| | dS | jr|j| j	krj| j	
|j q|r| js| | dS | j	|j n$|r| jsdS tt| j|jg| _	dS )zl(internal) This method must be called by the template when an entry
        is touched by the user.
        buttonZscrollupZ
scrolldownZ
scrollleftZscrollrightFN)profiler   file_systemr6   r_   	dirselectis_double_tap
open_entrymultiselectr   remover   r*   r!   )rC   rp   rZ   Z_dirr   r<   r<   r=   entry_touchedX  s(    



z#FileChooserController.entry_touchedc                 C   sp   d|j kr|jdkrdS | jsl| j|jr>| js>| | n.|jrl| jr\| j|jr\dS | 	d| j
| dS )z(internal) This method must be called by the template when an entry
        is touched by the user.

        .. versionadded:: 1.1.0
        r   r   FNrj   )r   r   r   r   r6   r_   r   r   r   r   r   )rC   rp   rZ   r<   r<   r=   entry_releasedu  s    z$FileChooserController.entry_releasedc                 C   sZ   z| j |j W n tk
r,   d|_Y n*X tt| j|j| _| jrP| jgng | _d S rT   )	r   r   r_   OSErrorlockedr*   r!   r   r   rC   rp   r<   r<   r=   r     s    z FileChooserController.open_entryc                    s   j s
|S g }j D ]F t tjjrB| fdd|D  q| fdd|D  qjs~fdd|D }|| tt|S )Nc                    s   g | ]} j |r|qS r<   r_   r8   rD   filtrC   r<   r=   
<listcomp>  s      z8FileChooserController._apply_filters.<locals>.<listcomp>c                    s   g | ]}t | r|qS r<   r-   r   )r   r<   r=   r     s     
 c                    s   g | ]} j |r|qS r<   )r   r6   r   rm   r<   r=   r     s      )	r   
isinstancecollectionsabcCallableextendfilter_dirsrv   set)rC   r@   filtereddirsr<   r   r=   _apply_filters  s    

z$FileChooserController._apply_filtersc                 C   sf   | j |rdS z| j |}W n tk
r6   Y dS X tD ]$}|dk rXd||f   S |d }q<dS )zPass the filepath. Returns the size in the best human readable
        format or '' if it is a directory (Don't recursively calculate size).
        rO   z--g      @z%1.0f %sN)r   r6   r(   r   filesize_units)rC   rD   sizeunitr<   r<   r=   get_nice_size  s    z#FileChooserController.get_nice_sizec                 O   s   g | _ |dd | _| j|d| j| jd| _t| j| _| j}|d k	rR|  | 	  | 
 r|d kr~t| j
d }| _|  d S )NrQ   r_   r_   rQ   g?)_gitemsget_gitems_parent_generate_file_entriesr_   _gitems_genr*   _create_files_entries_evrR   _hide_progress_create_files_entriesr   Zschedule_interval)rC   r   r}   r   r<   r<   r=   r     s$     
z#FileChooserController._update_filesc                 C   s   dd |D S )Nc                 S   s   g | ]
}|j qS r<   r   r8   filer<   r<   r=   r     s     z9FileChooserController._get_file_paths.<locals>.<listcomp>r<   rC   itemsr<   r<   r=   _get_file_paths  s    z%FileChooserController._get_file_pathsc                 G   sV  t  }d}d } }}t  | dk s,|dk rz(t| j\}}}| j| |d7 }W q tk
rp   d}Y qY q tk
r   d}Y qY qX q|s|   || j_	|| j_
dS | j | _}| j}	|	d kr| d |D ]}
| d|
|	 qn&||	jd d < |D ]}
| d|
|	 q| || jd d < |   d | _d | _| j}|d k	rR|  dS )	NFrP   g?
   Trg   rf   rh   )r   nextr   r   r   StopIteration	TypeError_show_progressr   ra   r`   r   r   r   entriesr   r@   r   r   rR   )rC   r   startfinishedr`   ra   countr   r   rQ   rp   r   r<   r<   r=   r     sH    

z+FileChooserController._create_files_entriesc                 G   sR   | j }|dk	r|  |   t| jdkrN| jd | _| j}|dk	rN|  dS )zCancel any background action started by filechooser, such as loading
        a new directory.

        .. versionadded:: 1.2.0
        NrP   r   )r   rR   r   lenr   r_   r   )rC   rS   r   r<   r<   r=   rR     s    zFileChooserController.cancelc                 C   sJ   | j r
d S | j}t|tr$t|}|| jd| _ d| j _| | j  d S )Nr   r
   )	r   progress_clsr   r   r   r   r_   r   
add_widget)rC   clsr<   r<   r=   r     s    

z$FileChooserController._show_progressc                 C   s   | j r| | j  d | _ d S r4   )r   Zremove_widgetrm   r<   r<   r=   r   "  s    z$FileChooserController._hide_progressc                 o   s  d}| d| j}| dd d k	}| jr\t| j}t|}||sN|| _d S ||krd}nFtdkrzt|d ttfk}n(tdkrt	t
|tk}ntdt  |s<|s<d	t }tdkr
|d |t }t|kr|t7 }| t|d
|t| dd tdd d}	n&| t|d
|t| dd tdd d}	dd|	fV  z(| |D ]\}
}}|
||fV  qHW n4 tk
r   td| j  g | jd d < Y nX d S )NFr_   rQ   Tr0   rP   )macosxlinuxZandroidZioszFilechooser: Unsupported OS: %rz..rO   c                   S   s   dS NrO   r<   r<   r<   r<   r=   <lambda>J      z>FileChooserController._generate_file_entries.<locals>.<lambda>)namer   r_   ru   r)   rQ   r"   r   c                   S   s   dS r   r<   r<   r<   r<   r=   r   O  r   r
   zUnable to open directory <%s>)r   r_   r   r'   rN   r   r&   r"   r%   r#   r$   r   warningrfind_create_entry_widgetdictr   
_add_filesr   rM   r@   )rC   r   r}   Zis_rootr_   Zhave_parentr   backnew_pathpardirr`   ra   r   r<   r<   r=   r   '  sb    


     
     z,FileChooserController._generate_file_entriesc                 C   s"   | j r| j jn| j}tj|f|S r4   )r   r   r   template)rC   ctxr   r<   r<   r=   r   Z  s
    
z*FileChooserController._create_entry_widgetc              	   #   sB  t |}t|rt|}g }|j}j|D ]b}z|tt|| W q. tk
rl   t	
d| Y q. tk
r   t	
d| Y q.X q.|}|j}jjjsʇfdd|D }|jd d < t|}t}t|D ]L\}  fdd}	t |	 |j |td}
|
}|||fV  qd S )Nzunable to decode <{}>zunable to encode <{}>c                    s   g | ]} |s|qS r<   r<   )r8   x)rE   r<   r=   r   t  s      z4FileChooserController._add_files.<locals>.<listcomp>c                      s
     S r4   )r   r<   )rD   rC   r<   r=   r   z  s    z7FileChooserController._add_files.<locals>.get_nice_size)r   r   r_   ru   r)   rQ   r"   )r$   r+   r,   r   r   r   r#   r!   UnicodeDecodeErrorr   rM   formatUnicodeEncodeErrorr   	sort_funcrE   show_hiddenr@   r   r   	enumerater    r6   r"   r   )rC   r_   rQ   r@   Zfappendr9   ra   Zwselfr`   r   r   rp   r<   )rD   rE   rC   r=   r   _  s@    


z FileChooserController._add_filesc                 C   s&   | j |jsd S | j|j|d d S )Nr   )r   r6   r_   r   r   r<   r<   r=   entry_subselect  s    z%FileChooserController.entry_subselectc                 C   s   |j D ]}| d|| qd S r   )r   r   )rC   rp   ro   r<   r<   r=   close_subselection  s    
z(FileChooserController.close_subselection)N)N)N)=rG   rH   rI   rJ   r   r   rd   r   r   r_   r   r   r   r   rA   r   r@   r   r   r   r   r   rc   r   Zfile_encodingsr	   r   r   r   Z	font_namer   r   rt   ry   rX   r^   r   r   r   rf   rg   rh   ri   rj   r   r   r   r   r   r   r   r   rR   r   r   r   r   r   r   r   rb   r<   r<   r[   r=   r   2  sh   
	$
 


1
3
)r   c                   @   s   e Zd ZdZdZdS )r   zgImplementation of a :class:`FileChooserController` using a list view.

    .. versionadded:: 1.9.0
    rw   NrG   rH   rI   rJ   r   r<   r<   r<   r=   r     s   r   c                   @   s   e Zd ZdZdZdS )r   zhImplementation of a :class:`FileChooserController` using an icon view.

    .. versionadded:: 1.9.0
    r   Nr   r<   r<   r<   r=   r     s   r   c                       s   e Zd ZdZe Ze Zdd Ze	eddZ
e Zdd Zdd	 Ze	eed
dZedd Z fddZ fddZdd Zdd Zdd Zdd Zdd Zd&ddZdd Zd d! Zd"d# Zd'd$d%Z  ZS )(r   a  Implementation of a :class:`FileChooserController` which supports
    switching between multiple, synced layout views.

    The FileChooser can be used as follows:

    .. code-block:: kv

        BoxLayout:
            orientation: 'vertical'

            BoxLayout:
                size_hint_y: None
                height: sp(52)

                Button:
                    text: 'Icon View'
                    on_press: fc.view_mode = 'icon'
                Button:
                    text: 'List View'
                    on_press: fc.view_mode = 'list'

            FileChooser:
                id: fc
                FileChooserIconLayout
                FileChooserListLayout

    .. versionadded:: 1.9.0
    c                 C   s   | j S r4   
_view_listrm   r<   r<   r=   get_view_list  s    zFileChooser.get_view_listr   )bindc                 C   s   | j S r4   
_view_moderm   r<   r<   r=   get_view_mode  s    zFileChooser.get_view_modec                 C   s    || j krtd| || _d S )Nzunknown view mode %r)r   
ValueErrorr  )rC   moder<   r<   r=   set_view_mode  s    
zFileChooser.set_view_moder   c                 C   s   dd | j jD S )Nc                 S   s   g | ]}|j d  qS r
   )children)r8   screenr<   r<   r=   r     s     z&FileChooser._views.<locals>.<listcomp>)managerZscreensrm   r<   r<   r=   _views  s    zFileChooser._viewsc                    sL   t t| jf | t | _t t| | j t| j| _	| 
d| j	 d S )N	view_mode)rW   r   ry   r   r	  r   r   r   update_viewtrigger_update_viewrz   r|   r[   r<   r=   ry     s
    zFileChooser.__init__c                    s~   || j kr$tt| j|f|| nVt|drh|jd }t|d}| |_|| | j| | 	  nt
dt|j d S )Nrs   view)r   z*widget must be a FileChooserLayout, not %s)r   rW   r   r   hasattrrs   r   ru   r	  r  r  typerG   )rC   Zwidgetr   r}   r   r  r[   r<   r=   r     s    





zFileChooser.add_widgetc                 C   sD   dd | j D }|| jkr@|| _| j| jkr8| jd | _|   d S )Nc                 S   s   g | ]
}|j qS r<   )rs   r8   r  r<   r<   r=   r     s     z-FileChooser.rebuild_views.<locals>.<listcomp>r
   )r
  r   r  r   )rC   Zviewsr<   r<   r=   rebuild_views  s    
zFileChooser.rebuild_viewsc           	      G   sz   |    | j}| j}| j}|jd d }||kr:||nd}||krP||nd}||k r`dnd}||j_|d |_d S )Nr
   leftrightr  )r  r	  r   r  currentr`   Z
transition	direction)	rC   r   smZviewlistr  r  Z	viewindexZcurrentindexr  r<   r<   r=   r    s    zFileChooser.update_viewc                    s    fdd| j D S )Nc                    s   g | ]}t j|jf qS r<   )r   r   r   r  r   r<   r=   r     s   z4FileChooser._create_entry_widget.<locals>.<listcomp>r
  )rC   r   r<   r  r=   r     s    
z FileChooser._create_entry_widgetc                 C   s   | j rdd |D S g S )Nc                 S   s   g | ]}|d  j qS r  r   r   r<   r<   r=   r   #  s     z/FileChooser._get_file_paths.<locals>.<listcomp>r  r   r<   r<   r=   r   !  s    zFileChooser._get_file_pathsc                 G   s0   | j D ]$}|d j| jk}|D ]
}||_qqd S )Nr
   r   )rC   r   Zviewitemrr   r   r<   r<   r=   r   &  s    
z"FileChooser._update_item_selectionNc                 C   s6   t | jD ]&\}}|d|| |r*|| nd  q
d S r   r   r
  r   )rC   rl   rQ   r`   r  r<   r<   r=   rf   ,  s     zFileChooser.on_entry_addedc                 C   s   | j D ]}|d qd S rx   )r
  r   )rC   r  r<   r<   r=   rg   2  s    
zFileChooser.on_entries_clearedc                 C   s*   t | jD ]\}}|d|| | q
d S r   r  rC   ro   rp   r`   r  r<   r<   r=   rh   6  s    z FileChooser.on_subentry_to_entryc                 C   s*   t | jD ]\}}|d|| | q
d S r   r  r  r<   r<   r=   ri   :  s    zFileChooser.on_remove_subentryc                 C   s4   | j }| jD ]"}||jkr|d||  d S qd S r   )r  r
  rs   r   )rC   rr   rZ   r  r  r<   r<   r=   rj   >  s
    

zFileChooser.on_submit)N)N)rG   rH   rI   rJ   r   r	  r   r   r   r   Z	view_listr   r  r  r  r  propertyr
  ry   r   r  r  r   r   r   rf   rg   rh   ri   rj   rb   r<   r<   r[   r=   r     s6     	


r   __main__)Apppprinta      BoxLayout:
        orientation: 'vertical'

        BoxLayout:
            size_hint_y: None
            height: sp(52)

            Button:
                text: 'Icon View'
                on_press: fc.view_mode = 'icon'
            Button:
                text: 'List View'
                on_press: fc.view_mode = 'list'

        FileChooser:
            id: fc

            FileChooserIconLayout
            FileChooserListLayout
    c                   @   s   e Zd Zdd ZdS )FileChooserAppc                 C   sF   t jj}ttjdkr"tjd |_|jdd d |jdd d t S )NrP   c                  W   s   t d| dd   S )Nzselection: %srP   r   r   r<   r<   r=   r   i  r   z&FileChooserApp.build.<locals>.<lambda>)r   c                  W   s   t d| dd   S )Nzpath: %srP   r   r#  r<   r<   r=   r   j  r   r   )rootr   Zfcr   sysargvr_   r   )rC   vr<   r<   r=   buildd  s    zFileChooserApp.buildN)rG   rH   rI   r(  r<   r<   r<   r=   r"  b  s   r"  )TrJ   __all__weakrefr   r   Zkivy.core.textr   Zkivy.compatr   Zkivy.factoryr   Z
kivy.clockr   Z	kivy.langr   Zkivy.loggerr   Z
kivy.utilsr   Zcore_platformZkivy.uix.floatlayoutr   Zkivy.uix.relativelayoutr   Zkivy.uix.screenmanagerr   r   Zkivy.propertiesr   r   r   r   r   r   collections.abcr   osr   os.pathr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r.   r   rL   Z	win32filer1   r2   r3   ImportErrorrA   objectr   r	   r   rc   rd   r   r   r   r   r   r   rG   Zkivy.appr  r!  textwrapr%  load_stringdedentr$  r"  runr<   r<   r<   r=   <module>   sj   Q <

)"    d %
