Prompting for File Names


Many applications need to prompt the user for file names, and ithe FileBox object lets us do this.  But in its raw form the procedure is a little tedious and can be eased by encapsulating some of the humdrum into a couple of defined functions.

First port of call is a function to embellish filename extensions with descriptions, so that we can provide an appropriate set of filter values...

     ∇ z←FileFilters w;⎕IO;⎕ML;filters;ext
[1]       ⍝ Filebox filter set for given filename
[2]    ⎕IO ⎕ML←0 3
[3]    filters←''
[4]    filters,←⊂'*.csv' 'Comma-separated files (*.csv)'
[5]    filters,←⊂'*.dcf' 'Dyalog component files (*.dcf)'
[6]    filters,←⊂'*.dws' 'Dyalog workspaces (*.dws)'
[7]    filters,←⊂'*.htm' 'HTML files (*.htm)'
[8]    filters,←⊂'*.html' 'HTML files (*.html)'
[9]    filters,←⊂'*.htm*' 'HTML files (*.htm[l])'
[10]   filters,←⊂'*.jpg' 'JPEG files (*.jpg)'
[11]   filters,←⊂'*.rtf' 'RichText files (*.rtf)'
[12]   filters,←⊂'*.txt' 'Text files (*.txt)'
[13]   ext←{'*.',∊¯1↑(~⍵∊'.')⊂⍵}w
[14]   :If (⊂ext)∊↑¨filters
[15]       z←(,((↑¨filters)∊⊂ext)/filters),⊂'*.*' 'All Files (*.*)'
[16]   :Else
[17]       z←''
[18]   :EndIf
     ∇

  displayr  FileFilters '*.txt'
┌2─────────────────────────────────────────────────────────────┐
│ ┌2─────────────────────────────┐ ┌2────────────────────────┐ │
│ │ ┌5────┐ ┌18────────────────┐ │ │ ┌3──┐ ┌15─────────────┐ │ │
│ │ │*.txt│ │Text files (*.txt)│ │ │ │*.*│ │All Files (*.*)│ │ │
│ │ └─────┘ └──────────────────┘ │ │ └───┘ └───────────────┘ │ │
│ └2─────────────────────────────┘ └2────────────────────────┘ │
└3─────────────────────────────────────────────────────────────┘

   displayr  ∪⊃,/FileFilters¨ '*.txt' '*.rtf'
┌3──────────────────────────────────────────────────────────────────────────────────────────────────┐
│ ┌2─────────────────────────────┐ ┌2────────────────────────┐ ┌2─────────────────────────────────┐ │
│ │ ┌5────┐ ┌18────────────────┐ │ │ ┌3──┐ ┌15─────────────┐ │ │ ┌5────┐ ┌22────────────────────┐ │ │
│ │ │*.txt│ │Text files (*.txt)│ │ │ │*.*│ │All Files (*.*)│ │ │ │*.rtf│ │RichText files (*.rtf)│ │ │
│ │ └─────┘ └──────────────────┘ │ │ └───┘ └───────────────┘ │ │ └─────┘ └──────────────────────┘ │ │
│ └2─────────────────────────────┘ └2────────────────────────┘ └2─────────────────────────────────┘ │
└3──────────────────────────────────────────────────────────────────────────────────────────────────┘

As always, there are compromises here - <FileFilters> was written with a primary requirement to select only a single file type.  If you find that allowing selection from a range of type is common you might generalise the function to accept multiple types in its argument (and rid yourself of any hokeypokey needed to rearrange the result).  Notice also that by default "all files" is added.  Extending the list of types and descriptions is obviously a trivil matter.

We can then wrap everything else we need into a single function...

   ∇ z←FileBox w;⎕IO;fb;msg;⎕ML;form;prompt;folder;style;mode;filter
[1]       ⍝ File selector
[2]    ⎕IO ⎕ML←0 3
[3]    form prompt folder style mode filter←6↑w,⊂(⊂'*.*' 'All Files (*.*)')
[4]    fb←form.⎕NEW'FileBox'(('Caption'prompt)('Directory'folder)('Style'style)('FileMode'mode)('Filters'filter))
[5]    fb.(onFileBoxOK onFileBoxCancel)←1
[6]    msg←fb.Wait
[7]    :If 'FileBoxOK'≡1⊃msg
[8]        :If style≡'Single'
[9]            z←⊃,/fb.(Directory File)
[10]       :Else
[11]           z←(⊂fb.Directory),¨fb.File
[12]       :EndIf
[13]   :Else
[14]       z←''
[15]   :EndIf
[16]   ⎕EX'fb'
     ∇

   FileBox # 'Select File' 'c:\dick\temp' 'Single' 'Read' (FileFilters '*.txt')
C:\Dick\Temp\aaa.txt

Page created 28 May 2009.
Copyright © Dogon Research 2009.