Viewing contents of file '../idllib/user_contrib/creaso/ccw_pickf.pro'
; Copyright(c) 1992, CreaSo Creative Software Systems GmbH. All rights reserved.
;	Unauthorized reproduction prohibited.
;+
; NAME:
;      	CCW_PICKF 
;
; PURPOSE:
;	This function allows the user to interactively pick a file.  A file
;	selection tool with a graphical user interface is created.  Files
; 	can be selected from the current directory or other directories.
;
; EXTERN LIBRARIES:
;       creasolib.tlb
;
; CATEGORY:
;	Widgets.
;
; CALLING SEQUENCE:
;	Result = ccw_pickf()
;
; KEYWORD PARAMETERS:
;	GROUP:	The widget ID of the widget that calls ccw_pickf. When this
;		ID is specified, a death of the caller results in the death of
;		the ccw_pickf widget application.
;
;	READ:	Set this keyword to make the title of the ccw_pickf window 
;		"Select File to Read".
;
;	WRITE:	Set this keyword to make the title of the ccw_pickf window 
;		"Select File to Write".
;
;	PATH:	The initial path to select files from.  If this keyword is 
;		not set, the current directory is used. (will be changed)
;
;	FILTER:	A string array of file extensions to be allowed.  This
;		keyword is used to ensure that the user can only select files 
;		of a certain type. (will be changed)
;
;               Passing a string (not a string array!) that contains wildcard
;               characters (*), this string serves as a filename filter.
;
;       LANGARR: Language array. Follwing order of used words has to specified
;                langarr (0)  = filter
;                langarr (1)  = up one directory level
;                langarr (2)  = subdirectories
;                langarr (3)  = files
;                langarr (4)  = selection
;                langarr (5)  = ok
;                langarr (6)  = cancel
;                langarr (7)  = message
;                langarr (8) = directory >
;                langarr (9) = < does not exist !
;                langarr (10) = please select a file
;                langarr (11) = for reading
;                langarr (12) = for writing
;                langarr (13) = File >
;
;                If it is not specified, the standard english vocabulary is
;                used
;       GERMAN: If the language array was not specified, then standard german
;               vocabulary was used.
;
;       CREATE: If this keyword is set, the selected filename will be tested on
;               existing filepath only.
;               Example: If you want to specify an filename for writing, the
;                        filename must not exist. Then the ccw_pickf routine
;                        checks only the filepath.
;
;       XOFFSET: X offset of ccw_pickf widget.
;
;       YOFFSET: Y offset of ccw_pickf widget.
;
;	TITLE:	A scalar string to be used for the window title.
;
; OUTPUTS:
;	CCW_PICKF returns a string that contains the name of the file selected.
;	If no file is selected, CCW_PICKF returns a null string.
;
; COMMON BLOCKS:
;	PICKER:	COMMON block that maintains state for the widget.
;
; SIDE EFFECTS:
;	This function initiates the XMANAGER if it is not already running.
;
; RESTRICTIONS:
;       Only on VAX/VMS tested.
;	This routine is known to work on Suns (OPEN LOOK), MIPS, RS/6000, 
;	VAX/VMS and SGI machines.
;
;	Only one instance of the CCW_PICKF widget can be running at one time.
;
;	CCW_PICKF does not recognize symbolic links to other files in UNIX.
;
; PROCEDURE:
;	Create and register the widget and then exit, returning the filename
;	that was picked.
;
; EXAMPLE:
;	Create a CCW_PICKF widget that lets users select only files with 
;	the extensions 'pro' and 'dat'.  Use the 'Select File to Read' title 
;	and store the name of the selected file in the variable F.  Enter:
;
;		F = CCW_PICKF (/READ, FILTER = ['pro', 'dat'])
;
;	Create a CCW_PICKF widget that lets users select only files beginning
;       with with 'x' and the extension 'pro'. Use the 'Select File to Write'
;	title and store the name of the selected file in the variable F.  Enter:
;
;		F = CCW_PICKF (/WRITE, FILTER = 'x*.pro')
;
; MODIFICATION HISTORY:
; 	Written by:	Steve Richards,	April, 1991
;	July, 1991	Added a FILTER keyword to allow users
;			to select files with a given extension or 
;			extensions.
;	August, 1991	Fixed bugs caused by differences between
;			spawned ls commands on different machines.
;	3/92  - ACY	Corrected initialization of dirsave, change spawn
;			command to "ls -lL" and added case for links
;			add NOCONFIRM keyword for auto exiting on selection
;       6/92  - HJB	Fixed various bugs for VMS and added functionality to
;                       change disks on VMS (Filter) including interpreting
;                       filters like "*.d*" for VMS.
;       8/92  - HJB	Added X and Y offset keywords.
;       10/92 - AH      Changed to Compound Widget. (redesign)
;-
;
;
;
; This procedure set the filter with the widget_control routine
;------------------------------------------------------------------------------
pro xpf_set_value, id, value

   ;a: Get widget structure

   bas = widget_info(id, /child)  
   widget_control, bas, get_uvalue=xpf

   ;a: Set new filter value

   filescan, value, path=p, name=n, type=t, ver=v
   xpf.thefile = n+t+v

   error=0
   if (xpf.thefile ne '' and xpf.create eq 0) then begin
      if ((findfile(value))(0) eq '') then begin
         xpfsendmsg, xpf, xpf.lang(13)+value+xpf.lang(9)
         error = -1
      endif
   endif else begin
      cd, current=cur
      changedir, p, error=error
      cd, cur
      if (error eq -1) then begin
         xpfsendmsg, xpf, xpf.lang(8)+p+xpf.lang(9)
      endif
   endelse

   ;a: Get filter value

   widget_control, xpf.wid.fil, get_value = thefilter
   filescan, thefilter(0), path=fp, name=n, type=t, ver=v
   thefilter = n+t+v

   if (value eq '' and error eq 0) then newpath = p $
                                   else newpath = fp

   ;a: Load file list.

   filelist,path=newpath, FILES = files, $
             DIRECTORIES = directories, $
             FILTER = thefilter, $
             usedpath = usedpath, $
             error = error

   ;a: Show message if an error occured.

   if (error ne 0) then $
       xpfsendmsg, xpf, xpf.lang(8) + usedpath+xpf.lang(9)

   xpf.usedpath = usedpath
   xpf.thefilter = thefilter

   ;a: Load new values to widgets

   widget_control, xpf.wid.sel, set_value = value
   widget_control, xpf.wid.fil, set_value = xpf.usedpath+xpf.thefilter 
   widget_control, xpf.wid.fli, set_value = files
   widget_control, xpf.wid.dli, set_value = directories
   widget_control, xpf.wid.fbs, set_uvalue = files
   widget_control, xpf.wid.dbs, set_uvalue = directories
   widget_control, xpf.wid.bas, set_uvalue = xpf

