├── screenshot.png
├── filebrowser.png
├── doc
├── source
│ ├── _static
│ │ ├── logo.png
│ │ ├── filebrowser.png
│ │ └── default.css
│ ├── api.rst
│ ├── index.rst
│ ├── _templates
│ │ └── layout.html
│ └── conf.py
├── Makefile
└── make.bat
├── LICENSE
├── README.rst
└── __init__.py
/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fitoprincipe/garden.filebrowser/master/screenshot.png
--------------------------------------------------------------------------------
/filebrowser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fitoprincipe/garden.filebrowser/master/filebrowser.png
--------------------------------------------------------------------------------
/doc/source/_static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fitoprincipe/garden.filebrowser/master/doc/source/_static/logo.png
--------------------------------------------------------------------------------
/doc/source/_static/filebrowser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fitoprincipe/garden.filebrowser/master/doc/source/_static/filebrowser.png
--------------------------------------------------------------------------------
/doc/source/api.rst:
--------------------------------------------------------------------------------
1 |
2 | #####################
3 | The FileBrowser API
4 | #####################
5 |
6 | :mod:`filebrowser`
7 | ==============================
8 |
9 | .. automodule:: __init__
10 | :members:
11 | :show-inheritance:
12 |
--------------------------------------------------------------------------------
/doc/source/index.rst:
--------------------------------------------------------------------------------
1 | .. FileBrowser documentation master file, created by
2 | sphinx-quickstart on Mon Dec 23 18:07:03 2013.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to FileBrowser's documentation!
7 | =======================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 | api.rst
15 |
16 | * :ref:`genindex`
17 | * :ref:`modindex`
18 | * :ref:`search`
19 |
--------------------------------------------------------------------------------
/doc/source/_templates/layout.html:
--------------------------------------------------------------------------------
1 | {% extends "!layout.html" %}
2 |
3 |
4 | {% block rootrellink %}
5 |
home|
6 | search|
7 | {% endblock %}
8 |
9 |
10 | {% block relbar1 %}
11 |
12 |
13 |

