Re: File Search & Select PGM
Mr. Fred Cole proposed his version of a file select function,
Here is my own version.
Specifications:
-> full navigation
this version doesn't use mouse but have full navigation with cursor
key,
PageUp, PageDown, Home and End keys.
-> ESC key can be used to cancel the operation, in which case and empty
sequence
is returned to caller.
-> The file list adapt itself to current screen metrics.
-> Directory names are displayed in black, file names in white and the
selected
one is on green background.
-> screen state saved and restored
How to use it:
include filelist.e in your program
srceen is organised in 3 regions:
first line is filter and number of files in current list.
second line is selected file info (name, size, date, etc)
rest of screen is the list
The function to call is ChooseFile(filter)
the parameter filter is a path or wildcard filter.
you can change the filter or drive while viewing the list with the f
command.
example:
include FileList.e
sequence FileName
FileName = ChooseFile("c:\\euphoria\*.ex")
puts(1,name)
Consider it public domain.
I would appreciated report on bugs and to receive your improve version
of it.
************************************************************************
-- FileList: display le list of file for user to pick one and return the
-- selected file.
-- Creation date: august 26th, 1996
-- By: Jacques Deschenes, Baie-comeau, P.Q. Canada
-- e-mail: desja at quebectel.com
--
-- caller pass a wildcard path to use as a filter
without warning
without type_check
-- with trace
include graphics.e
include wildcard.e
include machine.e
include get.e
include image.e
include file.e
-- Keys constant
constant ESC = 27, ENTER = 13, HOME = 327, END = 335, UP = 328, DOWN =
336,
LEFT =331, RIGHT =333, PG_UP = 329, PG_DOWN = 337
sequence list,path,filter
list = {}
path = current_dir() & '\\' -- default path
filter = "*.*" -- default filter
-- display metrics
integer ListLines, -- number of lines to display list
ListCol, -- number of columns to display the list
PerLine -- number of file name displayed per line
constant NAME_FIELD= 14 -- width of name field
-- math functions
function Min(integer a, integer b)
if a < b then
return a
else
return b
end if
end function -- Min
function Max(integer a, integer b)
if a > b then
return a
else
return b
end if
end function -- Max
function ToUpper(integer c)
-- convert c to upper case
if c >= 'a' and c <= 'z' then
return c - 'a' + 'A'
else
return c
end if
end function -- ToUpper()
function f_split(sequence path)
-- split path to drive, directory, name and extension
-- return sequence {drive,dir,name,ext}
sequence slice,drive,dir,name,ext
atom c
slice = {}
drive = {} dir = {} name = {} ext = {}
for i =1 to length(path) by 1 do
c = ToUpper(path[i])
slice = slice & c
if c = ':' then
drive = slice
slice = {}
elsif c = '\\' then
dir = dir & slice
slice = {}
elsif c = '.' then
name = slice[1..length(slice)-1]
slice = {}
end if
end for
if length(name) = 0 then
name = slice
else
ext = slice
end if
if length(ext)=0 and not match("*",name) and not match("?",name)
then
dir = dir & name
name = "*"
ext = "*"
end if
if length(dir) then
if dir[length(dir)] != '\\' then
dir = dir & '\\'
end if
end if
return {drive,dir,name,ext}
end function -- f_split()
function ParentDir(sequence path)
-- return the parent directory
sequence parent integer i
if path[length(path)] = '\\' then
path = path[1..length(path)-1]
end if
i = length(path)
while i > 0 do
if path[i] = '\\' or path[i] = ':' then
exit
end if
i = i-1
end while
if i = 0 then
return {}
end if
parent = path[1..i]
if parent[length(parent)] != '\\' then
parent = parent & '\\'
end if
return parent
end function -- ParentDir()
function CreateList(sequence filter)
-- create the list of files to display.
object FileList
FileList = dir(filter)
if atom(FileList) then
return {}
end if
if length(FileList[1][D_NAME]) = 1 and
match(".",FileList[1][D_NAME]) then
FileList = FileList[2..length(FileList)]
end if
return FileList
end function -- CreateList
function Left(sequence Str, integer width)
-- left justify a string in a specified field width.
Str = Str & repeat(32,width)
return Str[1..width]
end function -- Left()
procedure WriteFileInfo(integer index)
-- write file info line on second line of screen
position(2,1)
bk_color(BLUE)
text_color(WHITE)
if index=0 then
puts(1,"No files\n")
else
printf(1,"%14s %5s %8d %4d/%2.2d/%2.2d
%2.2d:%2.2d:%2.2d\n",
list[index])
end if
end procedure --WriteFileInfo()
sequence padding
padding = repeat(32,NAME_FIELD)
procedure WriteFileName(integer i)
-- write file name to screen
-- directory are displayed in black, files in white
sequence name
if match("d",list[i][D_ATTRIBUTES]) then
text_color(BLACK)
else
text_color(WHITE)
end if
name = list[i][D_NAME] & padding
puts(1,name[1..NAME_FIELD])
end procedure -- WriteFileName()
integer PrevFirst, PrevIndex
PrevFirst = 0 PrevIndex = 0
procedure DisplayList(integer index)
-- Display the list HiLight the selected one
sequence pos
integer first,last
if index = PrevIndex then
return
end if
first = 1
if index > ListLines*PerLine then
first = floor(index/PerLine-ListLines+1)*PerLine+1
end if
if first = PrevFirst then
position(3+floor((PrevIndex-first)/PerLine),
NAME_FIELD*remainder(PrevIndex-first,PerLine)+1)
bk_color(BROWN)
WriteFileName(PrevIndex)
position(3+floor((index-first)/PerLine),
NAME_FIELD*remainder(index-first,PerLine)+1)
bk_color(GREEN)
WriteFileName(index)
WriteFileInfo(index)
PrevIndex = index
return
end if
bk_color(BROWN)
clear_screen()
text_color(WHITE)
bk_color(BLUE)
puts(1,repeat(32,2*ListCol))
position(1,1)
printf(1,"%s files: %d\n",{Left(path&filter,60),length(list)})
WriteFileInfo(index)
last = Min(first+ListLines*PerLine-1,length(list))
bk_color(BROWN)
for i = first to last by 1 do
WriteFileName(i)
if remainder(i,PerLine)=0 then
pos = get_position()
if pos[1] < ListLines + 2 then
puts(1,"\n")
end if
end if
end for
position(3+floor((index-first)/PerLine),
NAME_FIELD*remainder(index-first,PerLine)+1)
bk_color(GREEN)
WriteFileName(index)
PrevFirst = first
PrevIndex = index
end procedure --DisplayList
function NewSpec()
sequence PathSplit, new_path, new_filter
object input_line, new_list
-- trace(1)
new_list = {}
position(2,1)
text_color(WHITE)
bk_color(BLUE)
puts(1,repeat(32,80))
cursor(#0607)
position(2,1)
puts(1,"NEW FILTER: ")
input_line = gets(0)
cursor(NO_CURSOR)
if atom(input_line) then
return list
else
new_filter = input_line[1..length(input_line)-1]
if length(new_filter) = 0 then
return list
end if
end if
PathSplit=f_split(new_filter)
if length(PathSplit[3]) then
new_filter = PathSplit[3]&'.'&PathSplit[4]
else
new_filter = filter
end if
if length(PathSplit[1]) then
new_path = PathSplit[1]&PathSplit[2]
elsif length(PathSplit[2]) then
new_path = PathSplit[2]
else
new_path = path
end if
if new_path[length(new_path)] != '\\' then
new_path = new_path & '\\'
end if
new_list=dir(new_path&new_filter)
if atom(new_list) then
return list
end if
filter = new_filter
path = new_path
if length(new_list[1][D_NAME])=1 and match(".",new_list[1][D_NAME])
then
return new_list[2..length(new_list)]
else
return new_list
end if
end function -- NewSpec()
function DoSelect()
-- navigate the list and return the index of the selected one
integer index,car
index = 1
while 1 do
DisplayList(index)
car = wait_key()
if car = ESC then
return 0
elsif car = LEFT then
if index > 1 then
index = index - 1
end if
elsif car = RIGHT then
if index < length(list) then
index = index + 1
end if
elsif car = UP then
if index > PerLine then
index = index - PerLine
end if
elsif car = DOWN then
if index <= length(list)-PerLine then
index = index + PerLine
end if
elsif car = HOME then
if index > 1 then
index = 1
end if
elsif car = END then
if index < length(list) then
index = length(list)
end if
elsif car = PG_DOWN then
if PrevFirst + PerLine*ListLines -1 < length(list) then
index = Min(index+ListLines*PerLine,length(list))
end if
elsif car = PG_UP then
if index > ListLines*PerLine then
index = index - ListLines*PerLine
end if
elsif car = 'F' or car = 'f' then
list = NewSpec()
index = 1
PrevIndex = 0 PrevFirst = 0
elsif car = ENTER then
if match("d",list[index][D_ATTRIBUTES])=0 then
return index
else
if match("..",list[index][D_NAME])=1 then
path = ParentDir(path)
else
path = path&list[index][D_NAME]&'\\'
end if
list = CreateList(path&filter)
index = 1
PrevIndex = 0 PrevFirst = 0
end if
end if
end while
end function -- DoSelect
global function ChooseFile(sequence APath)
-- display a list of file
-- return the selected file or {} if operation canceled
sequence saved, FileSpec, vc, CurPos
integer pick,OldColor,OldBack
CurPos = get_position()
OldColor = TextColor OldBack= BkColor
FileSpec=f_split(APath)
if length(FileSpec[1]) then
path = FileSpec[1] & FileSpec[2]
end if
if length(FileSpec[3]) then
filter = FileSpec[3]&"."&FileSpec[4]
end if
vc = video_config()
saved=save_text_image({1,1},{vc[VC_LINES],vc[VC_COLUMNS]}) -- save all
screen
cursor(NO_CURSOR)
ListLines = vc[VC_LINES] - 2
ListCol = vc[VC_COLUMNS]
PerLine = floor(ListCol/NAME_FIELD)
list = CreateList(filter)
pick = DoSelect()
display_text_image({1,1},saved)
text_color(OldColor) bk_color(OldBack)
cursor(#0607)
FileSpec = f_split(filter)
position(CurPos[1],CurPos[2])
if pick then
return FileSpec[1] & FileSpec[2] & list[pick][D_NAME]
else
return {}
end if
end function -- ChooseFile
|
Not Categorized, Please Help
|
|