merge callable_filechooser_filters

This commit is contained in:
gabriel.pettier 2012-07-20 01:30:34 +02:00
parent b9f6396eef
commit b67ad45e40
1 changed files with 43 additions and 29 deletions

View File

@ -6,12 +6,13 @@ FileChooser
.. warning:: .. warning::
This is experimental and subject to change as long as this warning notice is This is experimental and subject to change as long as this warning notice
present. is present.
.. versionchanged:: 1.2.0 .. versionchanged:: 1.2.0
In chooser template, the `controller` is not a direct reference anymore, but In chooser template, the `controller` is not a direct reference anymore,
a weak-reference. You must update all the notation `root.controller.xxx` to but a weak-reference.
You must update all the notation `root.controller.xxx` to
`root.controller().xxx`. `root.controller().xxx`.
''' '''
@ -138,19 +139,29 @@ class FileChooserController(FloatLayout):
filters = ListProperty([]) filters = ListProperty([])
''':class:`~kivy.properties.ListProperty`, defaults to [], equal to '\*'. ''':class:`~kivy.properties.ListProperty`, defaults to [], equal to '\*'.
The filters to be applied to the files in the directory, e.g. ['\*.png']. The filters to be applied to the files in the directory.
The filters are not reset when the path changes. You need to do that The filters are not reset when the path changes. You need to do that
yourself if desired. You can use the following patterns: yourself if desired.
========== ================================= There are two kinds of filters :
Pattern Meaning
========== =================================
\* matches everything
? matches any single character
[seq] matches any character in seq
[!seq] matches any character not in seq
========== =================================
filename patterns : e.g. ['\*.png'].
You can use the following patterns:
========== =================================
Pattern Meaning
========== =================================
\* matches everything
? matches any single character
[seq] matches any character in seq
[!seq] matches any character not in seq
========== =================================
.. versionchanged:: 1.4.0
if the filter is a callable (function or method). It will be called
with the path and the file name as arguments for each file in dir. The
callable should returns True to indicate a match and False overwise.
''' '''
filter_dirs = BooleanProperty(False) filter_dirs = BooleanProperty(False)
@ -162,8 +173,8 @@ class FileChooserController(FloatLayout):
sort_func = ObjectProperty(alphanumeric_folders_first) sort_func = ObjectProperty(alphanumeric_folders_first)
''' '''
:class:`~kivy.properties.ObjectProperty`. :class:`~kivy.properties.ObjectProperty`.
Provides a function to be called with a list of filenames as the only argument. Provides a function to be called with a list of filenames as the only
Returns a list of filenames sorted for display in the view. argument. Returns a list of filenames sorted for display in the view.
''' '''
files = ListProperty([]) files = ListProperty([])
@ -202,9 +213,9 @@ class FileChooserController(FloatLayout):
rootpath = StringProperty(None, allownone=True) rootpath = StringProperty(None, allownone=True)
''' '''
Root path to use, instead of the system root path. If set, it will not show Root path to use, instead of the system root path. If set, it will not show
a ".." directory to go upper the root path. For example, if you set rootpath a ".." directory to go upper the root path. For example, if you set
to /Users/foo, the user will be unable to go to /Users, or to any other rootpath to /Users/foo, the user will be unable to go to /Users, or to any
directory not starting with /Users/foo. other directory not starting with /Users/foo.
.. versionadded:: 1.2.0 .. versionadded:: 1.2.0
@ -220,7 +231,6 @@ class FileChooserController(FloatLayout):
:class:`FileChooserProgress` :class:`FileChooserProgress`
''' '''
file_encodings = ListProperty(['utf-8', 'latin1', 'cp1252']) file_encodings = ListProperty(['utf-8', 'latin1', 'cp1252'])
'''Possible encodings for decoding a filename to unicode. In the case that '''Possible encodings for decoding a filename to unicode. In the case that
the user has a weird filename, undecodable without knowing it's the user has a weird filename, undecodable without knowing it's
@ -358,7 +368,10 @@ class FileChooserController(FloatLayout):
return files return files
filtered = [] filtered = []
for filter in self.filters: for filter in self.filters:
filtered.extend([fn for fn in files if fnmatch(fn, filter)]) if callable(filter):
filtered.extend([fn for fn in files if filter(self.path, fn)])
else:
filtered.extend([fn for fn in files if fnmatch(fn, filter)])
if not self.filter_dirs: if not self.filter_dirs:
dirs = [fn for fn in files if isdir(fn)] dirs = [fn for fn in files if isdir(fn)]
filtered.extend(dirs) filtered.extend(dirs)
@ -403,8 +416,8 @@ class FileChooserController(FloatLayout):
def _create_files_entries(self, *args): def _create_files_entries(self, *args):
# create maximum entries during 50ms max, or 10 minimum (slow system) # create maximum entries during 50ms max, or 10 minimum (slow system)
# (on a "fast system" (core i7 2700K), we can create up to 40 entries in # (on a "fast system" (core i7 2700K), we can create up to 40 entries
# 50 ms. So 10 is fine for low system. # in 50 ms. So 10 is fine for low system.
start = time() start = time()
finished = False finished = False
index = total = count = 1 index = total = count = 1
@ -445,16 +458,17 @@ class FileChooserController(FloatLayout):
return False return False
def cancel(self, *largs): def cancel(self, *largs):
'''Cancel any background action started by filechooser, such as loading a '''Cancel any background action started by filechooser, such as loading
new directory. a new directory.
.. versionadded:: 1.2.0 .. versionadded:: 1.2.0
''' '''
Clock.unschedule(self._create_files_entries) Clock.unschedule(self._create_files_entries)
self._hide_progress() self._hide_progress()
if len(self._previous_path) > 1: if len(self._previous_path) > 1:
# if we cancel any action, the path will be set same as the previous # if we cancel any action, the path will be set same as the
# one, so we can safely cancel the update of the previous path. # previous one, so we can safely cancel the update of the previous
# path.
self.path = self._previous_path[-2] self.path = self._previous_path[-2]
Clock.unschedule(self._update_files) Clock.unschedule(self._update_files)
@ -556,8 +570,8 @@ class FileChooserController(FloatLayout):
yield index, total, entry yield index, total, entry
def _force_unicode(self, s): def _force_unicode(self, s):
# the idea is, whatever is the filename, unicode or str, even if the str # the idea is, whatever is the filename, unicode or str, even if the
# can't be directly returned as a unicode, return something. # str can't be directly returned as a unicode, return something.
if type(s) is unicode: if type(s) is unicode:
return s return s
encodings = self.file_encodings encodings = self.file_encodings