Re: File Search & Select PGM

new topic     » goto parent     » topic index » view thread      » older message » newer message

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

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu