├── 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 | py4sci 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 | --------------------------------------------------------------------------------