end
;
;
;
; This procedure send ccw-pickf box message
;------------------------------------------------------------------------------
pro xpfsendmsg, xpf, messagestr

   ;a: Send message.

   widget_control, xpf.wid.mes, set_value = xpf.lang(7)+messagestr

end
;
;
;
; This function gets the selected filename to the widget_control routine
;------------------------------------------------------------------------------
function xpf_get_value, id

   ;a: Get widget structure.

   bas = widget_info(id, /child)  
   widget_control, bas, get_uvalue=xpf

   ;a: REad file from text widget to structure.

   WIDGET_CONTROL, xpf.wid.sel, GET_VALUE = temp
   xpf.thefile = strcompress (temp(0))
   widget_control, bas, set_uvalue=xpf

   ;a: Return current file value.

   return, xpf.thefile
end
;
;
;
; This procedure processes the events being sent by the XManager.
;------------------------------------------------------------------------------
function xpf_event, event

   ;a: Get structure.

   bas = widget_info(event.handler, /child)  
   widget_control, bas, get_uvalue=xpf

   ;a: Calculate event for compound widget.

   ev = event
   ev.handler = xpf.wid.wid

   ;a: Send event.

   xpf_ev, ev
   thefile = xpf.thefile
   widget_control, xpf.wid.bas, get_uvalue=xpf

   if (thefile ne xpf.thefile) then begin

      ;a: Return compound widget evenet structure.

      return, {CCW_PICKF, id:xpf.wid.wid, top:event.top, $
                             handler:event.handler, select : xpf.thefile}

   endif else return, 0
