# # FileDialog class # class FileDialog : _Dialog( init_dir, # Initial directory name init_file, # Initial file name res, # Resulting file path dir, # TextField directory file, # TextField filename dlist, # TextList of directories flist, # TextList of files okay, # cancel, # extra_attribs # Custom attributes ) # # Extra attributes set by caller. # method set_extra_attribs(l) return extra_attribs := l end # # Get the directory part of the result # method get_directory() return directory_name(\res) end # # Get the result, (will fail if cancel was pressed). # method get_result() return \res end # # Set the initial directory. # method set_directory(s) return init_dir := s end # # Set the initial file # method set_file(s) return init_file := s end # # Set the initial file/directory from a whole path. # method set_path(s) init_dir := directory_name(s) init_file := file_name(s) return s end # # Set the result # method set_result() res := get_std_dir() || file.get_contents() end # # Get the directory TextField contents standardized with a # trailing / # method get_std_dir() s := dir.get_contents() if (s[-1] ~== "/") then s ||:= "/" return s end method dialog_event(ev) case ev.get_component() of { cancel : if ev.get_code() > 0 then dispose() okay : if ev.get_code() > 0 then { set_result() dispose() } file : # # If return pressed in file TextField, same as okay # if ev.get_code() = 0 then { set_result() dispose() } dlist : { if *dlist.get_selections() = 0 then return # # Clicked in the directory list; # get the item clicked on. # value := trim(dlist.get_contents()[ dlist.get_selections()[1]], , 0) s := get_std_dir() # # Go to parent directory (unless at root directory) # if value == "../" then { if s ~== "/" then { s[-1] := "" while s[-1] ~== "/" do s[-1] := "" } dir.set_contents(s) } else dir.set_contents(s ||:= value) # # Update directory and file lists. # l1 := [] l2 := [] get_directory_list(s, l1, l2) dlist.set_contents(l1) flist.set_contents(l2) file.set_contents("") } flist : # # Clicked in file list; set TextField # file.set_contents( flist.get_contents()[flist.get_selections()[1]]) dir : { if ev.get_code() = 0 then { # # Return pressed in directory TextField; update # lists. # l1 := [] l2 := [] dir.set_contents(s := get_std_dir()) get_directory_list(s, l1, l2) dlist.set_contents(l1) flist.set_contents(l2) file.set_contents("") } } } end method show() # # Defaults if none set by caller. # if /init_dir | (init_dir == "") then init_dir := chdir() /init_dir := "/" /init_file := "" if (init_dir[-1] ~== "/") then init_dir ||:= "/" attrib(["size=500,450", "resize=on"] ||| extra_attribs ) l := Label("label=Directory", "pos=50,50", "align=l,c") add(l) dir := TextField("pos=150,50", "size=100%-200", "align=l,c") dir.set_contents(init_dir) add(dir) l := Label("label=File", "pos=50,100", "align=l,c") add(l) file := TextField("pos=150,100", "size=100%-200", "align=l,c") file.set_contents(init_file) add(file) l1 := [] l2 := [] get_directory_list(init_dir, l1, l2) dlist := TextList("pos=50,150", "size=50%-75,100%-250") dlist.set_select_one() dlist.set_contents(l1) add(dlist) flist := TextList("pos=50%+25,150","size=50%-75,100%-250") flist.set_select_one() flist.set_contents(l2) add(flist) okay := TextButton("label=Okay", "pos=33%,100%-50", "align=c,c") add(okay) cancel := TextButton("label=Cancel", "pos=66%,100%-50", "align=c,c") add(cancel) self._Dialog.show() end method init_dialog() set_focus(file) end initially self._Dialog.initially() extra_attribs := [] show_modal() end # # Read a directory. # procedure get_directory_list(s, dir_list, file_list) p := open("ls -alL 2>/dev/null " || s, "pr") | fatal_error("couldn't run ls") read(p) while s := read(p) do { s ? { if ="d" then { move(54) put(dir_list, tab(0) || "/") } else { move(55) put(file_list, tab(0)) } } } return end # # Return the directory name of the file name s, including the # trailing / # procedure directory_name(s) local i every i := find("/", s) return s[1:\i + 1] | "" end # # Return the file name of s # procedure file_name(s) local i every i := find("/", s) return s[\i + 1:0] | s end # procedure main() FileDialog() end