15 |
16 | {{ super() }}
17 | {% endblock %}
18 |
19 | {# put the sidebar before the body #}
20 | {% block sidebar1 %}{{ sidebar() }}{% endblock %}
21 | {% block sidebar2 %}{% endblock %}
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010-2015 Kivy Team and other contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 |
2 | See http://kivy-garden.github.io/garden.filebrowser/index.html
3 |
4 |
5 | FileBrowser
6 | ===========
7 |
8 | The ``FileBrowser`` widget is an advanced file browser. You use it
9 | similarly to FileChooser usage.
10 |
11 | It provides a shortcut bar with links to special and system directories.
12 | When touching next to a shortcut in the links bar, it'll expand and show
13 | all the directories within that directory. It also facilitates specifying
14 | custom paths to be added to the shortcuts list.
15 |
16 | It provides a icon and list view to choose files from. And it also accepts
17 | filter and filename inputs.
18 |
19 | To create a ``FileBrowser`` which prints the currently selected file as
20 | well as the current text in the filename field when 'Select' is pressed,
21 | with a shortcut to the Documents directory added to the favorites bar:
22 |
23 | .. code-block:: python
24 |
25 | from kivy.app import App
26 | from os.path import sep, expanduser, isdir, dirname
27 |
28 | class TestApp(App):
29 |
30 | def build(self):
31 | if platform == 'win':
32 | user_path = dirname(expanduser('~')) + sep + 'Documents'
33 | else:
34 | user_path = expanduser('~') + sep + 'Documents'
35 | browser = FileBrowser(select_string='Select',
36 | favorites=[(user_path, 'Documents')])
37 | browser.bind(
38 | on_success=self._fbrowser_success,
39 | on_canceled=self._fbrowser_canceled)
40 | return browser
41 |
42 | def _fbrowser_canceled(self, instance):
43 | print 'cancelled, Close self.'
44 |
45 | def _fbrowser_success(self, instance):
46 | print instance.selection
47 |
48 | TestApp().run()
49 |
50 | Events
51 | ------
52 |
53 | - ``on_canceled``
54 | Fired when the `Cancel` buttons `on_release` event is called.
55 | - ``on_success``
56 | Fired when the `Select` buttons `on_release` event is called.
57 |
58 | License
59 | =======
60 |
61 | Same license as kivy (currently MIT License).
62 |
--------------------------------------------------------------------------------
/doc/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = build
9 |
10 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source
21 |
22 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
23 |
24 | help:
25 | @echo "Please use \`make ' where is one of"
26 | @echo " html to make standalone HTML files"
27 | @echo " dirhtml to make HTML files named index.html in directories"
28 | @echo " singlehtml to make a single large HTML file"
29 | @echo " pickle to make pickle files"
30 | @echo " json to make JSON files"
31 | @echo " htmlhelp to make HTML files and a HTML help project"
32 | @echo " qthelp to make HTML files and a qthelp project"
33 | @echo " devhelp to make HTML files and a Devhelp project"
34 | @echo " epub to make an epub"
35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
36 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
38 | @echo " text to make text files"
39 | @echo " man to make manual pages"
40 | @echo " texinfo to make Texinfo files"
41 | @echo " info to make Texinfo files and run them through makeinfo"
42 | @echo " gettext to make PO message catalogs"
43 | @echo " changes to make an overview of all changed/added/deprecated items"
44 | @echo " xml to make Docutils-native XML files"
45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
46 | @echo " linkcheck to check all external links for integrity"
47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
48 |
49 | clean:
50 | rm -rf $(BUILDDIR)/*
51 |
52 | html:
53 | @cd ../; python setup.py build_ext --inplace; @cd doc
54 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
55 | @echo
56 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
57 |
58 | dirhtml:
59 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
60 | @echo
61 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
62 |
63 | singlehtml:
64 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
65 | @echo
66 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
67 |
68 | pickle:
69 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
70 | @echo
71 | @echo "Build finished; now you can process the pickle files."
72 |
73 | json:
74 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
75 | @echo
76 | @echo "Build finished; now you can process the JSON files."
77 |
78 | htmlhelp:
79 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
80 | @echo
81 | @echo "Build finished; now you can run HTML Help Workshop with the" \
82 | ".hhp project file in $(BUILDDIR)/htmlhelp."
83 |
84 | qthelp:
85 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
86 | @echo
87 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
88 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
89 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FFPyPlayer.qhcp"
90 | @echo "To view the help file:"
91 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FFPyPlayer.qhc"
92 |
93 | devhelp:
94 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
95 | @echo
96 | @echo "Build finished."
97 | @echo "To view the help file:"
98 | @echo "# mkdir -p $$HOME/.local/share/devhelp/FFPyPlayer"
99 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FFPyPlayer"
100 | @echo "# devhelp"
101 |
102 | epub:
103 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
104 | @echo
105 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
106 |
107 | latex:
108 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
109 | @echo
110 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
111 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
112 | "(use \`make latexpdf' here to do that automatically)."
113 |
114 | latexpdf:
115 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
116 | @echo "Running LaTeX files through pdflatex..."
117 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
118 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
119 |
120 | latexpdfja:
121 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
122 | @echo "Running LaTeX files through platex and dvipdfmx..."
123 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
124 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
125 |
126 | text:
127 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
128 | @echo
129 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
130 |
131 | man:
132 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
133 | @echo
134 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
135 |
136 | texinfo:
137 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
138 | @echo
139 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
140 | @echo "Run \`make' in that directory to run these through makeinfo" \
141 | "(use \`make info' here to do that automatically)."
142 |
143 | info:
144 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
145 | @echo "Running Texinfo files through makeinfo..."
146 | make -C $(BUILDDIR)/texinfo info
147 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
148 |
149 | gettext:
150 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
151 | @echo
152 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
153 |
154 | changes:
155 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
156 | @echo
157 | @echo "The overview file is in $(BUILDDIR)/changes."
158 |
159 | linkcheck:
160 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
161 | @echo
162 | @echo "Link check complete; look for any errors in the above output " \
163 | "or in $(BUILDDIR)/linkcheck/output.txt."
164 |
165 | doctest:
166 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
167 | @echo "Testing of doctests in the sources finished, look at the " \
168 | "results in $(BUILDDIR)/doctest/output.txt."
169 |
170 | xml:
171 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
172 | @echo
173 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
174 |
175 | pseudoxml:
176 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
177 | @echo
178 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
179 |
--------------------------------------------------------------------------------
/doc/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
10 | set I18NSPHINXOPTS=%SPHINXOPTS% source
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 | echo. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. xml to make Docutils-native XML files
37 | echo. pseudoxml to make pseudoxml-XML files for display purposes
38 | echo. linkcheck to check all external links for integrity
39 | echo. doctest to run all doctests embedded in the documentation if enabled
40 | goto end
41 | )
42 |
43 | if "%1" == "clean" (
44 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
45 | del /q /s %BUILDDIR%\*
46 | goto end
47 | )
48 |
49 |
50 | %SPHINXBUILD% 2> nul
51 | if errorlevel 9009 (
52 | echo.
53 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
54 | echo.installed, then set the SPHINXBUILD environment variable to point
55 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
56 | echo.may add the Sphinx directory to PATH.
57 | echo.
58 | echo.If you don't have Sphinx installed, grab it from
59 | echo.http://sphinx-doc.org/
60 | exit /b 1
61 | )
62 |
63 | if "%1" == "html" (
64 | cd .. & python setup.py build_ext --inplace & cd doc
65 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
66 | if errorlevel 1 exit /b 1
67 | echo.
68 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
69 | goto end
70 | )
71 |
72 | if "%1" == "dirhtml" (
73 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
74 | if errorlevel 1 exit /b 1
75 | echo.
76 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
77 | goto end
78 | )
79 |
80 | if "%1" == "singlehtml" (
81 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
82 | if errorlevel 1 exit /b 1
83 | echo.
84 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
85 | goto end
86 | )
87 |
88 | if "%1" == "pickle" (
89 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
90 | if errorlevel 1 exit /b 1
91 | echo.
92 | echo.Build finished; now you can process the pickle files.
93 | goto end
94 | )
95 |
96 | if "%1" == "json" (
97 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
98 | if errorlevel 1 exit /b 1
99 | echo.
100 | echo.Build finished; now you can process the JSON files.
101 | goto end
102 | )
103 |
104 | if "%1" == "htmlhelp" (
105 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
106 | if errorlevel 1 exit /b 1
107 | echo.
108 | echo.Build finished; now you can run HTML Help Workshop with the ^
109 | .hhp project file in %BUILDDIR%/htmlhelp.
110 | goto end
111 | )
112 |
113 | if "%1" == "qthelp" (
114 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
115 | if errorlevel 1 exit /b 1
116 | echo.
117 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
118 | .qhcp project file in %BUILDDIR%/qthelp, like this:
119 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\project_name.qhcp
120 | echo.To view the help file:
121 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\project_name.ghc
122 | goto end
123 | )
124 |
125 | if "%1" == "devhelp" (
126 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
127 | if errorlevel 1 exit /b 1
128 | echo.
129 | echo.Build finished.
130 | goto end
131 | )
132 |
133 | if "%1" == "epub" (
134 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
135 | if errorlevel 1 exit /b 1
136 | echo.
137 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
138 | goto end
139 | )
140 |
141 | if "%1" == "latex" (
142 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
143 | if errorlevel 1 exit /b 1
144 | echo.
145 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
146 | goto end
147 | )
148 |
149 | if "%1" == "latexpdf" (
150 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
151 | cd %BUILDDIR%/latex
152 | make all-pdf
153 | cd %BUILDDIR%/..
154 | echo.
155 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
156 | goto end
157 | )
158 |
159 | if "%1" == "latexpdfja" (
160 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
161 | cd %BUILDDIR%/latex
162 | make all-pdf-ja
163 | cd %BUILDDIR%/..
164 | echo.
165 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
166 | goto end
167 | )
168 |
169 | if "%1" == "text" (
170 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
171 | if errorlevel 1 exit /b 1
172 | echo.
173 | echo.Build finished. The text files are in %BUILDDIR%/text.
174 | goto end
175 | )
176 |
177 | if "%1" == "man" (
178 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
179 | if errorlevel 1 exit /b 1
180 | echo.
181 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
182 | goto end
183 | )
184 |
185 | if "%1" == "texinfo" (
186 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
187 | if errorlevel 1 exit /b 1
188 | echo.
189 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
190 | goto end
191 | )
192 |
193 | if "%1" == "gettext" (
194 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
195 | if errorlevel 1 exit /b 1
196 | echo.
197 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
198 | goto end
199 | )
200 |
201 | if "%1" == "changes" (
202 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
203 | if errorlevel 1 exit /b 1
204 | echo.
205 | echo.The overview file is in %BUILDDIR%/changes.
206 | goto end
207 | )
208 |
209 | if "%1" == "linkcheck" (
210 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
211 | if errorlevel 1 exit /b 1
212 | echo.
213 | echo.Link check complete; look for any errors in the above output ^
214 | or in %BUILDDIR%/linkcheck/output.txt.
215 | goto end
216 | )
217 |
218 | if "%1" == "doctest" (
219 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
220 | if errorlevel 1 exit /b 1
221 | echo.
222 | echo.Testing of doctests in the sources finished, look at the ^
223 | results in %BUILDDIR%/doctest/output.txt.
224 | goto end
225 | )
226 |
227 | if "%1" == "xml" (
228 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
229 | if errorlevel 1 exit /b 1
230 | echo.
231 | echo.Build finished. The XML files are in %BUILDDIR%/xml.
232 | goto end
233 | )
234 |
235 | if "%1" == "pseudoxml" (
236 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
237 | if errorlevel 1 exit /b 1
238 | echo.
239 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
240 | goto end
241 | )
242 |
243 | :end
244 |
--------------------------------------------------------------------------------
/doc/source/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # FFPyPlayer documentation build configuration file, created by
4 | # sphinx-quickstart on Mon Dec 23 18:07:03 2013.
5 | #
6 | # This file is execfile()d with the current directory set to its
7 | # containing dir.
8 | #
9 | # Note that not all possible configuration values are present in this
10 | # autogenerated file.
11 | #
12 | # All configuration values have a default; values that are commented out
13 | # serve to show the default.
14 |
15 | import sys
16 | import os
17 |
18 | # If extensions (or modules to document with autodoc) are in another directory,
19 | # add these directories to sys.path here. If the directory is relative to the
20 | # documentation root, use os.path.abspath to make it absolute, like shown here.
21 | sys.path.insert(0, os.path.abspath('../../'))
22 |
23 | # -- General configuration ------------------------------------------------
24 |
25 | # If your documentation needs a minimal Sphinx version, state it here.
26 | #needs_sphinx = '1.0'
27 |
28 | # Add any Sphinx extension module names here, as strings. They can be
29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
30 | # ones.
31 | extensions = [
32 | 'sphinx.ext.autodoc',
33 | 'sphinx.ext.todo',
34 | 'sphinx.ext.coverage',
35 | 'sphinx.ext.extlinks',
36 | ]
37 |
38 | extlinks = {'kivy_fchooser': (
39 | 'http://kivy.org/docs/api-kivy.uix.filechooser.html#%s', '')}
40 |
41 | # Add any paths that contain templates here, relative to this directory.
42 | templates_path = ['_templates']
43 |
44 | # The suffix of source filenames.
45 | source_suffix = '.rst'
46 |
47 | # The encoding of source files.
48 | #source_encoding = 'utf-8-sig'
49 |
50 | # The master toctree document.
51 | master_doc = 'index'
52 |
53 | # General information about the project.
54 | project = u'FileBrowser'
55 | copyright = u'MIT - 2013, Matthew Einhorn'
56 | author = u'Matthew Einhorn'
57 |
58 | # The version info for the project you're documenting, acts as replacement for
59 | # |version| and |release|, also used in various other places throughout the
60 | # built documents.
61 | #
62 | # The short X.Y version.
63 | version = '1.1-dev'
64 | # The full version, including alpha/beta/rc tags.
65 | release = '1.1-dev'
66 |
67 | # The language for content autogenerated by Sphinx. Refer to documentation
68 | # for a list of supported languages.
69 | #language = None
70 |
71 | # There are two options for replacing |today|: either, you set today to some
72 | # non-false value, then it is used:
73 | #today = ''
74 | # Else, today_fmt is used as the format for a strftime call.
75 | #today_fmt = '%B %d, %Y'
76 |
77 | # List of patterns, relative to source directory, that match files and
78 | # directories to ignore when looking for source files.
79 | exclude_patterns = []
80 |
81 | # The reST default role (used for this markup: `text`) to use for all
82 | # documents.
83 | #default_role = None
84 |
85 | # If true, '()' will be appended to :func: etc. cross-reference text.
86 | #add_function_parentheses = True
87 |
88 | # If true, the current module name will be prepended to all description
89 | # unit titles (such as .. function::).
90 | #add_module_names = True
91 |
92 | # If true, sectionauthor and moduleauthor directives will be shown in the
93 | # output. They are ignored by default.
94 | #show_authors = False
95 |
96 | # The name of the Pygments (syntax highlighting) style to use.
97 | pygments_style = 'sphinx'
98 |
99 | # A list of ignored prefixes for module index sorting.
100 | #modindex_common_prefix = []
101 |
102 | # If true, keep warnings as "system message" paragraphs in the built documents.
103 | #keep_warnings = False
104 |
105 |
106 | # -- Options for HTML output ----------------------------------------------
107 |
108 | # The theme to use for HTML and HTML Help pages. See the documentation for
109 | # a list of builtin themes.
110 | html_theme = 'default'
111 |
112 | # Theme options are theme-specific and customize the look and feel of a theme
113 | # further. For a list of options available for each theme, see the
114 | # documentation.
115 | #html_theme_options = {}
116 |
117 | # Add any paths that contain custom themes here, relative to this directory.
118 | #html_theme_path = []
119 |
120 | # The name for this set of Sphinx documents. If None, it defaults to
121 | # " v documentation".
122 | #html_title = None
123 |
124 | # A shorter title for the navigation bar. Default is the same as html_title.
125 | #html_short_title = None
126 |
127 | # The name of an image file (relative to this directory) to place at the top
128 | # of the sidebar.
129 | #html_logo = None
130 |
131 | # The name of an image file (within the static path) to use as favicon of the
132 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
133 | # pixels large.
134 | #html_favicon = None
135 |
136 | # Add any paths that contain custom static files (such as style sheets) here,
137 | # relative to this directory. They are copied after the builtin static files,
138 | # so a file named "default.css" will overwrite the builtin "default.css".
139 | html_static_path = ['_static']
140 |
141 | # Add any extra paths that contain custom files (such as robots.txt or
142 | # .htaccess) here, relative to this directory. These files are copied
143 | # directly to the root of the documentation.
144 | #html_extra_path = []
145 |
146 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
147 | # using the given strftime format.
148 | #html_last_updated_fmt = '%b %d, %Y'
149 |
150 | # If true, SmartyPants will be used to convert quotes and dashes to
151 | # typographically correct entities.
152 | #html_use_smartypants = True
153 |
154 | # Custom sidebar templates, maps document names to template names.
155 | #html_sidebars = {}
156 |
157 | # Additional templates that should be rendered to pages, maps page names to
158 | # template names.
159 | #html_additional_pages = {}
160 |
161 | # If false, no module index is generated.
162 | #html_domain_indices = True
163 |
164 | # If false, no index is generated.
165 | #html_use_index = True
166 |
167 | # If true, the index is split into individual pages for each letter.
168 | #html_split_index = False
169 |
170 | # If true, links to the reST sources are added to the pages.
171 | #html_show_sourcelink = True
172 |
173 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
174 | #html_show_sphinx = True
175 |
176 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
177 | #html_show_copyright = True
178 |
179 | # If true, an OpenSearch description file will be output, and all pages will
180 | # contain a tag referring to it. The value of this option must be the
181 | # base URL from which the finished HTML is served.
182 | #html_use_opensearch = ''
183 |
184 | # This is the file name suffix for HTML files (e.g. ".xhtml").
185 | #html_file_suffix = None
186 |
187 | # Output file base name for HTML help builder.
188 | htmlhelp_basename = project + 'doc'
189 |
190 |
191 | # -- Options for LaTeX output ---------------------------------------------
192 |
193 | latex_elements = {
194 | # The paper size ('letterpaper' or 'a4paper').
195 | #'papersize': 'letterpaper',
196 |
197 | # The font size ('10pt', '11pt' or '12pt').
198 | #'pointsize': '10pt',
199 |
200 | # Additional stuff for the LaTeX preamble.
201 | #'preamble': '',
202 | }
203 |
204 | # Grouping the document tree into LaTeX files. List of tuples
205 | # (source start file, target name, title,
206 | # author, documentclass [howto, manual, or own class]).
207 | latex_documents = [
208 | ('index', project + '.tex', project + u' Documentation',
209 | author, 'manual'),
210 | ]
211 |
212 | # The name of an image file (relative to this directory) to place at the top of
213 | # the title page.
214 | #latex_logo = None
215 |
216 | # For "manual" documents, if this is true, then toplevel headings are parts,
217 | # not chapters.
218 | #latex_use_parts = False
219 |
220 | # If true, show page references after internal links.
221 | #latex_show_pagerefs = False
222 |
223 | # If true, show URL addresses after external links.
224 | #latex_show_urls = False
225 |
226 | # Documents to append as an appendix to all manuals.
227 | #latex_appendices = []
228 |
229 | # If false, no module index is generated.
230 | #latex_domain_indices = True
231 |
232 |
233 | # -- Options for manual page output ---------------------------------------
234 |
235 | # One entry per manual page. List of tuples
236 | # (source start file, name, description, authors, manual section).
237 | man_pages = [
238 | ('index', project, project + u' Documentation',
239 | [author], 1)
240 | ]
241 |
242 | # If true, show URL addresses after external links.
243 | #man_show_urls = False
244 |
245 |
246 | # -- Options for Texinfo output -------------------------------------------
247 |
248 | # Grouping the document tree into Texinfo files. List of tuples
249 | # (source start file, target name, title, author,
250 | # dir menu entry, description, category)
251 | texinfo_documents = [
252 | ('index', project, project + u' Documentation',
253 | author, project, 'One line description of project.',
254 | 'Miscellaneous'),
255 | ]
256 |
257 | # Documents to append as an appendix to all manuals.
258 | #texinfo_appendices = []
259 |
260 | # If false, no module index is generated.
261 | #texinfo_domain_indices = True
262 |
263 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
264 | #texinfo_show_urls = 'footnote'
265 |
266 | # If true, do not generate a @detailmenu in the "Top" node's menu.
267 | #texinfo_no_detailmenu = False
268 |
--------------------------------------------------------------------------------
/doc/source/_static/default.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Alternate Sphinx design
3 | * Originally created by Armin Ronacher for Werkzeug, adapted by Georg Brandl.
4 | */
5 |
6 | body {
7 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva', 'Verdana', sans-serif;
8 | font-size: 14px;
9 | letter-spacing: -0.01em;
10 | line-height: 150%;
11 | text-align: center;
12 | /*background-color: #AFC1C4; */
13 | background-color: #BFD1D4;
14 | color: black;
15 | padding: 0;
16 | border: 1px solid #aaa;
17 |
18 | margin: 0px 80px 0px 80px;
19 | min-width: 740px;
20 | }
21 |
22 | a {
23 | color: #CA7900;
24 | text-decoration: none;
25 | }
26 |
27 | a:hover {
28 | color: #2491CF;
29 | }
30 |
31 | pre {
32 | font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
33 | font-size: 0.95em;
34 | letter-spacing: 0.015em;
35 | padding: 0.5em;
36 | border: 1px solid #ccc;
37 | background-color: #f8f8f8;
38 | }
39 |
40 | td.linenos pre {
41 | padding: 0.5em 0;
42 | border: 0;
43 | background-color: transparent;
44 | color: #aaa;
45 | }
46 |
47 | table.highlighttable {
48 | margin-left: 0.5em;
49 | }
50 |
51 | table.highlighttable td {
52 | padding: 0 0.5em 0 0.5em;
53 | }
54 |
55 | cite, code, tt {
56 | font-family: 'Consolas', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
57 | font-size: 0.95em;
58 | letter-spacing: 0.01em;
59 | }
60 |
61 | hr {
62 | border: 1px solid #abc;
63 | margin: 2em;
64 | }
65 |
66 | tt {
67 | background-color: #f2f2f2;
68 | border-bottom: 1px solid #ddd;
69 | color: #333;
70 | }
71 |
72 | tt.descname {
73 | background-color: transparent;
74 | font-weight: bold;
75 | font-size: 1.2em;
76 | border: 0;
77 | }
78 |
79 | tt.descclassname {
80 | background-color: transparent;
81 | border: 0;
82 | }
83 |
84 | tt.xref {
85 | background-color: transparent;
86 | font-weight: bold;
87 | border: 0;
88 | }
89 |
90 | a tt {
91 | background-color: transparent;
92 | font-weight: bold;
93 | border: 0;
94 | color: #CA7900;
95 | }
96 |
97 | a tt:hover {
98 | color: #2491CF;
99 | }
100 |
101 | dl {
102 | margin-bottom: 15px;
103 | }
104 |
105 | dd p {
106 | margin-top: 0px;
107 | }
108 |
109 | dd ul, dd table {
110 | margin-bottom: 10px;
111 | }
112 |
113 | dd {
114 | margin-top: 3px;
115 | margin-bottom: 10px;
116 | margin-left: 30px;
117 | }
118 |
119 | .refcount {
120 | color: #060;
121 | }
122 |
123 | dt:target,
124 | .highlight {
125 | background-color: #fbe54e;
126 | }
127 |
128 | dl.class, dl.function {
129 | border-top: 2px solid #888;
130 | }
131 |
132 | dl.method, dl.attribute {
133 | border-top: 1px solid #aaa;
134 | }
135 |
136 | dl.glossary dt {
137 | font-weight: bold;
138 | font-size: 1.1em;
139 | }
140 |
141 | pre {
142 | line-height: 120%;
143 | }
144 |
145 | pre a {
146 | color: inherit;
147 | text-decoration: underline;
148 | }
149 |
150 | .first {
151 | margin-top: 0 !important;
152 | }
153 |
154 | div.document {
155 | background-color: white;
156 | text-align: left;
157 | background-image: url(contents.png);
158 | background-repeat: repeat-x;
159 | }
160 |
161 | /*
162 | div.documentwrapper {
163 | width: 100%;
164 | }
165 | */
166 |
167 | div.clearer {
168 | clear: both;
169 | }
170 |
171 | div.related h3 {
172 | display: none;
173 | }
174 |
175 | div.related ul {
176 | background-image: url(navigation.png);
177 | height: 2em;
178 | list-style: none;
179 | border-top: 1px solid #ddd;
180 | border-bottom: 1px solid #ddd;
181 | margin: 0;
182 | padding-left: 10px;
183 | }
184 |
185 | div.related ul li {
186 | margin: 0;
187 | padding: 0;
188 | height: 2em;
189 | float: left;
190 | }
191 |
192 | div.related ul li.right {
193 | float: right;
194 | margin-right: 5px;
195 | }
196 |
197 | div.related ul li a {
198 | margin: 0;
199 | padding: 0 5px 0 5px;
200 | line-height: 1.75em;
201 | color: #EE9816;
202 | }
203 |
204 | div.related ul li a:hover {
205 | color: #3CA8E7;
206 | }
207 |
208 | div.body {
209 | margin: 0;
210 | padding: 0.5em 20px 20px 20px;
211 | }
212 |
213 | div.bodywrapper {
214 | margin: 0 240px 0 0;
215 | border-right: 1px solid #ccc;
216 | }
217 |
218 | div.body a {
219 | text-decoration: underline;
220 | }
221 |
222 | div.sphinxsidebar {
223 | margin: 0;
224 | padding: 0.5em 15px 15px 0;
225 | width: 210px;
226 | float: right;
227 | text-align: left;
228 | /* margin-left: -100%; */
229 | }
230 |
231 | div.sphinxsidebar h4, div.sphinxsidebar h3 {
232 | margin: 1em 0 0.5em 0;
233 | font-size: 0.9em;
234 | padding: 0.1em 0 0.1em 0.5em;
235 | color: white;
236 | border: 1px solid #86989B;
237 | background-color: #AFC1C4;
238 | }
239 |
240 | div.sphinxsidebar ul {
241 | padding-left: 1.5em;
242 | margin-top: 7px;
243 | list-style: none;
244 | padding: 0;
245 | line-height: 130%;
246 | }
247 |
248 | div.sphinxsidebar ul ul {
249 | list-style: square;
250 | margin-left: 20px;
251 | }
252 |
253 | p {
254 | margin: 0.8em 0 0.5em 0;
255 | }
256 |
257 | p.rubric {
258 | font-weight: bold;
259 | }
260 |
261 | h1 {
262 | margin: 0;
263 | padding: 0.7em 0 0.3em 0;
264 | font-size: 1.5em;
265 | color: #11557C;
266 | }
267 |
268 | h2 {
269 | margin: 1.3em 0 0.2em 0;
270 | font-size: 1.35em;
271 | padding: 0;
272 | }
273 |
274 | h3 {
275 | margin: 1em 0 -0.3em 0;
276 | font-size: 1.2em;
277 | }
278 |
279 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
280 | color: black!important;
281 | }
282 |
283 | h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
284 | display: none;
285 | margin: 0 0 0 0.3em;
286 | padding: 0 0.2em 0 0.2em;
287 | color: #aaa!important;
288 | }
289 |
290 | h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
291 | h5:hover a.anchor, h6:hover a.anchor {
292 | display: inline;
293 | }
294 |
295 | h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
296 | h5 a.anchor:hover, h6 a.anchor:hover {
297 | color: #777;
298 | background-color: #eee;
299 | }
300 |
301 | table {
302 | border-collapse: collapse;
303 | margin: 0 -0.5em 0 -0.5em;
304 | }
305 |
306 | table td, table th {
307 | padding: 0.2em 0.5em 0.2em 0.5em;
308 | }
309 |
310 | div.footer {
311 | background-color: #E3EFF1;
312 | color: #86989B;
313 | padding: 3px 8px 3px 0;
314 | clear: both;
315 | font-size: 0.8em;
316 | text-align: right;
317 | }
318 |
319 | div.footer a {
320 | color: #86989B;
321 | text-decoration: underline;
322 | }
323 |
324 | div.pagination {
325 | margin-top: 2em;
326 | padding-top: 0.5em;
327 | border-top: 1px solid black;
328 | text-align: center;
329 | }
330 |
331 | div.sphinxsidebar ul.toc {
332 | margin: 1em 0 1em 0;
333 | padding: 0 0 0 0.5em;
334 | list-style: none;
335 | }
336 |
337 | div.sphinxsidebar ul.toc li {
338 | margin: 0.5em 0 0.5em 0;
339 | font-size: 0.9em;
340 | line-height: 130%;
341 | }
342 |
343 | div.sphinxsidebar ul.toc li p {
344 | margin: 0;
345 | padding: 0;
346 | }
347 |
348 | div.sphinxsidebar ul.toc ul {
349 | margin: 0.2em 0 0.2em 0;
350 | padding: 0 0 0 1.8em;
351 | }
352 |
353 | div.sphinxsidebar ul.toc ul li {
354 | padding: 0;
355 | }
356 |
357 | div.admonition, div.warning {
358 | font-size: 0.9em;
359 | margin: 1em 0 0 0;
360 | border: 1px solid #86989B;
361 | background-color: #f7f7f7;
362 | }
363 |
364 | div.admonition p, div.warning p {
365 | margin: 0.5em 1em 0.5em 1em;
366 | padding: 0;
367 | }
368 |
369 | div.admonition pre, div.warning pre {
370 | margin: 0.4em 1em 0.4em 1em;
371 | }
372 |
373 | div.admonition p.admonition-title,
374 | div.warning p.admonition-title {
375 | margin: 0;
376 | padding: 0.1em 0 0.1em 0.5em;
377 | color: white;
378 | border-bottom: 1px solid #86989B;
379 | font-weight: bold;
380 | background-color: #AFC1C4;
381 | }
382 |
383 | div.warning {
384 | border: 1px solid #940000;
385 | }
386 |
387 | div.warning p.admonition-title {
388 | background-color: #CF0000;
389 | border-bottom-color: #940000;
390 | }
391 |
392 | div.admonition ul, div.admonition ol,
393 | div.warning ul, div.warning ol {
394 | margin: 0.1em 0.5em 0.5em 3em;
395 | padding: 0;
396 | }
397 |
398 | div.versioninfo {
399 | margin: 1em 0 0 0;
400 | border: 1px solid #ccc;
401 | background-color: #DDEAF0;
402 | padding: 8px;
403 | line-height: 1.3em;
404 | font-size: 0.9em;
405 | }
406 |
407 |
408 | a.headerlink {
409 | color: #c60f0f!important;
410 | font-size: 1em;
411 | margin-left: 6px;
412 | padding: 0 4px 0 4px;
413 | text-decoration: none!important;
414 | visibility: hidden;
415 | }
416 |
417 | h1:hover > a.headerlink,
418 | h2:hover > a.headerlink,
419 | h3:hover > a.headerlink,
420 | h4:hover > a.headerlink,
421 | h5:hover > a.headerlink,
422 | h6:hover > a.headerlink,
423 | dt:hover > a.headerlink {
424 | visibility: visible;
425 | }
426 |
427 | a.headerlink:hover {
428 | background-color: #ccc;
429 | color: white!important;
430 | }
431 |
432 | table.indextable td {
433 | text-align: left;
434 | vertical-align: top;
435 | }
436 |
437 | table.indextable dl, table.indextable dd {
438 | margin-top: 0;
439 | margin-bottom: 0;
440 | }
441 |
442 | table.indextable tr.pcap {
443 | height: 10px;
444 | }
445 |
446 | table.indextable tr.cap {
447 | margin-top: 10px;
448 | background-color: #f2f2f2;
449 | }
450 |
451 | img.toggler {
452 | margin-right: 3px;
453 | margin-top: 3px;
454 | cursor: pointer;
455 | }
456 |
457 | img.inheritance {
458 | border: 0px
459 | }
460 |
461 | form.pfform {
462 | margin: 10px 0 20px 0;
463 | }
464 |
465 | table.contentstable {
466 | width: 90%;
467 | }
468 |
469 | table.contentstable p.biglink {
470 | line-height: 150%;
471 | }
472 |
473 | a.biglink {
474 | font-size: 1.3em;
475 | }
476 |
477 | span.linkdescr {
478 | font-style: italic;
479 | padding-top: 5px;
480 | font-size: 90%;
481 | }
482 |
483 | ul.search {
484 | margin: 10px 0 0 20px;
485 | padding: 0;
486 | }
487 |
488 | ul.search li {
489 | padding: 5px 0 5px 20px;
490 | background-image: url(file.png);
491 | background-repeat: no-repeat;
492 | background-position: 0 7px;
493 | }
494 |
495 | ul.search li a {
496 | font-weight: bold;
497 | }
498 |
499 | ul.search li div.context {
500 | color: #888;
501 | margin: 2px 0 0 30px;
502 | text-align: left;
503 | }
504 |
505 | ul.keywordmatches li.goodmatch a {
506 | font-weight: bold;
507 | }
508 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
1 | '''
2 | FileBrowser
3 | ===========
4 |
5 | The :class:`FileBrowser` widget is an advanced file browser. You use it
6 | similarly to FileChooser usage.
7 |
8 | It provides a shortcut bar with links to special and system directories.
9 | When touching next to a shortcut in the links bar, it'll expand and show
10 | all the directories within that directory. It also facilitates specifying
11 | custom paths to be added to the shortcuts list.
12 |
13 | It provides a icon and list view to choose files from. And it also accepts
14 | filter and filename inputs.
15 |
16 | To create a FileBrowser which prints the currently selected file as well as
17 | the current text in the filename field when 'Select' is pressed, with
18 | a shortcut to the Documents directory added to the favorites bar::
19 |
20 | import os
21 | from kivy.app import App
22 |
23 | class TestApp(App):
24 |
25 | def build(self):
26 | user_path = os.path.join(get_home_directory(), 'Documents')
27 | browser = FileBrowser(select_string='Select',
28 | favorites=[(user_path, 'Documents')])
29 | browser.bind(on_success=self._fbrowser_success,
30 | on_canceled=self._fbrowser_canceled,
31 | on_submit=self._fbrowser_submit)
32 | return browser
33 |
34 | def _fbrowser_canceled(self, instance):
35 | print('cancelled, Close self.')
36 |
37 | def _fbrowser_success(self, instance):
38 | print(instance.selection)
39 |
40 | def _fbrowser_submit(self, instance):
41 | print(instance.selection)
42 |
43 | TestApp().run()
44 |
45 | :Events:
46 | `on_canceled`:
47 | Fired when the `Cancel` buttons `on_release` event is called.
48 |
49 | `on_success`:
50 | Fired when the `Select` buttons `on_release` event is called.
51 |
52 | `on_success`:
53 | Fired when a file has been selected with a double-tap.
54 |
55 | .. image:: _static/filebrowser.png
56 | :align: right
57 | '''
58 |
59 | __all__ = ('FileBrowser', )
60 | __version__ = '1.1-dev'
61 |
62 | from kivy.uix.boxlayout import BoxLayout
63 | from kivy.uix.treeview import TreeViewLabel, TreeView
64 | from kivy.uix.filechooser import FileChooserIconView as IconView
65 | try:
66 | from kivy.garden.filechooserthumbview import FileChooserThumbView as\
67 | IconView
68 | except:
69 | pass
70 | from kivy.properties import (ObjectProperty, StringProperty, OptionProperty,
71 | ListProperty, BooleanProperty)
72 | from kivy.lang import Builder
73 | from kivy.utils import platform
74 | from kivy.clock import Clock
75 | from kivy.compat import PY2
76 | import string
77 | from os.path import sep, dirname, expanduser, isdir, join
78 | from os import walk
79 | from sys import getfilesystemencoding
80 | from functools import partial
81 |
82 | if platform == 'win':
83 | from ctypes import windll, create_unicode_buffer
84 |
85 |
86 | def get_home_directory():
87 | if platform == 'win':
88 | user_path = expanduser('~')
89 |
90 | if not isdir(join(user_path, 'Desktop')):
91 | user_path = dirname(user_path)
92 |
93 | else:
94 | user_path = expanduser('~')
95 |
96 | if PY2:
97 | user_path = user_path.decode(getfilesystemencoding())
98 |
99 | return user_path
100 |
101 |
102 | def get_drives():
103 | drives = []
104 | if platform == 'win':
105 | bitmask = windll.kernel32.GetLogicalDrives()
106 | GetVolumeInformationW = windll.kernel32.GetVolumeInformationW
107 | for letter in string.ascii_uppercase:
108 | if bitmask & 1:
109 | name = create_unicode_buffer(64)
110 | # get name of the drive
111 | drive = letter + u':'
112 | res = GetVolumeInformationW(drive + sep, name, 64, None,
113 | None, None, None, 0)
114 | drives.append((drive, name.value))
115 | bitmask >>= 1
116 | elif platform == 'linux':
117 | drives.append((sep, sep))
118 | drives.append((expanduser(u'~'), '~/'))
119 | places = (sep + u'mnt', sep + u'media')
120 | for place in places:
121 | if isdir(place):
122 | for directory in next(walk(place))[1]:
123 | drives.append((place + sep + directory, directory))
124 | elif platform == 'macosx' or platform == 'ios':
125 | drives.append((expanduser(u'~'), '~/'))
126 | vol = sep + u'Volume'
127 | if isdir(vol):
128 | for drive in next(walk(vol))[1]:
129 | drives.append((vol + sep + drive, drive))
130 | return drives
131 |
132 | class FileBrowserIconView(IconView):
133 | pass
134 |
135 | Builder.load_string('''
136 | #:kivy 1.2.0
137 | #:import metrics kivy.metrics
138 | #:import abspath os.path.abspath
139 |
140 | :
141 | on_touch_down:
142 | self.parent.browser.current_tab.content.path = self.path if\
143 | self.collide_point(*args[1].pos) and self.path else\
144 | self.parent.browser.current_tab.content.path
145 | on_is_open: self.is_open and self.parent.trigger_populate(self)
146 |
147 | :
148 | orientation: 'vertical'
149 | spacing: 5
150 | padding: [6, 6, 6, 6]
151 | select_state: select_button.state
152 | cancel_state: cancel_button.state
153 | filename: file_text.text
154 | on_favorites: link_tree.reload_favs(self.favorites)
155 | BoxLayout:
156 | orientation: 'horizontal'
157 | spacing: 5
158 | Splitter:
159 | sizable_from: 'right'
160 | min_size: '153sp'
161 | size_hint: (.2, 1)
162 | id: splitter
163 | ScrollView:
164 | LinkTree:
165 | id: link_tree
166 | browser: tabbed_browser
167 | size_hint_y: None
168 | height: self.minimum_height
169 | on_parent: self.fill_tree(root.favorites)
170 | root_options: {'text': 'Locations', 'no_selection':True}
171 | BoxLayout:
172 | size_hint_x: .8
173 | orientation: 'vertical'
174 | Label:
175 | size_hint_y: None
176 | height: '22dp'
177 | text_size: self.size
178 | padding_x: '10dp'
179 | text: abspath(root.path)
180 | valign: 'middle'
181 | TabbedPanel:
182 | id: tabbed_browser
183 | do_default_tab: False
184 | TabbedPanelItem:
185 | text: 'List View'
186 | FileChooserListView:
187 | id: list_view
188 | path: root.path
189 | filters: root.filters
190 | filter_dirs: root.filter_dirs
191 | show_hidden: root.show_hidden
192 | multiselect: root.multiselect
193 | dirselect: root.dirselect
194 | rootpath: root.rootpath
195 | on_submit: root.dispatch('on_submit')
196 | TabbedPanelItem:
197 | text: 'Icon View'
198 | FileBrowserIconView:
199 | id: icon_view
200 | path: root.path
201 | filters: root.filters
202 | filter_dirs: root.filter_dirs
203 | show_hidden: root.show_hidden
204 | multiselect: root.multiselect
205 | dirselect: root.dirselect
206 | rootpath: root.rootpath
207 | on_submit: root.dispatch('on_submit')
208 | GridLayout:
209 | size_hint: (1, None)
210 | height: file_text.line_height * 4
211 | cols: 2
212 | rows: 2
213 | spacing: [5]
214 | TextInput:
215 | id: file_text
216 | text: (root.selection and (root._shorten_filenames(\
217 | root.selection) if root.multiselect else root.selection[0])) or ''
218 | hint_text: 'Filename'
219 | multiline: False
220 | Button:
221 | id: select_button
222 | size_hint_x: None
223 | width: metrics.dp(100)
224 | text: root.select_string
225 | on_release: root.dispatch('on_success')
226 | TextInput:
227 | id: filt_text
228 | hint_text: '*.*'
229 | on_text_validate:
230 | root.filters = self.text.split(',') if self.text else []
231 | multiline: False
232 | text: ','.join([filt for filt in root.filters if isinstance(filt, str)])
233 | Button:
234 | id: cancel_button
235 | size_hint_x: None
236 | width: metrics.dp(100)
237 | text: root.cancel_string
238 | on_release: root.dispatch('on_canceled')
239 |
240 | ''')
241 |
242 |
243 | class TreeLabel(TreeViewLabel):
244 | path = StringProperty('')
245 | '''Full path to the location this node points to.
246 |
247 | :class:`~kivy.properties.StringProperty`, defaults to ''
248 | '''
249 |
250 |
251 | class LinkTree(TreeView):
252 | # link to the favorites section of link bar
253 | _favs = ObjectProperty(None)
254 | _computer_node = None
255 |
256 | def fill_tree(self, fav_list):
257 | user_path = get_home_directory()
258 | self._favs = self.add_node(TreeLabel(text='Favorites', is_open=True,
259 | no_selection=True))
260 | self.reload_favs(fav_list)
261 |
262 | libs = self.add_node(TreeLabel(text='Libraries', is_open=True,
263 | no_selection=True))
264 | places = ('Documents', 'Music', 'Pictures', 'Videos')
265 | for place in places:
266 | if isdir(join(user_path, place)):
267 | self.add_node(TreeLabel(text=place, path=join(user_path,
268 | place)), libs)
269 | self._computer_node = self.add_node(TreeLabel(text='Computer',\
270 | is_open=True, no_selection=True))
271 | self._computer_node.bind(on_touch_down=self._drives_touch)
272 | self.reload_drives()
273 |
274 | def _drives_touch(self, obj, touch):
275 | if obj.collide_point(*touch.pos):
276 | self.reload_drives()
277 |
278 | def reload_drives(self):
279 | nodes = [(node, node.text + node.path) for node in\
280 | self._computer_node.nodes if isinstance(node, TreeLabel)]
281 | sigs = [s[1] for s in nodes]
282 | nodes_new = []
283 | sig_new = []
284 | for path, name in get_drives():
285 | if platform == 'win':
286 | text = u'{}({})'.format((name + ' ') if name else '', path)
287 | else:
288 | text = name
289 | nodes_new.append((text, path))
290 | sig_new.append(text + path + sep)
291 | for node, sig in nodes:
292 | if sig not in sig_new:
293 | self.remove_node(node)
294 | for text, path in nodes_new:
295 | if text + path + sep not in sigs:
296 | self.add_node(TreeLabel(text=text, path=path + sep),
297 | self._computer_node)
298 |
299 | def reload_favs(self, fav_list):
300 | user_path = get_home_directory()
301 | favs = self._favs
302 | remove = []
303 | for node in self.iterate_all_nodes(favs):
304 | if node != favs:
305 | remove.append(node)
306 | for node in remove:
307 | self.remove_node(node)
308 | places = ('Desktop', 'Downloads')
309 | for place in places:
310 | if isdir(join(user_path, place)):
311 | self.add_node(TreeLabel(text=place, path=join(user_path,
312 | place)), favs)
313 | for path, name in fav_list:
314 | if isdir(path):
315 | self.add_node(TreeLabel(text=name, path=path), favs)
316 |
317 | def trigger_populate(self, node):
318 | if not node.path or node.nodes:
319 | return
320 | parent = node.path
321 | _next = next(walk(parent))
322 | if _next:
323 | for path in _next[1]:
324 | self.add_node(TreeLabel(text=path, path=parent + sep + path),
325 | node)
326 |
327 |
328 | class FileBrowser(BoxLayout):
329 | '''FileBrowser class, see module documentation for more information.
330 | '''
331 |
332 | __events__ = ('on_canceled', 'on_success', 'on_submit')
333 |
334 | select_state = OptionProperty('normal', options=('normal', 'down'))
335 | '''State of the 'select' button, must be one of 'normal' or 'down'.
336 | The state is 'down' only when the button is currently touched/clicked,
337 | otherwise 'normal'. This button functions as the typical Ok/Select/Save
338 | button.
339 |
340 | :data:`select_state` is an :class:`~kivy.properties.OptionProperty`.
341 | '''
342 | cancel_state = OptionProperty('normal', options=('normal', 'down'))
343 | '''State of the 'cancel' button, must be one of 'normal' or 'down'.
344 | The state is 'down' only when the button is currently touched/clicked,
345 | otherwise 'normal'. This button functions as the typical cancel button.
346 |
347 | :data:`cancel_state` is an :class:`~kivy.properties.OptionProperty`.
348 | '''
349 |
350 | select_string = StringProperty('Ok')
351 | '''Label of the 'select' button.
352 |
353 | :data:`select_string` is an :class:`~kivy.properties.StringProperty`,
354 | defaults to 'Ok'.
355 | '''
356 |
357 | cancel_string = StringProperty('Cancel')
358 | '''Label of the 'cancel' button.
359 |
360 | :data:`cancel_string` is an :class:`~kivy.properties.StringProperty`,
361 | defaults to 'Cancel'.
362 | '''
363 |
364 | filename = StringProperty('')
365 | '''The current text in the filename field. Read only. When multiselect is
366 | True, the list of selected filenames is shortened. If shortened, filename
367 | will contain an ellipsis.
368 |
369 | :data:`filename` is an :class:`~kivy.properties.StringProperty`,
370 | defaults to ''.
371 |
372 | .. versionchanged:: 1.1
373 | '''
374 |
375 | selection = ListProperty([])
376 | '''Read-only :class:`~kivy.properties.ListProperty`.
377 | Contains the list of files that are currently selected in the current tab.
378 | See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.selection`.
379 |
380 | .. versionchanged:: 1.1
381 | '''
382 |
383 | path = StringProperty(u'/')
384 | '''
385 | :class:`~kivy.properties.StringProperty`, defaults to the current working
386 | directory as a unicode string. It specifies the path on the filesystem that
387 | browser should refer to.
388 | See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.path`.
389 |
390 | .. versionadded:: 1.1
391 | '''
392 |
393 | filters = ListProperty([])
394 | ''':class:`~kivy.properties.ListProperty`, defaults to [], equal to '\*'.
395 | Specifies the filters to be applied to the files in the directory.
396 | See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.filters`.
397 |
398 | Filering keywords that the user types into the filter field as a comma
399 | separated list will be reflected here.
400 |
401 | .. versionadded:: 1.1
402 | '''
403 |
404 | filter_dirs = BooleanProperty(False)
405 | '''
406 | :class:`~kivy.properties.BooleanProperty`, defaults to False.
407 | Indicates whether filters should also apply to directories.
408 | See
409 | :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.filter_dirs`.
410 |
411 | .. versionadded:: 1.1
412 | '''
413 |
414 | show_hidden = BooleanProperty(False)
415 | '''
416 | :class:`~kivy.properties.BooleanProperty`, defaults to False.
417 | Determines whether hidden files and folders should be shown.
418 | See
419 | :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.show_hidden`.
420 |
421 | .. versionadded:: 1.1
422 | '''
423 |
424 | multiselect = BooleanProperty(False)
425 | '''
426 | :class:`~kivy.properties.BooleanProperty`, defaults to False.
427 | Determines whether the user is able to select multiple files or not.
428 | See
429 | :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.multiselect`.
430 |
431 | .. versionadded:: 1.1
432 | '''
433 |
434 | dirselect = BooleanProperty(False)
435 | '''
436 | :class:`~kivy.properties.BooleanProperty`, defaults to False.
437 | Determines whether directories are valid selections or not.
438 | See
439 | :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.dirselect`.
440 |
441 | .. versionadded:: 1.1
442 | '''
443 |
444 | rootpath = StringProperty(None, allownone=True)
445 | '''
446 | Root path to use instead of the system root path. If set, it will not show
447 | a ".." directory to go up to the root path. For example, if you set
448 | rootpath to /users/foo, the user will be unable to go to /users or to any
449 | other directory not starting with /users/foo.
450 | :class:`~kivy.properties.StringProperty`, defaults to None.
451 | See :kivy_fchooser:`kivy.uix.filechooser.FileChooserController.rootpath`.
452 |
453 | .. versionadded:: 1.1
454 | '''
455 |
456 | favorites = ListProperty([])
457 | '''A list of the paths added to the favorites link bar. Each element
458 | is a tuple where the first element is a string containing the full path
459 | to the location, while the second element is a string with the name of
460 | path to be displayed.
461 |
462 | :data:`favorites` is an :class:`~kivy.properties.ListProperty`,
463 | defaults to '[]'.
464 | '''
465 |
466 | def on_success(self):
467 | pass
468 |
469 | def on_canceled(self):
470 | pass
471 |
472 | def on_submit(self):
473 | pass
474 |
475 | def __init__(self, **kwargs):
476 | super(FileBrowser, self).__init__(**kwargs)
477 | Clock.schedule_once(self._post_init)
478 |
479 | def _post_init(self, *largs):
480 | self.ids.icon_view.bind(selection=partial(self._attr_callback, 'selection'),
481 | path=partial(self._attr_callback, 'path'),
482 | filters=partial(self._attr_callback, 'filters'),
483 | filter_dirs=partial(self._attr_callback, 'filter_dirs'),
484 | show_hidden=partial(self._attr_callback, 'show_hidden'),
485 | multiselect=partial(self._attr_callback, 'multiselect'),
486 | dirselect=partial(self._attr_callback, 'dirselect'),
487 | rootpath=partial(self._attr_callback, 'rootpath'))
488 | self.ids.list_view.bind(selection=partial(self._attr_callback, 'selection'),
489 | path=partial(self._attr_callback, 'path'),
490 | filters=partial(self._attr_callback, 'filters'),
491 | filter_dirs=partial(self._attr_callback, 'filter_dirs'),
492 | show_hidden=partial(self._attr_callback, 'show_hidden'),
493 | multiselect=partial(self._attr_callback, 'multiselect'),
494 | dirselect=partial(self._attr_callback, 'dirselect'),
495 | rootpath=partial(self._attr_callback, 'rootpath'))
496 |
497 | def _shorten_filenames(self, filenames):
498 | if not len(filenames):
499 | return ''
500 | elif len(filenames) == 1:
501 | return filenames[0]
502 | elif len(filenames) == 2:
503 | return filenames[0] + ', ' + filenames[1]
504 | else:
505 | return filenames[0] + ', _..._, ' + filenames[-1]
506 |
507 | def _attr_callback(self, attr, obj, value):
508 | setattr(self, attr, getattr(obj, attr))
509 |
510 | if __name__ == '__main__':
511 | import os
512 | from kivy.app import App
513 |
514 | class TestApp(App):
515 |
516 | def build(self):
517 | user_path = os.path.join(get_home_directory(), 'Documents')
518 | browser = FileBrowser(select_string='Select',
519 | favorites=[(user_path, 'Documents')])
520 | browser.bind(on_success=self._fbrowser_success,
521 | on_canceled=self._fbrowser_canceled,
522 | on_submit=self._fbrowser_submit)
523 | return browser
524 |
525 | def _fbrowser_canceled(self, instance):
526 | print('cancelled, Close self.')
527 |
528 | def _fbrowser_success(self, instance):
529 | print(instance.selection)
530 |
531 | def _fbrowser_submit(self, instance):
532 | print(instance.selection)
533 |
534 | TestApp().run()
535 |
--------------------------------------------------------------------------------