end
;
;
;
;
; This procedure processes the events being sent by the XManager.
;------------------------------------------------------------------------------
PRO xpf_ev, event

COMMON picker,      $ ; name of common block
       thefile,     $ ; Selected filename.
       thepath,     $ ; selected path.
       thefilter      ; selected filter.

   ;a: Get uvalue of calling widget.

   widget_control, /hourglass
   widget_control, event.id,  get_uvalue = eventval

   ;a: Get widget structure

   bas = widget_info(event.handler, /child)  
   widget_control, bas, get_uvalue=xpf

   ;a: Clear message.

   widget_control, xpf.wid.mes, set_value = xpf.lang(7)

   ;s: Switch on uvalue.

   CASE eventval OF

     ;c: CANCEL (only no parent is avaiable)

     "CANCEL"    : begin

                   ;a: Destroy widget

                   widget_control, xpf.wid.wid, /destroy
                   xpf.wid.wid = 0

                   ;a: Set return values

                   thefile = ''
                   thepath   = xpf.usedpath
                   thefilter = xpf.thefilter
     end

     ;a: Call directory selection event routine.

     "DIRSEL"    : xpfdirsel,  event

     ;a: Call directory up event routine

     "DIRUP"     : xpfdirup,   event

     ;a: Call filter event routine

     "FILTER"    : xpffilter,  event

     ;a: Call fileselection event routine.

     "SELFILE"   : xpfselfile, event

     ;c: OK button 

     "OK"        : begin

                   ;a: Restore value from simple text widget

                   WIDGET_CONTROL, xpf.wid.sel, GET_VALUE = temp

                   error=0
                   if (xpf.create eq 0) then begin
                      if ((findfile(temp(0)))(0) eq '') then begin
                         xpfsendmsg, xpf, xpf.lang(13)+temp(0)+xpf.lang(9)
                         error = -1
                      endif
                   endif else begin
                      filescan, temp(0), path=path
                      cd, current=cur
                      changedir, path, error=error
                      cd, cur
                      if (error ne 0) then begin
                         xpfsendmsg, xpf, xpf.lang(8)+path+xpf.lang(9)
                      endif
                   endelse

                   if (error eq 0) then begin

                     ;in: Parrent is available

                      if (xpf.wid.par eq 0) then begin

                         ;a: Set return values.

                         thefile   = strcompress (temp(0))
                         thepath   = xpf.usedpath
                         thefilter = xpf.thefilter
                         widget_control, xpf.wid.wid, /destroy
                      endif else begin

                         ;a: Set new filename in widget structure.

                         xpf.thefile   = strcompress (temp(0))
                         widget_control, xpf.wid.bas, set_uvalue = xpf
                      endelse
                   endif
     end

     ELSE: MESSAGE, "Event User Value Not Found" 

   ENDCASE

