Source code for spike.Interactive.ipyfilechooser

# FileChooser code is from
# https://github.com/crahan/ipyfilechooser

from __future__ import print_function, division
from ipywidgets import Dropdown, Text, Select, Button, HTML
from ipywidgets import Layout, GridBox, HBox, VBox
#from .utils import update_path, get_subpaths, get_dir_contents
import os

__version__ = '0.1.2'

[docs]class FileChooser(VBox): _LBL_TEMPLATE = '<span style="margin-left:10px; color:{1};">{0}</span>' _LBL_NOFILE = 'No file selected' def __init__( self, path=os.getcwd(), filename='', show_hidden=False, **kwargs): self._default_path = path.rstrip(os.path.sep) self._default_filename = filename self._selected_path = '' self._selected_filename = '' self._show_hidden = show_hidden # Widgets self._pathlist = Dropdown( description="", layout=Layout( width='auto', grid_area='pathlist' ) ) self._filename = Text( placeholder='output filename', layout=Layout( width='auto', grid_area='filename' ) ) self._dircontent = Select( rows=8, layout=Layout( width='auto', grid_area='dircontent' ) ) self._cancel = Button( description='Cancel', button_style='warning', # 'success', 'info', 'warning', 'danger' or '' layout=Layout( width='auto', display='none' ) ) self._select = Button( description='Select', button_style='success', # 'success', 'info', 'warning', 'danger' or '' layout=Layout(width='auto') ) # Widget observe handlers self._pathlist.observe( self._on_pathlist_select, names='value' ) self._dircontent.observe( self._on_dircontent_select, names='value' ) self._filename.observe( self._on_filename_change, names='value' ) self._select.on_click(self._on_select_click) self._cancel.on_click(self._on_cancel_click) # Selected file label self._label = HTML( value=self._LBL_TEMPLATE.format( self._LBL_NOFILE, 'black' ), placeholder='', description='' ) # Layout self._gb = GridBox( children=[ self._pathlist, self._filename, self._dircontent ], layout=Layout( display='none', width='500px', grid_gap='0px 0px', grid_template_rows='auto auto', grid_template_columns='60% 40%', grid_template_areas=''' 'pathlist filename' 'dircontent dircontent' ''' ) ) buttonbar = HBox( children=[ self._select, self._cancel, self._label ], layout=Layout(width='auto') ) # Call setter to set initial form values self._set_form_values( self._default_path, self._default_filename ) # Call VBox super class __init__ super().__init__( children=[ self._gb, buttonbar, ], layout=Layout(width='auto'), **kwargs ) def _set_form_values(self, path, filename): '''Set the form values''' # Disable triggers to prevent selecting an entry in the Select # box from automatically triggering a new event. self._pathlist.unobserve( self._on_pathlist_select, names='value' ) self._dircontent.unobserve( self._on_dircontent_select, names='value' ) self._filename.unobserve( self._on_filename_change, names='value' ) # Set form values self._pathlist.options = get_subpaths(path) self._pathlist.value = path self._filename.value = filename self._dircontent.options = get_dir_contents( path, hidden=self._show_hidden ) # If the value in the filename Text box equals a value in the # Select box and the entry is a file then select the entry. if ((filename in self._dircontent.options) and os.path.isfile(os.path.join(path, filename))): self._dircontent.value = filename else: self._dircontent.value = None # Reenable triggers again self._pathlist.observe( self._on_pathlist_select, names='value' ) self._dircontent.observe( self._on_dircontent_select, names='value' ) self._filename.observe( self._on_filename_change, names='value' ) # Set the state of the select Button if self._gb.layout.display is None: selected = os.path.join( self._selected_path, self._selected_filename ) # filename value is empty or equals the selected value if (filename == '') or (os.path.join(path, filename) == selected): self._select.disabled = True else: self._select.disabled = False def _on_pathlist_select(self, change): '''Handler for when a new path is selected''' self._set_form_values( change['new'], self._filename.value ) def _on_dircontent_select(self, change): '''Handler for when a folder entry is selected''' new_path = update_path( self._pathlist.value, change['new'] ) # Check if folder or file if os.path.isdir(new_path): path = new_path filename = self._filename.value elif os.path.isfile(new_path): path = self._pathlist.value filename = change['new'] self._set_form_values( path, filename ) def _on_filename_change(self, change): '''Handler for when the filename field changes''' self._set_form_values( self._pathlist.value, change['new'] ) def _on_select_click(self, b): '''Handler for when the select button is clicked''' if self._gb.layout.display is 'none': self._gb.layout.display = None self._cancel.layout.display = None # Show the form with the correct path and filename if self._selected_path and self._selected_filename: path = self._selected_path filename = self._selected_filename else: path = self._default_path filename = self._default_filename self._set_form_values(path, filename) else: self._gb.layout.display = 'none' self._cancel.layout.display = 'none' self._select.description = 'Change' self._selected_path = self._pathlist.value self._selected_filename = self._filename.value # self._default_path = self._selected_path # self._default_filename = self._selected_filename selected = os.path.join( self._selected_path, self._selected_filename ) if os.path.isfile(selected): self._label.value = self._LBL_TEMPLATE.format( selected, 'orange' ) else: self._label.value = self._LBL_TEMPLATE.format( selected, 'green' ) def _on_cancel_click(self, b): '''Handler for when the cancel button is clicked''' self._gb.layout.display = 'none' self._cancel.layout.display = 'none' self._select.disabled = False
[docs] def reset(self, path=None, filename=None): '''Reset the form to the default path and filename''' self._selected_path = '' self._selected_filename = '' self._label.value = self._LBL_TEMPLATE.format( self._LBL_NOFILE, 'black' ) if path is not None: self._default_path = path.rstrip(os.path.sep) if filename is not None: self._default_filename = filename self._set_form_values( self._default_path, self._default_filename )
[docs] def refresh(self): '''Re-render the form''' self._set_form_values( self._pathlist.value, self._filename.value )
@property def show_hidden(self): '''Get current number of rows''' return self._show_hidden @show_hidden.setter def show_hidden(self, hidden): '''Set number of rows''' self._show_hidden = hidden self.refresh() @property def rows(self): '''Get current number of rows''' return self._dircontent.rows @rows.setter def rows(self, rows): '''Set number of rows''' self._dircontent.rows = rows @property def default(self): '''Get the default value''' return os.path.join( self._default_path, self._default_filename ) @property def default_path(self): '''Get the default_path value''' return self._default_path @default_path.setter def default_path(self, path): '''Set the default_path''' self._default_path = path.rstrip(os.path.sep) self._default = os.path.join( self._default_path, self._filename.value ) self._set_form_values( self._default_path, self._filename.value ) @property def default_filename(self): '''Get the default_filename value''' return self._default_filename @default_filename.setter def default_filename(self, filename): '''Set the default_filename''' self._default_filename = filename self._default = os.path.join( self._pathlist.value, self._default_filename ) self._set_form_values( self._pathlist.value, self._default_filename ) @property def selected(self): '''Get selected value''' return os.path.join( self._selected_path, self._selected_filename ) @property def selected_path(self): '''Get selected_path value''' return self._selected_path @property def selected_filename(self): '''Get the selected_filename''' return self._selected_filename @property def nmrname(self): # added by MAD return os.path.join(os.path.basename(os.path.dirname(self._selected_path)), os.path.basename(self._selected_path)) def __repr__(self): str_ = ("FileChooser(" "path='{0}', " "filename='{1}', " "show_hidden='{2}')").format( self._default_path, self._default_filename, self._show_hidden ) return str_
[docs]def get_subpaths(path): '''Walk a path and return a list of subpaths''' if os.path.isfile(path): path = os.path.dirname(path) paths = [path] path, tail = os.path.split(path) while tail: paths.append(path) path, tail = os.path.split(path) return paths
[docs]def update_path(path, item): '''Update path with new item''' if item == '..': path = os.path.dirname(path) else: path = os.path.join(path, item) return path
[docs]def has_parent(path): '''Check if a path has a parent folder''' return os.path.basename(path) != ''
[docs]def get_dir_contents(path, hidden=False): '''Get directory contents''' files = list() dirs = list() if os.path.isdir(path): for item in os.listdir(path): append = True if item.startswith('.') and not hidden: append = False full_item = os.path.join(path, item) if os.path.isdir(full_item) and append: dirs.append(item) elif append: files.append(item) if has_parent(path): dirs.insert(0, '..') return sorted(dirs) + sorted(files)