# Adapted from https://github.com/kivy-garden/filebrowser """ FileBrowser =========== The :class:`FileBrowser` widget is an advanced file browser. You use it similarly to FileChooser usage. It provides a shortcut bar with links to special and system directories. When touching next to a shortcut in the links bar, it'll expand and show all the directories within that directory. It also facilitates specifying custom paths to be added to the shortcuts list. It provides a icon and list view to choose files from. And it also accepts filter and filename inputs. To create a FileBrowser which prints the currently selected file as well as the current text in the filename field when 'Select' is pressed, with a shortcut to the Documents directory added to the favorites bar:: import os from kivy.app import App class TestApp(App): def build(self): user_path = os.path.join(get_home_directory(), 'Documents') browser = FileBrowser(select_string='Select', favorites=[(user_path, 'Documents')]) browser.bind(on_success=self._fbrowser_success, on_submit=self._fbrowser_submit) return browser def _fbrowser_success(self, instance): print(instance.selection) def _fbrowser_submit(self, instance): print(instance.selection) TestApp().run() :Events: `on_success`: Fired when the `Select` buttons `on_release` event is called. `on_submit`: Fired when a file has been selected with a double-tap. .. image:: _static/filebrowser.png :align: right """ import string import warnings from functools import partial from os import walk from os.path import dirname, expanduser, getmtime, isdir, join, sep from kivy import Config from kivy.clock import Clock from kivy.lang import Builder from kivy.properties import BooleanProperty, ListProperty, ObjectProperty, OptionProperty, StringProperty from kivy.uix.boxlayout import BoxLayout from kivy.uix.filechooser import FileChooserListLayout, FileChooserListView from kivy.uix.treeview import TreeView, TreeViewLabel from kivy.utils import platform from katrain.gui.style import DEFAULT_FONT if platform == "win": from ctypes import windll, create_unicode_buffer def last_modified_first(files, filesystem): return sorted(f for f in files if filesystem.is_dir(f)) + sorted( [f for f in files if not filesystem.is_dir(f)], key=lambda f: -getmtime(f) ) def get_home_directory(): if platform == "win": user_path = expanduser("~") if not isdir(join(user_path, "Desktop")): user_path = dirname(user_path) else: user_path = expanduser("~") return user_path def get_drives(): drives = [] if platform == "win": bitmask = windll.kernel32.GetLogicalDrives() GetVolumeInformationW = windll.kernel32.GetVolumeInformationW for letter in string.ascii_uppercase: if bitmask & 1: name = create_unicode_buffer(64) # get name of the drive drive = letter + u":" res = GetVolumeInformationW(drive + sep, name, 64, None, None, None, None, 0) if isdir(drive): drives.append((drive, name.value)) bitmask >>= 1 elif platform == "linux": drives.append((sep, sep)) drives.append((expanduser(u"~"), "~/")) places = (sep + u"mnt", sep + u"media") for place in places: if isdir(place): for directory in next(walk(place))[1]: drives.append((place + sep + directory, directory)) elif platform == "macosx" or platform == "ios": drives.append((expanduser(u"~"), "~/")) vol = sep + u"Volume" if isdir(vol): for drive in next(walk(vol))[1]: drives.append((vol + sep + drive, drive)) return drives class I18NFileChooserListView(FileChooserListView): font_name = StringProperty(DEFAULT_FONT) show_hidden = BooleanProperty(True) # avoid errors class I18NFileChooserListLayout(FileChooserListLayout): _ENTRY_TEMPLATE = "I18NFileListEntry" log_level = Config.get("kivy", "log_level") Config.set("kivy", "log_level", "error") Builder.load_string( """ [I18NFileListEntry@FloatLayout+TreeViewNode]: locked: False entries: [] path: ctx.path is_selected: self.path in ctx.controller().selection orientation: 'horizontal' size_hint_y: None height: 24 # Don't allow expansion of the ../ node is_leaf: not ctx.isdir or ctx.name.endswith('..' + ctx.sep) or self.locked on_touch_down: self.collide_point(*args[1].pos) and ctx.controller().entry_touched(self, args[1]) on_touch_up: self.collide_point(*args[1].pos) and ctx.controller().entry_released(self, args[1]) BoxLayout: pos: root.pos size_hint_x: None width: root.width - 10 Label: id: filename text_size: self.width, None halign: 'left' shorten: True text: ctx.name font_name: ctx.controller().font_name Label: text_size: self.width, None size_hint_x: None halign: 'right' text: '{}'.format(ctx.get_nice_size()) : layout: layout I18NFileChooserListLayout: id: layout controller: root """ ) Config.set("kivy", "log_level", log_level) Builder.load_string( """ #:import metrics kivy.metrics #:import abspath os.path.abspath #:import i18n katrain.core.lang.i18n