END ;============= end of ccw_pickf event handling routine task =============
;
;
;
; This procedure is directory select event routine
;------------------------------------------------------------------------------
PRO xpfdirsel, event

   ;a: Get widget structure.

   bas = widget_info(event.handler, /child)  
   widget_control, bas, get_uvalue=xpf

   ;a: Load directories from widget

   widget_control, xpf.wid.dbs, get_uvalue = directories

   ;iy: Selected directory is available

   if event.index lt n_elements(directories) then begin

      ;a: Determine directory name

      filescan, directories(event.index), name=target_dir

      ;iy: System is VMS

      IF (!version.os EQ "vms") THEN BEGIN

         ;a: Prevent root directory

         IF ((target_dir ne '') and (target_dir eq '000000')) THEN return

      endif
   endif else return

   ;iy: System enviroment is VMS

   usedpath = xpf.usedpath
   filter   = xpf.thefilter
   if (!version.os EQ "vms") then begin
      filescan, xpf.usedpath, dir=newdir, /exclude, node=newnode, dev=newdev
      if (newdir eq '000000' or newdir eq '') then newdir = target_dir $
      else newdir = newdir+'.'+target_dir
      newpath = ''
      if newnode ne '' then newpath = newnode+'::'
      if newdev ne '' then newpath = newpath+newdev+':'
      newpath = newpath+'['+newdir+']'
      u = newpath

      ;a: Load file list under VMS

      directories = ''
      filelist, path=newpath, FILES = files, $
                DIRECTORIES = directories, $
                FILTER      = filter, $
                usedpath    = usedpath, $
                error = error

      ;a: Send message, if directory was not found.

      if (error eq -1) then $
         xpfsendmsg, xpf, xpf.lang(8) + u + xpf.lang(9)

   endif else begin

      ;a: Load file list

      directories = ''
      filelist, path = target_dir, files = files, $
                directories = directories, $
                filter = filter, $
                usedpath = usedpath, $
                error = error

      ;a: Send message, if directory was not found.

      if (error eq -1) then $
         xpfsendmsg, xpf, xpf.lang(8) + u + xpf.lang(9)
   endelse
   xpf.usedpath  = usedpath
   xpf.thefilter = filter

   ;a: Set new values in widgets

   widget_control, xpf.wid.fil, set_value  = xpf.usedpath+xpf.thefilter 
   widget_control, xpf.wid.fli, set_value  = files
   widget_control, xpf.wid.dli, set_value  = directories
   widget_control, xpf.wid.fbs, set_uvalue = files
   widget_control, xpf.wid.dbs, set_uvalue = directories
   widget_control, xpf.wid.bas, set_uval=xpf

END  ;	procedure xpfdirsel
;
;
;
;
; This procedure directory up event routine
;------------------------------------------------------------------------------
PRO xpfdirup, event

   ;a: Get widget structure

   bas = widget_info(event.handler, /child)  
   widget_control, bas, get_uvalue=xpf

   ;iy: System enviroment is VMS

   usedpath = xpf.usedpath
   filter = xpf.thefilter

   IF (!version.os EQ "vms") THEN BEGIN

      if (strpos(usedpath, '000000') ne -1) then return

      filescan, usedpath+filter, node=node, dev=dev, dir=dir, /exclude, /full
      dir = dir + '.'+xpf.backchars

      newpath = ''
      if (node ne '') then newpath = node + '::'
      if (dev ne '') then newpath = newpath+dev + ':'
      newpath = newpath + '['+dir+']'

   ENDIF else newpath = ''

   ;a: Load file list.

   filelist,path=newpath, FILES = files, $
             DIRECTORIES = directories, $
             FILTER = filter, $
             usedpath = usedpath, $
             error = error

   ;a: Cut root character string.

   ;a: Show message if an error occured.

   if (error ne 0) then $
       xpfsendmsg, xpf, xpf.lang(8) + usedpath+xpf.lang(9)

   xpf.usedpath = usedpath
   xpf.thefilter = filter

   ;a: Load new values to widgets

   widget_control, xpf.wid.fil, set_value = xpf.usedpath+xpf.thefilter 
   widget_control, xpf.wid.fli, set_value = files
   widget_control, xpf.wid.dli, set_value = directories
   widget_control, xpf.wid.fbs, set_uvalue = files
   widget_control, xpf.wid.dbs, set_uvalue = directories
   widget_control, xpf.wid.bas, set_uval=xpf

END ; xpfdirup
;
;
;
;
; This procedure processes file selections the event
;------------------------------------------------------------------------------
PRO xpfselfile, event

COMMON picker,      $ ; name of common block
       thefile,     $ ; Selected filename.
       thepath,     $ ; selected path.
       thefilter      ; selected filter.

   ;a: Get widget structure

   bas = widget_info(event.handler, /child)  
   widget_control, bas, get_uvalue=xpf

   ;a: Load directories from widget

   widget_control, xpf.wid.fbs, get_uvalue = files

   ;a: Staore called widget index

   selection = event.index

   ;a: Concatenate path and filename

   usedpath = xpf.usedpath

   IF (!version.os EQ "vms") THEN BEGIN
      xpf.thefile = usedpath + files(selection)
   ENDIF ELSE BEGIN
      IF path NE "/" THEN xpf.thefile = usedpath + "/" + files(selection) $
      ELSE                xpf.thefile = usedpath + files(selection)
   ENDELSE

   ;a: Set new value

   WIDGET_CONTROL, xpf.wid.sel, set_value = xpf.thefile
   xpf.usedpath = usedpath

   ;a: Check on double click

   wait, 0.2
   ok = 0
   stop = 0
   repeat begin
      sev = widget_event (event.id, /nowait)
      if sev.id ne 0 then begin
         ok = 1
         stop = 1
      endif else stop = 1
   endrep until stop eq 1

   ;iy: Double click 

   if ok eq 1 then begin

      ;a: Save values

      if (xpf.wid.par eq 0) then begin
         thefile   = xpf.thefile
         thepath   = xpf.usedpath
         thefilter = xpf.thefilter
         widget_control, xpf.wid.wid, /destroy
      endif else begin
         xpf.thefile   = xpf.thefile
         widget_control, xpf.wid.bas, set_uvalue = xpf
      endelse
   endif else widget_control, xpf.wid.bas, set_uval=xpf

END ; xpfselfile
;
;
;
;
; This procedure handles the changing of the filter value
;------------------------------------------------------------------------------
PRO xpffilter, event

   ;a: Get widget structure.

   bas = widget_info(event.handler, /child)  
   widget_control, bas, get_uvalue=xpf

   ;a: Restore value from filter simple text widget

   widget_control, xpf.wid.fil, get_value = temp

   ;a: Determine filelist

   filescan, temp(0), name=name, type=type, ver=ver,$
                      node=node, dev=dev, dir=dir

   ;a: Concatenate name, type and version to the filter string.

   xpf.thefilter = name+type+ver

   ;a: Replace '*' filter through '*.*'

   if (xpf.thefilter eq "*" or xpf.thefilter eq "") then xpf.thefilter = "*.*"

   ;a: Determine new suppose path

   u = node+dev+dir
   dir_ok=1

   ;a: System enviroment is VMS

   usedpath = xpf.usedpath
   filter = xpf.thefilter

   ;a: Determine filelist.

   used = usedpath
   filelist, path=u, FILES = files, $
             DIRECTORIES = directories, $
             FILTER = filter, $
             error = error,   $
             usedpath = used

   ;iy: The new pathwas not found

   if (error ne 0) then begin

      ;a: Send message: Directory ... does not exist.

      xpfsendmsg, xpf, xpf.lang(8) + u + xpf.lang(9)

      ;a: Scan previous path

      filelist, path=usedpath, FILES = files, $
                DIRECTORIES = directories, $
                FILTER = filter, $
                usedpath = usedpath, $
                error = error

      ;a: Send message, if a error occurs.

      if (error eq -1) then $
         xpfsendmsg, xpf, xpf.lang(8) + u + xpf.lang(9)

   endif else usedpath = used

   xpf.usedpath = usedpath
   xpf.thefilter = filter

   ;a: Set new values in widgets

   widget_control, xpf.wid.fil, set_value = xpf.usedpath+xpf.thefilter 
   widget_control, xpf.wid.fli, set_value = files
   widget_control, xpf.wid.dli, set_value = directories
   widget_control, xpf.wid.fbs, set_uvalue = files
   widget_control, xpf.wid.dbs, set_uvalue = directories
   widget_control, xpf.wid.bas, set_uval=xpf

END ; xpffilter
;------------------------------------------------------------------------------
;	procedure ccw_pickf 
;------------------------------------------------------------------------------
;  This is the actual routine that creates the widget and registers it with the
;  Xmanager.  It also determines the operating system and sets the specific
;  file designators for that operating system.
;------------------------------------------------------------------------------
function ccw_pickf, parent,$
                    group     = group,     $
                    create    = create,    $
                    path      = path,      $
                    read      = read,      $
                    write     = write,     $
                    filter    = filter,    $
                    title     = title,     $
                    mess_wid  = mess_wid,  $
                    modal     = modal,     $
                    xoffset   = xoffset,   $
                    yoffset   = yoffset,   $
                    german    = german,    $
                    langarr   = langarr,   $
                    value     = value,     $
                    uvalue    = uvalue,    $
                    frame     = frame

COMMON picker,      $ ; name of common block
       thefile,     $ ; Selected filename.
       thepath,     $ ; selected path.
       thefilter      ; selected filter.

   ;a: Initialize common block

   thefile = ''
   thefilter = ''
   thepath = ''

   if (n_params() eq 0) then parent_id = 0l else parent_id = long(parent)

   ;a: Define structure.

   xpf = {__xpf                                    , $
      lang       : strarr(15)                      , $ ; Language array
      backchars  : ''                              , $ ; Directory back char
      thefilter  : ''                              , $ ; Current filter
      thefile    : ''                              , $ ; Current file.      
      usedpath   : ''                              , $ ; current path.
      create     : 0B                              , $ ; Put flag.
      wid        : {xpf_wid                        , $
         wid   : 0L                                , $ ; Widget base
         bas   : 0L                                , $ ; Structure base
         dbs   : 0L                                , $ ; Dirlist base
         fbs   : 0L                                , $ ; Filelist base
         fli   : 0L                                , $ ; Filelist widget id
         dli   : 0L                                , $ ; Dirlist widget id
         fil   : 0L                                , $ ; Filter widget
         sel   : 0L                                , $ ; Selection widget
         par   : parent_id                         , $ ; Parent widget ID
         mes   : 0L                                  $ ; Message widget
      }                                              $
   }

   ;a: Check keywords.

   if (keyword_set(create)) then xpf.create = 1
   if (keyword_set(value)) then begin
      filescan, value, path=p, name=n, ver=v, type=t, /current
      xpf.thefile = n+t+v
   endif else xpf.thefile = ''
   if (keyword_set(filter)) then begin
      filescan, filter, path=path, name=n, ver=v, type=t, /current
      if (xpf.usedpath eq '') then p=path
      xpf.thefilter = n+t+v
   endif else xpf.thefilter = '*.*'

   if (not keyword_set(xoffset)) then xoffset = 100
   if (not keyword_set(yoffset)) then yoffset = 100
   if (not keyword_set(frame)) then frame = 0
   if (not keyword_set (uvalue)) then uvalue = 'CCW_PICKF'

   ;a: Fill language array

   if keyword_set (langarr) then xpf.lang = langarr $
   else begin
      if keyword_set (german) then begin
         xpf.lang (0)  = 'Filter:'
         xpf.lang (1)  = 'Ein Verzeichnis zur|ck'
         xpf.lang (2)  = 'Unterverzeichnisse'
         xpf.lang (3)  = 'Dateien'
         xpf.lang (4)  = 'Selektion:'
         xpf.lang (5)  = '    Ok     '
         xpf.lang (6)  = ' Abbrechen '
         xpf.lang (7)  = 'Meldung:'
         xpf.lang (8) = 'Verzeichnis >'
         xpf.lang (9) = '< existiert nicht !'
         xpf.lang (10) = 'Bitte selektieren Sie eine Datei'
         xpf.lang (11) = ' zum Vffnen'
         xpf.lang (12) = ' zum Schreiben'
         xpf.lang (13) = 'Datei >'
      endif else begin
         xpf.lang (0)  = 'Filter:'
         xpf.lang (1)  = 'Up One Directory Level'
         xpf.lang (2)  = 'Subdirectories'
         xpf.lang (3)  = 'Files'
         xpf.lang (4)  = 'Selection:'
         xpf.lang (5)  = '    Ok    '
         xpf.lang (6)  = '  Cancel  '
         xpf.lang (7)  = 'Message:'
         xpf.lang (8) = 'Directory >'
         xpf.lang (9) = '< does not exist !'
         xpf.lang (10) = 'Please Select a File'
         xpf.lang (11) = ' for reading'
         xpf.lang (12) = ' for writing'
         xpf.lang (13) = 'File >'
      endelse
   endelse


   ; set the characters the file separator

   if (!version.os eq "vms") then begin
      xpf.backchars = "-"		       
   endif else begin
      xpf.backchars = ".."
   endelse

   ;a: Get filelist.

   selection = -1
   usedpath = xpf.usedpath
   thefilter = xpf.thefilter
   usedpath = xpf.usedpath
   filelist, path  = path,              $               
             files = files,             $           	
	     directories = directories, $	       
	     filter   = thefilter,      $
             usedpath = usedpath
   xpf.usedpath = usedpath

   if (not (keyword_set(title))) then $			
      title = xpf.lang (10)       			
   if (keyword_set(read)) then $
      title = title + xpf.lang (11)
   if (keyword_set(write)) then $
      title = title + xpf.lang (12)

   if xpf.wid.par ne 0 then begin
      xpf.wid.wid = widget_base(xpf.wid.par, title=title, /column, $
                      frame=frame, event_func = 'xpf_event',       $
                      pro_set_value = 'xpf_set_value', $
                      func_get_value = 'xpf_get_value', $
                      uvalue=uvalue)
   endif else begin
      xpf.wid.wid = widget_base(title=title, /column, uvalue=uvalue, $
                      xoffset=xoffset, yoffset=yoffset, frame=frame)
   endelse

   xpf.wid.bas   = widget_base  (xpf.wid.wid, /column)

   base   = widget_base  (xpf.wid.bas, /row)
   label  = widget_label (base, value = xpf.lang(0))
   xpf.wid.fil = widget_text  (base, xsize = 46, $
                                ysize = 1,  $
                                uvalue = 'FILTER', $
                                value = xpf.usedpath+xpf.thefilter, $
                                /editable)

   backup     = widget_button (xpf.wid.bas, $
	                       value  = xpf.lang(1), $
                               uvalue = "DIRUP")

   xpf.wid.dbs = widget_base   (xpf.wid.bas, /row   , space=30)
   dirs        = widget_base   (xpf.wid.dbs, /column, /frame)
   lbl         = widget_label  (dirs, value = xpf.lang(2))

   xpf.wid.dli = widget_list   (dirs, value=directories, ysize=8, $
                                uvalue = "DIRSEL")
   widget_control, xpf.wid.dbs, set_uvalue=directories

   xpf.wid.fbs = widget_base (xpf.wid.dbs, $
                             /column, $
                             /frame)
                        
   lbl = widget_label (xpf.wid.fbs, value = xpf.lang (3))

   xpf.wid.fli = widget_list (xpf.wid.fbs, $
                           value = files, $
                           ysize = 8, $
                           uvalue = "SELFILE")
   widget_control, xpf.wid.fbs, set_uvalue=files

   widebase  = widget_base  (xpf.wid.bas, /ROW)
   label     = widget_label (widebase, VALUE = xpf.lang(4))
   xpf.wid.sel = widget_text  (widebase, $
                             VALUE = xpf.usedpath+xpf.thefile, $
                             XSIZE = 42, $
                             YSIZE = 1, $
                             UVALUE = "OK", $
                             /EDITABLE)

   if xpf.wid.par eq 0 then begin
      rowbase = WIDGET_BASE (xpf.wid.bas, $
                              SPACE = 20, $
                              /ROW)

      ok = WIDGET_BUTTON (xpf.wid.bas,                 $
                          VALUE = xpf.lang(5), $
                          UVALUE = "OK")

      cancel = WIDGET_BUTTON (xpf.wid.bas,             $
                              VALUE = xpf.lang(6), $
                              UVALUE = "CANCEL")

   endif

   xpf.wid.mes = widget_text (xpf.wid.bas, value = xpf.lang(7))
   mess_wid = xpf.wid.mes
   widget_control, xpf.wid.bas, set_uvalue=xpf
   if (keyword_set(uvalue)) then widget_control, xpf.wid.wid, set_uvalue=uvalue

   if xpf.wid.par eq 0 then begin

      WIDGET_CONTROL, xpf.wid.wid, /REALIZE		
							

      XManager, "ccw_pickf", xpf.wid.wid, $		
                              EVENT_HANDLER = "xpf_ev",$
                              GROUP_LEADER  = GROUP, modal=modal
							
      if (keyword_set(path)) then path = thepath
      if (keyword_set(filter)) then filter = thefilter
      return, thefile

   endif else return, xpf.wid.wid

end